From e910c9875f77c0ce7d1ec0e46afa556b4c7ebc83 Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Tue, 25 Sep 2018 11:12:29 -0400 Subject: [PATCH] Improve file log formatting --- .../Configuration/FileLoggingConfiguration.cs | 34 +++++++++ .../Configuration/GeneralConfiguration.cs | 15 ---- src/Tgstation.Server.Host/Core/Application.cs | 73 +++++++++++++++---- .../Tgstation.Server.Host.csproj | 4 +- .../appsettings.Development.json | 4 +- src/Tgstation.Server.Host/appsettings.json | 9 ++- 6 files changed, 105 insertions(+), 34 deletions(-) create mode 100644 src/Tgstation.Server.Host/Configuration/FileLoggingConfiguration.cs diff --git a/src/Tgstation.Server.Host/Configuration/FileLoggingConfiguration.cs b/src/Tgstation.Server.Host/Configuration/FileLoggingConfiguration.cs new file mode 100644 index 0000000000..7650a7573e --- /dev/null +++ b/src/Tgstation.Server.Host/Configuration/FileLoggingConfiguration.cs @@ -0,0 +1,34 @@ +namespace Tgstation.Server.Host.Configuration +{ + /// + /// File logging configuration options + /// + sealed class FileLoggingConfiguration + { + /// + /// The key for the the resides in + /// + public const string Section = "FileLogging"; + + /// + /// Where log files are stored + /// + public string Directory { get; set; } + + /// + /// If file logging is disabled + /// + public bool Disable { get; set; } + + /// + /// The ified minimum to display in logs + /// + public string LogLevel { get; set; } + + + /// + /// The ified minimum to display in logs for Microsoft library sources + /// + public string MicrosoftLogLevel { get; set; } + } +} diff --git a/src/Tgstation.Server.Host/Configuration/GeneralConfiguration.cs b/src/Tgstation.Server.Host/Configuration/GeneralConfiguration.cs index fc5cf03f09..ccf366863c 100644 --- a/src/Tgstation.Server.Host/Configuration/GeneralConfiguration.cs +++ b/src/Tgstation.Server.Host/Configuration/GeneralConfiguration.cs @@ -10,21 +10,6 @@ /// public const string Section = "General"; - /// - /// Where log files are stored - /// - public string LogFileDirectory { get; set; } - - /// - /// The stringified for file logging - /// - public string LogFileLevel { get; set; } - - /// - /// If file logging is disabled - /// - public bool DisableFileLogging { get; set; } - /// /// Minimum length of database user passwords /// diff --git a/src/Tgstation.Server.Host/Core/Application.cs b/src/Tgstation.Server.Host/Core/Application.cs index 3c654d2c52..225b915ef6 100644 --- a/src/Tgstation.Server.Host/Core/Application.cs +++ b/src/Tgstation.Server.Host/Core/Application.cs @@ -13,6 +13,9 @@ using Microsoft.Extensions.Primitives; using Microsoft.IdentityModel.Tokens; using Newtonsoft.Json; using Newtonsoft.Json.Converters; +using Serilog; +using Serilog.Events; +using Serilog.Formatting.Display; using System; using System.Globalization; using System.IdentityModel.Tokens.Jwt; @@ -54,12 +57,6 @@ namespace Tgstation.Server.Host.Core readonly Microsoft.AspNetCore.Hosting.IHostingEnvironment hostingEnvironment; readonly TaskCompletionSource startupTcs; - static LogLevel GetMinimumLogLevel(string stringLevel) - { - if (String.IsNullOrWhiteSpace(stringLevel) || !Enum.TryParse(stringLevel, out var minimumLevel)) - minimumLevel = LogLevel.Information; - return minimumLevel; - } /// /// Construct an @@ -89,19 +86,69 @@ namespace Tgstation.Server.Host.Core services.Configure(configuration.GetSection(UpdatesConfiguration.Section)); var databaseConfigurationSection = configuration.GetSection(DatabaseConfiguration.Section); services.Configure(databaseConfigurationSection); - var generalConfigurationSection = configuration.GetSection(GeneralConfiguration.Section); - services.Configure(generalConfigurationSection); + services.Configure(configuration.GetSection(GeneralConfiguration.Section)); - //remember, anything you .Get manually can be null if the config is missing - var generalConfiguration = generalConfigurationSection.Get(); var isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); var ioManager = new DefaultIOManager(); - if (generalConfiguration?.DisableFileLogging != true) + //remember, anything you .Get manually can be null if the config is missing + var fileLoggingConfigurationSection = configuration.GetSection(FileLoggingConfiguration.Section); + var fileLoggingConfiguration = fileLoggingConfigurationSection.Get(); + if (fileLoggingConfiguration?.Disable != true) { - var logPath = !String.IsNullOrEmpty(generalConfiguration?.LogFileDirectory) ? generalConfiguration.LogFileDirectory : ioManager.ConcatPath(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), VersionPrefix, "Logs"); + var logPath = !String.IsNullOrEmpty(fileLoggingConfiguration?.Directory) ? fileLoggingConfiguration.Directory : ioManager.ConcatPath(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), VersionPrefix, "Logs"); - services.AddLogging(builder => builder.AddFile(ioManager.ConcatPath(logPath, "tgs-{Date}.log"), GetMinimumLogLevel(generalConfiguration?.LogFileLevel))); + logPath = ioManager.ConcatPath(logPath, "tgs-{Date}.log"); + + services.AddLogging(builder => + { + LogLevel GetMinimumLogLevel(string stringLevel) + { + if (String.IsNullOrWhiteSpace(stringLevel) || !Enum.TryParse(stringLevel, out var minimumLevel)) + minimumLevel = LogLevel.Information; + return minimumLevel; + } + + LogEventLevel? ConvertLogLevel(LogLevel logLevel) + { + switch (logLevel) + { + case LogLevel.Critical: + return LogEventLevel.Fatal; + case LogLevel.Debug: + return LogEventLevel.Debug; + case LogLevel.Error: + return LogEventLevel.Error; + case LogLevel.Information: + return LogEventLevel.Information; + case LogLevel.Trace: + return LogEventLevel.Verbose; + case LogLevel.Warning: + return LogEventLevel.Warning; + case LogLevel.None: + return null; + default: + throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "Invalid log level {0}", logLevel)); + } + }; + + var logEventLevel = ConvertLogLevel(GetMinimumLogLevel(fileLoggingConfiguration?.LogLevel)); + var microsoftEventLevel = ConvertLogLevel(GetMinimumLogLevel(fileLoggingConfiguration?.MicrosoftLogLevel)); + + var formatter = new MessageTemplateTextFormatter("{Timestamp:o} {RequestId,13} [{Level:u3}] {SourceContext:l}: {Message} ({EventId:x8}){NewLine}{Exception}", null); + + var configuration = new LoggerConfiguration() + .Enrich.FromLogContext() + .WriteTo.Async(w => w.RollingFile(formatter, logPath, shared: true, flushToDiskInterval: TimeSpan.FromSeconds(2))); + + if (logEventLevel.HasValue) + configuration.MinimumLevel.Is(logEventLevel.Value); + + if (microsoftEventLevel.HasValue) + configuration.MinimumLevel.Override("Microsoft", microsoftEventLevel.Value); + + builder.AddSerilog(configuration.CreateLogger(), true); + }); } services.AddOptions(); diff --git a/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj b/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj index 3c20773be9..7921dd2120 100644 --- a/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj +++ b/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj @@ -42,7 +42,9 @@ - + + + diff --git a/src/Tgstation.Server.Host/appsettings.Development.json b/src/Tgstation.Server.Host/appsettings.Development.json index bf605320bf..5510b3cca2 100644 --- a/src/Tgstation.Server.Host/appsettings.Development.json +++ b/src/Tgstation.Server.Host/appsettings.Development.json @@ -1,5 +1,5 @@ { - "General": { - "DisableFileLogging": true + "FileLogging": { + "Disable": true } } diff --git a/src/Tgstation.Server.Host/appsettings.json b/src/Tgstation.Server.Host/appsettings.json index 0504931d30..e24be80260 100644 --- a/src/Tgstation.Server.Host/appsettings.json +++ b/src/Tgstation.Server.Host/appsettings.json @@ -1,11 +1,14 @@ { "General": { - "LogFileDirectory": null, //use the default path - "DisableFileLogging": false, - "LogFileLevel": "Debug", "MinimumPasswordLength": 15, "GitHubAccessToken": null }, + "FileLogging": { + "Directory": null, //use the default path + "Disable": false, + "LogLevel": "Debug", + "MicrosoftLogLevel": "Warning" + }, "Kestrel": { "EndPoints": { "Http": {