Logging Enhancements (#1521)
* Recreated Kavita Logging with Serilog instead of Default. This needs to be move out of the appsettings now, to allow auto updater to patch. * Refactored the code to be completely configured via Code rather than appsettings.json. This is a required step for Auto Updating. * Added in the ability to send logs directly to the UI only for users on the log route. Stopping implementation as Alerts page will handle the rest of the implementation. * Fixed up the backup service to not rely on Config from appsettings.json * Tweaked the Logging levels available * Moved everything over to File-scoped namespaces * Moved everything over to File-scoped namespaces * Code cleanup, removed an old migration and changed so debug logging doesn't print sensitive db data * Removed dead code
This commit is contained in:
parent
9f715cc35f
commit
d1a14f7e68
212 changed files with 16599 additions and 16834 deletions
157
API/Program.cs
157
API/Program.cs
|
@ -7,7 +7,9 @@ using System.Threading.Tasks;
|
|||
using API.Data;
|
||||
using API.Entities;
|
||||
using API.Entities.Enums;
|
||||
using API.Logging;
|
||||
using API.Services;
|
||||
using API.SignalR;
|
||||
using Kavita.Common;
|
||||
using Kavita.Common.EnvironmentInfo;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
|
@ -18,35 +20,42 @@ using Microsoft.Extensions.Configuration;
|
|||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Serilog;
|
||||
using Serilog.Events;
|
||||
using Serilog.Sinks.AspNetCore.SignalR.Extensions;
|
||||
|
||||
namespace API
|
||||
namespace API;
|
||||
|
||||
public class Program
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
private static readonly int HttpPort = Configuration.Port;
|
||||
private static readonly int HttpPort = Configuration.Port;
|
||||
|
||||
protected Program()
|
||||
protected Program()
|
||||
{
|
||||
}
|
||||
|
||||
public static async Task Main(string[] args)
|
||||
{
|
||||
Console.OutputEncoding = System.Text.Encoding.UTF8;
|
||||
var isDocker = new OsInfo(Array.Empty<IOsVersionAdapter>()).IsDocker;
|
||||
Log.Logger = new LoggerConfiguration()
|
||||
.WriteTo.Console()
|
||||
.CreateBootstrapLogger();
|
||||
|
||||
var directoryService = new DirectoryService(null, new FileSystem());
|
||||
|
||||
// Before anything, check if JWT has been generated properly or if user still has default
|
||||
if (!Configuration.CheckIfJwtTokenSet() &&
|
||||
Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") != Environments.Development)
|
||||
{
|
||||
Console.WriteLine("Generating JWT TokenKey for encrypting user sessions...");
|
||||
var rBytes = new byte[128];
|
||||
RandomNumberGenerator.Create().GetBytes(rBytes);
|
||||
Configuration.JwtToken = Convert.ToBase64String(rBytes).Replace("/", string.Empty);
|
||||
}
|
||||
|
||||
public static async Task Main(string[] args)
|
||||
try
|
||||
{
|
||||
Console.OutputEncoding = System.Text.Encoding.UTF8;
|
||||
var isDocker = new OsInfo(Array.Empty<IOsVersionAdapter>()).IsDocker;
|
||||
|
||||
|
||||
var directoryService = new DirectoryService(null, new FileSystem());
|
||||
|
||||
// Before anything, check if JWT has been generated properly or if user still has default
|
||||
if (!Configuration.CheckIfJwtTokenSet() &&
|
||||
Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") != Environments.Development)
|
||||
{
|
||||
Console.WriteLine("Generating JWT TokenKey for encrypting user sessions...");
|
||||
var rBytes = new byte[128];
|
||||
RandomNumberGenerator.Create().GetBytes(rBytes);
|
||||
Configuration.JwtToken = Convert.ToBase64String(rBytes).Replace("/", string.Empty);
|
||||
}
|
||||
|
||||
var host = CreateHostBuilder(args).Build();
|
||||
|
||||
using var scope = host.Services.CreateScope();
|
||||
|
@ -97,58 +106,76 @@ namespace API
|
|||
return;
|
||||
}
|
||||
|
||||
// Update the logger with the log level
|
||||
var unitOfWork = services.GetRequiredService<IUnitOfWork>();
|
||||
var settings = await unitOfWork.SettingsRepository.GetSettingsDtoAsync();
|
||||
LogLevelOptions.SwitchLogLevel(settings.LoggingLevel);
|
||||
|
||||
await host.RunAsync();
|
||||
}
|
||||
|
||||
private static async Task<string> GetMigrationDirectory(DataContext context, IDirectoryService directoryService)
|
||||
} catch (Exception ex)
|
||||
{
|
||||
string currentVersion = null;
|
||||
try
|
||||
{
|
||||
if (!await context.ServerSetting.AnyAsync()) return "vUnknown";
|
||||
currentVersion =
|
||||
(await context.ServerSetting.SingleOrDefaultAsync(s =>
|
||||
s.Key == ServerSettingKey.InstallVersion))?.Value;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
Log.Fatal(ex, "Host terminated unexpectedly");
|
||||
} finally
|
||||
{
|
||||
Log.CloseAndFlush();
|
||||
}
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(currentVersion))
|
||||
{
|
||||
currentVersion = "vUnknown";
|
||||
}
|
||||
|
||||
var migrationDirectory = directoryService.FileSystem.Path.Join(directoryService.TempDirectory,
|
||||
"migration", currentVersion);
|
||||
return migrationDirectory;
|
||||
private static async Task<string> GetMigrationDirectory(DataContext context, IDirectoryService directoryService)
|
||||
{
|
||||
string currentVersion = null;
|
||||
try
|
||||
{
|
||||
if (!await context.ServerSetting.AnyAsync()) return "vUnknown";
|
||||
currentVersion =
|
||||
(await context.ServerSetting.SingleOrDefaultAsync(s =>
|
||||
s.Key == ServerSettingKey.InstallVersion))?.Value;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
private static IHostBuilder CreateHostBuilder(string[] args) =>
|
||||
Host.CreateDefaultBuilder(args)
|
||||
.ConfigureAppConfiguration((hostingContext, config) =>
|
||||
if (string.IsNullOrEmpty(currentVersion))
|
||||
{
|
||||
currentVersion = "vUnknown";
|
||||
}
|
||||
|
||||
var migrationDirectory = directoryService.FileSystem.Path.Join(directoryService.TempDirectory,
|
||||
"migration", currentVersion);
|
||||
return migrationDirectory;
|
||||
}
|
||||
|
||||
private static IHostBuilder CreateHostBuilder(string[] args) =>
|
||||
Host.CreateDefaultBuilder(args)
|
||||
.UseSerilog((_, services, configuration) =>
|
||||
{
|
||||
LogLevelOptions.CreateConfig(configuration)
|
||||
.WriteTo.SignalRSink<LogHub, ILogHub>(
|
||||
LogEventLevel.Information,
|
||||
services);
|
||||
})
|
||||
.ConfigureAppConfiguration((hostingContext, config) =>
|
||||
{
|
||||
config.Sources.Clear();
|
||||
|
||||
var env = hostingContext.HostingEnvironment;
|
||||
|
||||
config.AddJsonFile("config/appsettings.json", optional: true, reloadOnChange: false)
|
||||
.AddJsonFile($"config/appsettings.{env.EnvironmentName}.json",
|
||||
optional: true, reloadOnChange: false);
|
||||
})
|
||||
.ConfigureWebHostDefaults(webBuilder =>
|
||||
{
|
||||
webBuilder.UseKestrel((opts) =>
|
||||
{
|
||||
config.Sources.Clear();
|
||||
|
||||
var env = hostingContext.HostingEnvironment;
|
||||
|
||||
config.AddJsonFile("config/appsettings.json", optional: true, reloadOnChange: false)
|
||||
.AddJsonFile($"config/appsettings.{env.EnvironmentName}.json",
|
||||
optional: true, reloadOnChange: false);
|
||||
})
|
||||
.ConfigureWebHostDefaults(webBuilder =>
|
||||
{
|
||||
webBuilder.UseKestrel((opts) =>
|
||||
{
|
||||
opts.ListenAnyIP(HttpPort, options => { options.Protocols = HttpProtocols.Http1AndHttp2; });
|
||||
});
|
||||
|
||||
webBuilder.UseStartup<Startup>();
|
||||
opts.ListenAnyIP(HttpPort, options => { options.Protocols = HttpProtocols.Http1AndHttp2; });
|
||||
});
|
||||
|
||||
webBuilder.UseStartup<Startup>();
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue