mirror of
https://github.com/Sonarr/Sonarr.git
synced 2024-12-16 11:37:58 +02:00
Added progress messaging, using info logging
Also extension methods for complete and failed (for coloured UI messaging)
This commit is contained in:
parent
eeda4e83f9
commit
c928ccb201
@ -11,7 +11,7 @@ namespace NzbDrone.Api.Commands
|
||||
public class CommandConnection : NzbDronePersistentConnection,
|
||||
IHandleAsync<CommandStartedEvent>,
|
||||
IHandleAsync<CommandCompletedEvent>,
|
||||
IHandle<CommandFailedEvent>
|
||||
IHandleAsync<CommandFailedEvent>
|
||||
{
|
||||
public override string Resource
|
||||
{
|
||||
@ -28,7 +28,7 @@ public void HandleAsync(CommandCompletedEvent message)
|
||||
BroadcastMessage(message.TrackedCommand);
|
||||
}
|
||||
|
||||
public void Handle(CommandFailedEvent message)
|
||||
public void HandleAsync(CommandFailedEvent message)
|
||||
{
|
||||
BroadcastMessage(message.TrackedCommand);
|
||||
}
|
||||
|
@ -86,6 +86,9 @@
|
||||
<Compile Include="Commands\CommandConnection.cs" />
|
||||
<Compile Include="Config\NamingConfigResource.cs" />
|
||||
<Compile Include="Config\NamingModule.cs" />
|
||||
<Compile Include="ProgressMessaging\ProgressMessageConnection.cs" />
|
||||
<Compile Include="ProgressMessaging\ProgressMessageModule.cs" />
|
||||
<Compile Include="ProgressMessaging\ProgressMessageResource.cs" />
|
||||
<Compile Include="EpisodeFiles\EpisodeFileModule.cs" />
|
||||
<Compile Include="EpisodeFiles\EpisodeFileResource.cs" />
|
||||
<Compile Include="Directories\DirectoryLookupService.cs" />
|
||||
|
24
NzbDrone.Api/ProgressMessaging/ProgressMessageConnection.cs
Normal file
24
NzbDrone.Api/ProgressMessaging/ProgressMessageConnection.cs
Normal file
@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using Microsoft.AspNet.SignalR;
|
||||
using Microsoft.AspNet.SignalR.Infrastructure;
|
||||
using NzbDrone.Api.SignalR;
|
||||
using NzbDrone.Common.Messaging;
|
||||
using NzbDrone.Core.ProgressMessaging;
|
||||
|
||||
namespace NzbDrone.Api.ProgressMessaging
|
||||
{
|
||||
public class ProgressMessageConnection : NzbDronePersistentConnection,
|
||||
IHandleAsync<NewProgressMessageEvent>
|
||||
{
|
||||
public override string Resource
|
||||
{
|
||||
get { return "/ProgressMessage"; }
|
||||
}
|
||||
|
||||
public void HandleAsync(NewProgressMessageEvent message)
|
||||
{
|
||||
var context = ((ConnectionManager)GlobalHost.ConnectionManager).GetConnection(GetType());
|
||||
context.Connection.Broadcast(message.ProgressMessage);
|
||||
}
|
||||
}
|
||||
}
|
21
NzbDrone.Api/ProgressMessaging/ProgressMessageModule.cs
Normal file
21
NzbDrone.Api/ProgressMessaging/ProgressMessageModule.cs
Normal file
@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Nancy;
|
||||
using NzbDrone.Api.Extensions;
|
||||
|
||||
namespace NzbDrone.Api.ProgressMessaging
|
||||
{
|
||||
public class ProgressMessageModule : NzbDroneRestModule<ProgressMessageResource>
|
||||
{
|
||||
public ProgressMessageModule()
|
||||
{
|
||||
Get["/"] = x => GetAllMessages();
|
||||
}
|
||||
|
||||
private Response GetAllMessages()
|
||||
{
|
||||
return new List<ProgressMessageResource>().AsResponse();
|
||||
}
|
||||
}
|
||||
}
|
12
NzbDrone.Api/ProgressMessaging/ProgressMessageResource.cs
Normal file
12
NzbDrone.Api/ProgressMessaging/ProgressMessageResource.cs
Normal file
@ -0,0 +1,12 @@
|
||||
using System;
|
||||
using NzbDrone.Api.REST;
|
||||
|
||||
namespace NzbDrone.Api.ProgressMessaging
|
||||
{
|
||||
public class ProgressMessageResource : RestResource
|
||||
{
|
||||
public DateTime Time { get; set; }
|
||||
public String CommandId { get; set; }
|
||||
public String Message { get; set; }
|
||||
}
|
||||
}
|
@ -30,11 +30,11 @@ public void Setup()
|
||||
|
||||
Mocker.GetMock<ITrackCommands>()
|
||||
.Setup(c => c.TrackIfNew(It.IsAny<CommandA>()))
|
||||
.Returns(new TrackedCommand(new CommandA(), CommandState.Running));
|
||||
.Returns(new TrackedCommand(new CommandA(), ProcessState.Running));
|
||||
|
||||
Mocker.GetMock<ITrackCommands>()
|
||||
.Setup(c => c.TrackIfNew(It.IsAny<CommandB>()))
|
||||
.Returns(new TrackedCommand(new CommandB(), CommandState.Running));
|
||||
.Returns(new TrackedCommand(new CommandB(), ProcessState.Running));
|
||||
}
|
||||
|
||||
[Test]
|
||||
@ -44,7 +44,7 @@ public void should_publish_command_to_executor()
|
||||
|
||||
Mocker.GetMock<ITrackCommands>()
|
||||
.Setup(c => c.TrackIfNew(commandA))
|
||||
.Returns(new TrackedCommand(commandA, CommandState.Running));
|
||||
.Returns(new TrackedCommand(commandA, ProcessState.Running));
|
||||
|
||||
Subject.PublishCommand(commandA);
|
||||
|
||||
@ -69,7 +69,7 @@ public void should_not_publish_to_incompatible_executor()
|
||||
|
||||
Mocker.GetMock<ITrackCommands>()
|
||||
.Setup(c => c.TrackIfNew(commandA))
|
||||
.Returns(new TrackedCommand(commandA, CommandState.Running));
|
||||
.Returns(new TrackedCommand(commandA, ProcessState.Running));
|
||||
|
||||
Subject.PublishCommand(commandA);
|
||||
|
||||
|
@ -13,7 +13,6 @@ public static string GetHash(this LogEventInfo logEvent)
|
||||
return HashUtil.CalculateCrc(hashSeed);
|
||||
}
|
||||
|
||||
|
||||
public static string GetFormattedMessage(this LogEventInfo logEvent)
|
||||
{
|
||||
var message = logEvent.FormattedMessage;
|
||||
|
40
NzbDrone.Common/Instrumentation/LoggerExtensions.cs
Normal file
40
NzbDrone.Common/Instrumentation/LoggerExtensions.cs
Normal file
@ -0,0 +1,40 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Messaging.Tracking;
|
||||
|
||||
namespace NzbDrone.Common.Instrumentation
|
||||
{
|
||||
public static class LoggerExtensions
|
||||
{
|
||||
public static void Complete(this Logger logger, string message)
|
||||
{
|
||||
var logEvent = new LogEventInfo(LogLevel.Info, logger.Name, message);
|
||||
logEvent.Properties.Add("Status", ProcessState.Completed);
|
||||
|
||||
logger.Log(logEvent);
|
||||
}
|
||||
|
||||
public static void Complete(this Logger logger, string message, params object[] args)
|
||||
{
|
||||
var formattedMessage = String.Format(message, args);
|
||||
Complete(logger, formattedMessage);
|
||||
}
|
||||
|
||||
public static void Failed(this Logger logger, string message)
|
||||
{
|
||||
var logEvent = new LogEventInfo(LogLevel.Info, logger.Name, message);
|
||||
logEvent.Properties.Add("Status", ProcessState.Failed);
|
||||
|
||||
logger.Log(logEvent);
|
||||
}
|
||||
|
||||
public static void Failed(this Logger logger, string message, params object[] args)
|
||||
{
|
||||
var formattedMessage = String.Format(message, args);
|
||||
Failed(logger, formattedMessage);
|
||||
}
|
||||
}
|
||||
}
|
@ -4,7 +4,6 @@ public interface IProcessMessage { }
|
||||
|
||||
public interface IProcessMessageAsync : IProcessMessage { }
|
||||
|
||||
|
||||
public interface IProcessMessage<TMessage> : IProcessMessage { }
|
||||
|
||||
public interface IProcessMessageAsync<TMessage> : IProcessMessageAsync { }
|
||||
|
@ -33,7 +33,7 @@ public TrackedCommand TrackIfNew(ICommand command)
|
||||
return null;
|
||||
}
|
||||
|
||||
var trackedCommand = new TrackedCommand(command, CommandState.Running);
|
||||
var trackedCommand = new TrackedCommand(command, ProcessState.Running);
|
||||
Store(trackedCommand);
|
||||
|
||||
return trackedCommand;
|
||||
@ -45,7 +45,7 @@ public ExistingCommand TrackNewOrGet(ICommand command)
|
||||
|
||||
if (trackedCommand == null)
|
||||
{
|
||||
trackedCommand = new TrackedCommand(command, CommandState.Running);
|
||||
trackedCommand = new TrackedCommand(command, ProcessState.Running);
|
||||
Store(trackedCommand);
|
||||
|
||||
return new ExistingCommand(false, trackedCommand);
|
||||
@ -57,7 +57,7 @@ public ExistingCommand TrackNewOrGet(ICommand command)
|
||||
public TrackedCommand Completed(TrackedCommand trackedCommand, TimeSpan runtime)
|
||||
{
|
||||
trackedCommand.StateChangeTime = DateTime.UtcNow;
|
||||
trackedCommand.State = CommandState.Completed;
|
||||
trackedCommand.State = ProcessState.Completed;
|
||||
trackedCommand.Runtime = runtime;
|
||||
|
||||
Store(trackedCommand);
|
||||
@ -68,7 +68,7 @@ public TrackedCommand Completed(TrackedCommand trackedCommand, TimeSpan runtime)
|
||||
public TrackedCommand Failed(TrackedCommand trackedCommand, Exception e)
|
||||
{
|
||||
trackedCommand.StateChangeTime = DateTime.UtcNow;
|
||||
trackedCommand.State = CommandState.Failed;
|
||||
trackedCommand.State = ProcessState.Failed;
|
||||
trackedCommand.Exception = e;
|
||||
|
||||
Store(trackedCommand);
|
||||
@ -94,7 +94,7 @@ public TrackedCommand FindExisting(ICommand command)
|
||||
|
||||
private List<TrackedCommand> Running(Type type = null)
|
||||
{
|
||||
var running = AllTracked().Where(i => i.State == CommandState.Running);
|
||||
var running = AllTracked().Where(i => i.State == ProcessState.Running);
|
||||
|
||||
if (type != null)
|
||||
{
|
||||
@ -116,7 +116,7 @@ private void Store(TrackedCommand trackedCommand)
|
||||
|
||||
public void Execute(TrackedCommandCleanupCommand message)
|
||||
{
|
||||
var old = AllTracked().Where(c => c.State != CommandState.Running && c.StateChangeTime < DateTime.UtcNow.AddMinutes(-5));
|
||||
var old = AllTracked().Where(c => c.State != ProcessState.Running && c.StateChangeTime < DateTime.UtcNow.AddMinutes(-5));
|
||||
|
||||
foreach (var trackedCommand in old)
|
||||
{
|
||||
|
14
NzbDrone.Common/Messaging/Tracking/ProcessState.cs
Normal file
14
NzbDrone.Common/Messaging/Tracking/ProcessState.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace NzbDrone.Common.Messaging.Tracking
|
||||
{
|
||||
public enum ProcessState
|
||||
{
|
||||
Running,
|
||||
Completed,
|
||||
Failed
|
||||
}
|
||||
}
|
@ -8,7 +8,7 @@ public class TrackedCommand
|
||||
public String Name { get; private set; }
|
||||
public String Type { get; private set; }
|
||||
public ICommand Command { get; private set; }
|
||||
public CommandState State { get; set; }
|
||||
public ProcessState State { get; set; }
|
||||
public DateTime StateChangeTime { get; set; }
|
||||
public TimeSpan Runtime { get; set; }
|
||||
public Exception Exception { get; set; }
|
||||
@ -17,7 +17,7 @@ public TrackedCommand()
|
||||
{
|
||||
}
|
||||
|
||||
public TrackedCommand(ICommand command, CommandState state)
|
||||
public TrackedCommand(ICommand command, ProcessState state)
|
||||
{
|
||||
Id = command.CommandId;
|
||||
Name = command.GetType().Name;
|
||||
@ -27,11 +27,4 @@ public TrackedCommand(ICommand command, CommandState state)
|
||||
StateChangeTime = DateTime.UtcNow;
|
||||
}
|
||||
}
|
||||
|
||||
public enum CommandState
|
||||
{
|
||||
Running = 0,
|
||||
Completed = 1,
|
||||
Failed = 2
|
||||
}
|
||||
}
|
||||
|
@ -92,6 +92,8 @@
|
||||
<Compile Include="IEnumerableExtensions.cs" />
|
||||
<Compile Include="Instrumentation\GlobalExceptionHandlers.cs" />
|
||||
<Compile Include="Instrumentation\ExceptronTarget.cs" />
|
||||
<Compile Include="Instrumentation\LoggerExtensions.cs" />
|
||||
<Compile Include="Messaging\Tracking\ProcessState.cs" />
|
||||
<Compile Include="Messaging\Tracking\CommandTrackingService.cs" />
|
||||
<Compile Include="Messaging\Tracking\ExistingCommand.cs" />
|
||||
<Compile Include="Messaging\Tracking\TrackedCommand.cs" />
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System.Linq;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Instrumentation;
|
||||
using NzbDrone.Common.Messaging;
|
||||
using NzbDrone.Core.DecisionEngine;
|
||||
using NzbDrone.Core.Download;
|
||||
@ -38,7 +39,7 @@ public void Sync()
|
||||
var decisions = _downloadDecisionMaker.GetRssDecision(reports);
|
||||
var qualifiedReports = _downloadApprovedReports.DownloadApproved(decisions);
|
||||
|
||||
_logger.Info("RSS Sync Completed. Reports found: {0}, Reports downloaded: {1}", reports.Count, qualifiedReports.Count());
|
||||
_logger.Complete("RSS Sync Completed. Reports found: {0}, Reports downloaded: {1}", reports.Count, qualifiedReports.Count());
|
||||
}
|
||||
|
||||
public void Execute(RssSyncCommand message)
|
||||
|
@ -221,7 +221,7 @@
|
||||
<Compile Include="Instrumentation\DeleteLogFilesService.cs" />
|
||||
<Compile Include="ProgressMessaging\NewProgressMessageEvent.cs" />
|
||||
<Compile Include="ProgressMessaging\ProgressMessage.cs" />
|
||||
<Compile Include="ProgressMessaging\ProgressMessagingTarget.cs" />
|
||||
<Compile Include="ProgressMessaging\ProgressMessageTarget.cs" />
|
||||
<Compile Include="Instrumentation\SetLoggingLevel.cs" />
|
||||
<Compile Include="Jobs\TaskManager.cs" />
|
||||
<Compile Include="Lifecycle\ApplicationShutdownRequested.cs" />
|
||||
|
@ -1,7 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using NzbDrone.Common.Messaging.Tracking;
|
||||
|
||||
namespace NzbDrone.Core.ProgressMessaging
|
||||
{
|
||||
@ -10,5 +8,6 @@ public class ProgressMessage
|
||||
public DateTime Time { get; set; }
|
||||
public String CommandId { get; set; }
|
||||
public String Message { get; set; }
|
||||
public ProcessState Status { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -4,17 +4,18 @@
|
||||
using NLog.Layouts;
|
||||
using NLog.Targets;
|
||||
using NzbDrone.Common.Messaging;
|
||||
using NzbDrone.Common.Messaging.Tracking;
|
||||
using NzbDrone.Core.Lifecycle;
|
||||
|
||||
namespace NzbDrone.Core.ProgressMessaging
|
||||
{
|
||||
|
||||
public class ProgressMessagingTarget : TargetWithLayout, IHandle<ApplicationStartedEvent>, IHandle<ApplicationShutdownRequested>
|
||||
public class ProgressMessageTarget : TargetWithLayout, IHandle<ApplicationStartedEvent>, IHandle<ApplicationShutdownRequested>
|
||||
{
|
||||
private readonly IMessageAggregator _messageAggregator;
|
||||
public LoggingRule Rule { get; set; }
|
||||
|
||||
public ProgressMessagingTarget(IMessageAggregator messageAggregator)
|
||||
public ProgressMessageTarget(IMessageAggregator messageAggregator)
|
||||
{
|
||||
_messageAggregator = messageAggregator;
|
||||
}
|
||||
@ -55,10 +56,13 @@ protected override void Write(LogEventInfo logEvent)
|
||||
return;
|
||||
}
|
||||
|
||||
var status = logEvent.Properties.ContainsKey("Status") ? (ProcessState)logEvent.Properties["Status"] : ProcessState.Running;
|
||||
|
||||
var message = new ProgressMessage();
|
||||
message.Time = logEvent.TimeStamp;
|
||||
message.CommandId = commandId;
|
||||
message.Message = logEvent.FormattedMessage;
|
||||
message.Status = status;
|
||||
|
||||
_messageAggregator.PublishEvent(new NewProgressMessageEvent(message));
|
||||
}
|
40
UI/ProgressMessaging/ProgressMessageCollection.js
Normal file
40
UI/ProgressMessaging/ProgressMessageCollection.js
Normal file
@ -0,0 +1,40 @@
|
||||
'use strict';
|
||||
define(
|
||||
[
|
||||
'backbone',
|
||||
'ProgressMessaging/ProgressMessageModel',
|
||||
'Shared/Messenger',
|
||||
'Mixins/backbone.signalr.mixin'
|
||||
], function (Backbone, ProgressMessageModel, Messenger) {
|
||||
|
||||
var ProgressMessageCollection = Backbone.Collection.extend({
|
||||
url : window.ApiRoot + '/progressmessage',
|
||||
model: ProgressMessageModel
|
||||
});
|
||||
|
||||
var collection = new ProgressMessageCollection().bindSignalR();
|
||||
|
||||
collection.signalRconnection.received(function (message) {
|
||||
|
||||
var type = getMessengerType(message.status);
|
||||
|
||||
Messenger.show({
|
||||
id : message.commandId,
|
||||
message: message.message,
|
||||
type : type
|
||||
});
|
||||
});
|
||||
|
||||
var getMessengerType = function (status) {
|
||||
switch (status) {
|
||||
case 'completed':
|
||||
return 'success';
|
||||
case 'failed':
|
||||
return 'error';
|
||||
default:
|
||||
return 'info';
|
||||
}
|
||||
}
|
||||
|
||||
return collection;
|
||||
});
|
8
UI/ProgressMessaging/ProgressMessageModel.js
Normal file
8
UI/ProgressMessaging/ProgressMessageModel.js
Normal file
@ -0,0 +1,8 @@
|
||||
'use strict';
|
||||
define(
|
||||
[
|
||||
'backbone'
|
||||
], function (Backbone) {
|
||||
return Backbone.Model.extend({
|
||||
});
|
||||
});
|
@ -5,11 +5,12 @@ require(
|
||||
'marionette',
|
||||
'Controller',
|
||||
'Series/SeriesCollection',
|
||||
'ProgressMessaging/ProgressMessageCollection',
|
||||
'Shared/Actioneer',
|
||||
'Navbar/NavbarView',
|
||||
'jQuery/RouteBinder',
|
||||
'jquery'
|
||||
], function (App, Marionette, Controller, SeriesCollection, Actioneer, NavbarView, RouterBinder, $) {
|
||||
], function (App, Marionette, Controller, SeriesCollection, ProgressMessageCollection, Actioneer, NavbarView, RouterBinder, $) {
|
||||
|
||||
var Router = Marionette.AppRouter.extend({
|
||||
|
||||
|
@ -105,7 +105,6 @@ define(
|
||||
title : 'RSS Sync',
|
||||
icon : 'icon-rss',
|
||||
command : 'rsssync',
|
||||
successMessage: 'RSS Sync Completed',
|
||||
errorMessage : 'RSS Sync Failed!'
|
||||
},
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user