feat: debug-level logging to file

recyclarr
Robert Dailey 3 years ago
parent 2a222ac6e5
commit 4d99530e48

@ -8,6 +8,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
### Added
- Debug-level logs are now written to file in addition to the Info-level logs in console output.
## [1.4.2] - 2021-05-15
### Fixed

@ -6,6 +6,7 @@
<PackageReference Update="FluentAssertions" Version="5.*" />
<PackageReference Update="GitHubActionsTestLogger" Version="1.*" />
<PackageReference Update="Microsoft.NET.Test.Sdk" Version="16.*" />
<PackageReference Update="morelinq" Version="3.*" />
<PackageReference Update="NSubstitute.Analyzers.CSharp" Version="1.*" />
<PackageReference Update="NSubstitute" Version="4.*" />
<PackageReference Update="NUnit.Analyzers" Version="3.*" />
@ -13,7 +14,6 @@
<PackageReference Update="NUnit3TestAdapter" Version="3.*" />
<PackageReference Update="Serilog.Sinks.NUnit" Version="1.*" />
<PackageReference Update="Serilog.Sinks.TestCorrelator" Version="3.*" />
<PackageReference Update="morelinq" Version="3.*" />
<!-- Non-Test Packages -->
<PackageReference Update="Autofac.Extensions.DependencyInjection" Version="7.*" />
@ -26,6 +26,7 @@
<PackageReference Update="Microsoft.CodeAnalysis.NetAnalyzers" Version="5.*"/>
<PackageReference Update="Nerdbank.GitVersioning" Version="3.*"/>
<PackageReference Update="Serilog.Sinks.Console" Version="3.*" />
<PackageReference Update="Serilog.Sinks.File" Version="4.*" />
<PackageReference Update="Serilog" Version="2.*" />
<PackageReference Update="System.Data.HashFunction.FNV" Version="2.*" />
<PackageReference Update="System.IO.Abstractions" Version="13.*" />

@ -0,0 +1,41 @@
using System.IO.Abstractions;
using NSubstitute;
using NUnit.Framework;
namespace Trash.Tests
{
[TestFixture]
[Parallelizable(ParallelScope.All)]
public class LogJanitorTest
{
[Test]
public void Keep_correct_number_of_newest_log_files()
{
var fs = Substitute.For<IFileSystem>();
var janitor = new LogJanitor(fs);
var testFileInfoList = new[]
{
Substitute.For<IFileInfo>(),
Substitute.For<IFileInfo>(),
Substitute.For<IFileInfo>(),
Substitute.For<IFileInfo>()
};
testFileInfoList[0].Name.Returns("trash_2021-05-15_19-00-00");
testFileInfoList[1].Name.Returns("trash_2021-05-15_20-00-00");
testFileInfoList[2].Name.Returns("trash_2021-05-15_21-00-00");
testFileInfoList[3].Name.Returns("trash_2021-05-15_22-00-00");
fs.DirectoryInfo.FromDirectoryName(Arg.Any<string>()).GetFiles()
.Returns(testFileInfoList);
janitor.DeleteOldestLogFiles(2);
testFileInfoList[0].Received().Delete();
testFileInfoList[1].Received().Delete();
testFileInfoList[2].DidNotReceive().Delete();
testFileInfoList[3].DidNotReceive().Delete();
}
}
}

@ -9,5 +9,7 @@ namespace Trash
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "trash-updater");
public static string DefaultConfigPath { get; } = Path.Combine(AppContext.BaseDirectory, "trash.yml");
public static string LogDirectory { get; } = Path.Combine(AppDataPath, "logs");
}
}

@ -19,10 +19,12 @@ namespace Trash.Command
public abstract class ServiceCommand : ICommand, IServiceCommand
{
private readonly LoggingLevelSwitch _loggingLevelSwitch;
private readonly ILogJanitor _logJanitor;
protected ServiceCommand(ILogger logger, LoggingLevelSwitch loggingLevelSwitch)
protected ServiceCommand(ILogger logger, LoggingLevelSwitch loggingLevelSwitch, ILogJanitor logJanitor)
{
_loggingLevelSwitch = loggingLevelSwitch;
_logJanitor = logJanitor;
Log = logger;
}
@ -54,6 +56,10 @@ namespace Trash.Command
Log.Error(e, "Unrecoverable Exception");
ExitDueToFailure();
}
finally
{
CleanupOldLogFiles();
}
}
[CommandOption("preview", 'p', Description =
@ -72,6 +78,11 @@ namespace Trash.Command
public abstract string CacheStoragePath { get; }
private void CleanupOldLogFiles()
{
_logJanitor.DeleteOldestLogFiles(20);
}
private void SetupLogging()
{
_loggingLevelSwitch.MinimumLevel =

@ -1,4 +1,6 @@
using System.IO.Abstractions;
using System;
using System.IO;
using System.IO.Abstractions;
using System.Reflection;
using Autofac;
using Autofac.Extras.AggregateService;
@ -27,16 +29,23 @@ namespace Trash
{
private static void SetupLogging(ContainerBuilder builder)
{
builder.RegisterType<LogJanitor>().As<ILogJanitor>();
builder.RegisterType<LoggingLevelSwitch>().SingleInstance();
builder.Register(c =>
{
const string template = "[{Level:u3}] {Message:lj}{NewLine}{Exception}";
var logPath = Path.Combine(AppPaths.LogDirectory,
$"trash_{DateTime.Now:yyyy-MM-dd_HH-mm-ss}.log");
const string consoleTemplate = "[{Level:u3}] {Message:lj}{NewLine}{Exception}";
return new LoggerConfiguration()
.MinimumLevel.ControlledBy(c.Resolve<LoggingLevelSwitch>())
.WriteTo.Console(outputTemplate: template)
.MinimumLevel.Debug()
.WriteTo.Console(outputTemplate: consoleTemplate, levelSwitch: c.Resolve<LoggingLevelSwitch>())
.WriteTo.File(logPath)
.CreateLogger();
})
.As<ILogger>();
.As<ILogger>()
.SingleInstance();
}
private static void SonarrRegistrations(ContainerBuilder builder)
@ -123,9 +132,7 @@ namespace Trash
public static IContainer Setup(ContainerBuilder builder)
{
builder.RegisterType<FileSystem>()
.As<IFileSystem>();
builder.RegisterType<FileSystem>().As<IFileSystem>();
builder.RegisterType<ServiceCache>().As<IServiceCache>();
builder.RegisterType<CacheStoragePath>().As<ICacheStoragePath>();

@ -0,0 +1,7 @@
namespace Trash
{
public interface ILogJanitor
{
void DeleteOldestLogFiles(int numberOfNewestToKeep);
}
}

@ -0,0 +1,25 @@
using System.IO.Abstractions;
using System.Linq;
namespace Trash
{
public class LogJanitor : ILogJanitor
{
private readonly IFileSystem _fileSystem;
public LogJanitor(IFileSystem fileSystem)
{
_fileSystem = fileSystem;
}
public void DeleteOldestLogFiles(int numberOfNewestToKeep)
{
foreach (var file in _fileSystem.DirectoryInfo.FromDirectoryName(AppPaths.LogDirectory).GetFiles()
.OrderByDescending(f => f.Name)
.Skip(numberOfNewestToKeep))
{
file.Delete();
}
}
}
}

@ -24,10 +24,11 @@ namespace Trash.Radarr
public RadarrCommand(
ILogger logger,
LoggingLevelSwitch loggingLevelSwitch,
ILogJanitor logJanitor,
IConfigurationLoader<RadarrConfiguration> configLoader,
Func<RadarrQualityDefinitionUpdater> qualityUpdaterFactory,
Lazy<ICustomFormatUpdater> customFormatUpdater)
: base(logger, loggingLevelSwitch)
: base(logger, loggingLevelSwitch, logJanitor)
{
_configLoader = configLoader;
_qualityUpdaterFactory = qualityUpdaterFactory;

@ -24,10 +24,11 @@ namespace Trash.Sonarr
public SonarrCommand(
ILogger logger,
LoggingLevelSwitch loggingLevelSwitch,
ILogJanitor logJanitor,
IConfigurationLoader<SonarrConfiguration> configLoader,
Func<ReleaseProfileUpdater> profileUpdaterFactory,
Func<SonarrQualityDefinitionUpdater> qualityUpdaterFactory)
: base(logger, loggingLevelSwitch)
: base(logger, loggingLevelSwitch, logJanitor)
{
_configLoader = configLoader;
_profileUpdaterFactory = profileUpdaterFactory;

@ -12,6 +12,7 @@
<PackageReference Include="CliFx" />
<PackageReference Include="Flurl.Http" />
<PackageReference Include="Flurl" />
<PackageReference Include="Serilog.Sinks.File" />
<PackageReference Include="Serilog.Sinks.Console" />
<PackageReference Include="Serilog" />
<PackageReference Include="System.Data.HashFunction.FNV" />

Loading…
Cancel
Save