Improved logging by switching to Serilog.

Refactored out hardcoded logpath and DB connection string and made them configurable through appsettings.json.
Add persistent store path in docker-compose.
This commit is contained in:
Roger Far 2021-01-09 11:05:33 -07:00
parent d6dbb2a750
commit cccf30c87d
10 changed files with 129 additions and 27 deletions

View file

@ -4,6 +4,7 @@ services:
image: rogerfar/rdtclient
volumes:
- 'C:/Downloads/:/data/downloads'
- 'C:/Docker/rdtclient/:/data/db'
container_name: rdtclient
restart: always
logging:

View file

@ -1,5 +1,4 @@
using System;
using System.Linq;
using System.Linq;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using RdtClient.Data.Models.Data;
@ -11,8 +10,6 @@ namespace RdtClient.Data.Data
public DataContext(DbContextOptions options) : base(options)
{
}
public static String ConnectionString => $"Data Source={AppContext.BaseDirectory}database.db";
public DbSet<Download> Downloads { get; set; }
public DbSet<Setting> Settings { get; set; }
@ -20,7 +17,7 @@ namespace RdtClient.Data.Data
protected override void OnConfiguring(DbContextOptionsBuilder options)
{
options.UseSqlite(ConnectionString);
}
protected override void OnModelCreating(ModelBuilder builder)

View file

@ -1,6 +1,37 @@
namespace RdtClient.Data.Models.Internal
using System;
namespace RdtClient.Data.Models.Internal
{
public class AppSettings
{
public AppSettingsLogging Logging { get; set; }
public AppSettingsDatabase Database { get; set; }
public String AllowedHosts { get; set; }
public String HostUrl { get; set; }
}
public class AppSettingsLogging
{
public AppSettingsLoggingLogLevel LogLevel { get; set; }
public AppSettingsLoggingFile File { get; set; }
}
public class AppSettingsLoggingLogLevel
{
public String Default { get; set; }
}
public class AppSettingsLoggingFile
{
public String Path { get; set; }
public String Append { get; set; }
public Int64 FileSizeLimitBytes { get; set; }
public Int32 MaxRollingFiles { get; set; }
}
public class AppSettingsDatabase
{
public String Path { get; set; }
}
}

View file

@ -15,6 +15,7 @@
</PackageReference>
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="RD.NET" Version="1.0.0" />
<PackageReference Include="Serilog" Version="2.10.0" />
</ItemGroup>
<ItemGroup>

View file

@ -9,6 +9,9 @@
<PackageReference Include="MonoTorrent" Version="1.0.28" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="RD.NET" Version="1.0.0" />
<PackageReference Include="Serilog" Version="2.10.0" />
<PackageReference Include="Serilog.Exceptions" Version="6.0.0" />
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
<PackageReference Include="SharpCompress" Version="0.26.0" />
</ItemGroup>

View file

@ -1,12 +1,17 @@
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using RdtClient.Data.Data;
using RdtClient.Data.Models.Internal;
using RdtClient.Service.Services;
using Serilog;
using Serilog.Events;
using Serilog.Exceptions;
namespace RdtClient.Web
{
@ -14,26 +19,68 @@ namespace RdtClient.Web
{
public static async Task Main(String[] args)
{
var host = CreateHostBuilder(args).Build();
try
{
var host = CreateHostBuilder(args).Build();
DataMigration.Setup(host.Services.CreateScope());
await host.RunAsync();
// Perform migrations
using (var scope = host.Services.CreateScope())
{
var dbContext = scope.ServiceProvider.GetRequiredService<DataContext>();
await dbContext.Database.MigrateAsync();
}
await host.RunAsync();
}
catch (Exception ex)
{
Log.Fatal(ex, "Host terminated unexpectedly");
}
finally
{
Log.CloseAndFlush();
}
}
// ReSharper disable once MemberCanBePrivate.Global
public static IHostBuilder CreateHostBuilder(String[] args)
{
var configuration = new ConfigurationBuilder()
#if DEBUG
.AddJsonFile("appsettings.Development.json", true, false)
#else
.AddJsonFile("appsettings.json", true, false)
#endif
.Build();
var hostUrl = configuration["HostUrl"];
var appSettings = new AppSettings();
configuration.Bind(appSettings);
if (String.IsNullOrWhiteSpace(hostUrl))
if (String.IsNullOrWhiteSpace(appSettings.HostUrl))
{
hostUrl = "http://0.0.0.0:6500";
appSettings.HostUrl = "http://0.0.0.0:6500";
}
if (!Enum.TryParse(appSettings.Logging.LogLevel.Default, out LogEventLevel logLevel))
{
logLevel = LogEventLevel.Information;
}
Log.Logger = new LoggerConfiguration()
.Enrich.FromLogContext()
.Enrich.WithExceptionDetails()
.WriteTo.File(appSettings.Logging.File.Path, logLevel, rollOnFileSizeLimit: true, fileSizeLimitBytes: appSettings.Logging.File.FileSizeLimitBytes, retainedFileCountLimit: appSettings.Logging.File.MaxRollingFiles)
.MinimumLevel.Information()
.CreateLogger();
Serilog.Debugging.SelfLog.Enable(msg =>
{
Debug.Print(msg);
Debugger.Break();
Console.WriteLine(msg);
Debug.WriteLine(msg);
});
return Host.CreateDefaultBuilder(args)
.UseWindowsService()
.ConfigureServices((hostContext, services) =>
@ -42,13 +89,8 @@ namespace RdtClient.Web
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.ConfigureLogging(logging =>
{
logging.ClearProviders();
logging.AddConsole();
logging.AddFile($"{AppContext.BaseDirectory}app.log");
})
.UseUrls(hostUrl)
webBuilder.UseUrls(appSettings.HostUrl)
.UseSerilog()
.UseKestrel()
.UseStartup<Startup>();
});

View file

@ -37,6 +37,9 @@
<PackageReference Include="Microsoft.Extensions.Identity.Core" Version="5.0.1" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="NReco.Logging.File" Version="1.1.1" />
<PackageReference Include="Serilog" Version="2.10.0" />
<PackageReference Include="Serilog.AspNetCore" Version="3.4.0" />
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
</ItemGroup>
<ItemGroup>

View file

@ -9,7 +9,6 @@ using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using RdtClient.Data;
using RdtClient.Data.Data;
using RdtClient.Data.Models.Internal;
using RdtClient.Service.Middleware;
@ -32,7 +31,8 @@ namespace RdtClient.Web
services.AddSingleton(appSettings);
services.AddDbContext<DataContext>(options => options.UseSqlite(DataContext.ConnectionString));
var connectionString = $"Data Source={appSettings.Database.Path}";
services.AddDbContext<DataContext>(options => options.UseSqlite(connectionString));
services.AddControllers()
.AddNewtonsoftJson();
@ -81,7 +81,7 @@ namespace RdtClient.Web
options.Cookie.Name = "SID";
});
DiConfig.Config(services);
Data.DiConfig.Config(services);
Service.DiConfig.Config(services);
}

View file

@ -0,0 +1,21 @@
{
"Logging": {
"LogLevel": {
"Default": "Debug",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information",
"Hangfire": "Information"
},
"File": {
"Path": "C:/Temp/rdtclient/rdtclient.log",
"Append": "True",
"FileSizeLimitBytes": 5242880,
"MaxRollingFiles": 5
}
},
"Database": {
"Path": "C:/Temp/rdtclient/rdtclient.db"
},
"AllowedHosts": "*",
"HostUrl": "http://0.0.0.0:6500"
}

View file

@ -7,12 +7,15 @@
"Hangfire": "Information"
},
"File": {
"Path": "app.log",
"Path": "/data/db/rdtclient.log",
"Append": "True",
"FileSizeLimitBytes": 2048,
"FileSizeLimitBytes": 5242880,
"MaxRollingFiles": 5
}
},
"Database": {
"Path": "/data/db/rdtclient.db"
},
"AllowedHosts": "*",
"HostUrl": "http://0.0.0.0:6500"
}
}