From 906fc2dadfa2348619388bf39de4fb4533bd6885 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Mon, 28 Nov 2022 08:47:54 +0100 Subject: [PATCH 1/5] Allow changing logging directory from configuration --- .../Configuration/Models/LoggingSettings.cs | 20 +++++++ .../Constants-SystemDirectories.cs | 1 + .../Logging/Serilog/LoggerConfigExtensions.cs | 60 ++++++++++++++++++- .../Migrations/Install/DatabaseBuilder.cs | 2 +- .../Extensions/ServiceCollectionExtensions.cs | 16 +++-- 5 files changed, 92 insertions(+), 7 deletions(-) diff --git a/src/Umbraco.Core/Configuration/Models/LoggingSettings.cs b/src/Umbraco.Core/Configuration/Models/LoggingSettings.cs index 37b671926c55..a6b4fa361912 100644 --- a/src/Umbraco.Core/Configuration/Models/LoggingSettings.cs +++ b/src/Umbraco.Core/Configuration/Models/LoggingSettings.cs @@ -2,6 +2,8 @@ // See LICENSE for more details. using System.ComponentModel; +using Microsoft.Extensions.Hosting; +using Umbraco.Cms.Core.Extensions; namespace Umbraco.Cms.Core.Configuration.Models; @@ -12,10 +14,28 @@ namespace Umbraco.Cms.Core.Configuration.Models; public class LoggingSettings { internal const string StaticMaxLogAge = "1.00:00:00"; // TimeSpan.FromHours(24); + internal const string StaticLoggingDirectory = Constants.SystemDirectories.LogFiles; /// /// Gets or sets a value for the maximum age of a log file. /// [DefaultValue(StaticMaxLogAge)] public TimeSpan MaxLogAge { get; set; } = TimeSpan.Parse(StaticMaxLogAge); + + /// + /// Gets or sets the folder to use for log files + /// + [DefaultValue(StaticLoggingDirectory)] + public string LoggingDirectory { get; set; } = StaticLoggingDirectory; + + public string GetAbsoluteLoggingPath(IHostEnvironment hostEnvironment) + { + var dir = LoggingDirectory; + if (dir.StartsWith("~/")) + { + hostEnvironment.MapPathContentRoot(dir); + } + + return dir; + } } diff --git a/src/Umbraco.Core/Constants-SystemDirectories.cs b/src/Umbraco.Core/Constants-SystemDirectories.cs index 85375390ac0a..27d66e18c6be 100644 --- a/src/Umbraco.Core/Constants-SystemDirectories.cs +++ b/src/Umbraco.Core/Constants-SystemDirectories.cs @@ -60,6 +60,7 @@ public static class SystemDirectories /// /// The default folder where Umbraco log files are stored /// + [Obsolete("Use LoggingSettings.GetLoggingDirectory() instead")] public const string LogFiles = Umbraco + "/Logs"; [Obsolete("Use PluginIcons instead")] diff --git a/src/Umbraco.Infrastructure/Logging/Serilog/LoggerConfigExtensions.cs b/src/Umbraco.Infrastructure/Logging/Serilog/LoggerConfigExtensions.cs index d8c6d1ff8fd7..6fb9905959d3 100644 --- a/src/Umbraco.Infrastructure/Logging/Serilog/LoggerConfigExtensions.cs +++ b/src/Umbraco.Infrastructure/Logging/Serilog/LoggerConfigExtensions.cs @@ -7,6 +7,7 @@ using Serilog.Events; using Serilog.Formatting; using Serilog.Formatting.Compact; +using Umbraco.Cms.Core.Configuration.Models; using Umbraco.Cms.Core.Extensions; using Umbraco.Cms.Core.Logging; using Umbraco.Cms.Core.Logging.Serilog.Enrichers; @@ -21,7 +22,7 @@ public static class LoggerConfigExtensions /// Such as adding ProcessID, Thread, AppDomain etc /// It is highly recommended that you keep/use this default in your own logging config customizations /// - [Obsolete("Please use an alternative method.")] + [Obsolete("Please use an alternative method. This will be removed in Umbraco 13.")] public static LoggerConfiguration MinimalConfiguration( this LoggerConfiguration logConfig, Umbraco.Cms.Core.Hosting.IHostingEnvironment hostingEnvironment, @@ -36,7 +37,7 @@ public static LoggerConfiguration MinimalConfiguration( /// Such as adding ProcessID, Thread, AppDomain etc /// It is highly recommended that you keep/use this default in your own logging config customizations /// - [Obsolete("Please use an alternative method.")] + [Obsolete("Please use an alternative method. This will be removed in Umbraco 13.")] public static LoggerConfiguration MinimalConfiguration( this LoggerConfiguration logConfig, Umbraco.Cms.Core.Hosting.IHostingEnvironment hostingEnvironment, @@ -126,6 +127,7 @@ public static LoggerConfiguration MinimalConfiguration( /// /// The log level you wish the JSON file to collect - default is Verbose (highest) /// The number of days to keep log files. Default is set to null which means all logs are kept + [Obsolete("Will be removed in the Umbraco 13.")] public static LoggerConfiguration OutputDefaultTextFile( this LoggerConfiguration logConfig, Umbraco.Cms.Core.Hosting.IHostingEnvironment hostingEnvironment, @@ -144,6 +146,31 @@ public static LoggerConfiguration OutputDefaultTextFile( return logConfig; } + /// + /// Outputs a .txt format log at /App_Data/Logs/ + /// + /// A Serilog LoggerConfiguration + /// + /// + /// The log level you wish the JSON file to collect - default is Verbose (highest) + public static LoggerConfiguration OutputDefaultTextFile( + this LoggerConfiguration logConfig, + IHostEnvironment hostEnvironment, + LoggingSettings loggingSettings, + LogEventLevel minimumLevel = LogEventLevel.Verbose) + { + //Main .txt logfile - in similar format to older Log4Net output + //Ends with ..txt as Date is inserted before file extension substring + logConfig.WriteTo.File( + Path.Combine(loggingSettings.GetAbsoluteLoggingPath(hostEnvironment), $"UmbracoTraceLog.{Environment.MachineName}..txt"), + shared: true, + rollingInterval: RollingInterval.Day, + restrictedToMinimumLevel: minimumLevel, + retainedFileCountLimit: null, //Setting to null means we keep all files - default is 31 days + outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss,fff} [P{ProcessId}/D{AppDomainId}/T{ThreadId}] {Log4NetLevel} {SourceContext} - {Message:lj}{NewLine}{Exception}"); + + return logConfig; + } /// /// Used in config - If renamed or moved to other assembly the config file also has be updated. @@ -195,6 +222,7 @@ public static LoggerConfiguration UmbracoFile( /// The log level you wish the JSON file to collect - default is Verbose (highest) /// /// The number of days to keep log files. Default is set to null which means all logs are kept + [Obsolete("Will be removed in the Umbraco 13.")] public static LoggerConfiguration OutputDefaultJsonFile( this LoggerConfiguration logConfig, Umbraco.Cms.Core.Hosting.IHostingEnvironment hostingEnvironment, @@ -215,5 +243,33 @@ public static LoggerConfiguration OutputDefaultJsonFile( return logConfig; } + /// + /// Outputs a CLEF format JSON log at /App_Data/Logs/ + /// + /// A Serilog LoggerConfiguration + /// + /// The logging configuration + /// The log level you wish the JSON file to collect - default is Verbose (highest) + /// The number of days to keep log files. Default is set to null which means all logs are kept + public static LoggerConfiguration OutputDefaultJsonFile( + this LoggerConfiguration logConfig, + IHostEnvironment hostEnvironment, + LoggingSettings loggingSettings, + LogEventLevel minimumLevel = LogEventLevel.Verbose, + int? retainedFileCount = null) + { + // .clef format (Compact log event format, that can be imported into local SEQ & will make searching/filtering logs easier) + // Ends with ..txt as Date is inserted before file extension substring + logConfig.WriteTo.File( + new CompactJsonFormatter(), + Path.Combine(loggingSettings.GetAbsoluteLoggingPath(hostEnvironment) ,$"UmbracoTraceLog.{Environment.MachineName}..json"), + shared: true, + rollingInterval: RollingInterval.Day, // Create a new JSON file every day + retainedFileCountLimit: retainedFileCount, // Setting to null means we keep all files - default is 31 days + restrictedToMinimumLevel: minimumLevel); + + return logConfig; + } + } } diff --git a/src/Umbraco.Infrastructure/Migrations/Install/DatabaseBuilder.cs b/src/Umbraco.Infrastructure/Migrations/Install/DatabaseBuilder.cs index d8e132440ca1..1218880fd6c5 100644 --- a/src/Umbraco.Infrastructure/Migrations/Install/DatabaseBuilder.cs +++ b/src/Umbraco.Infrastructure/Migrations/Install/DatabaseBuilder.cs @@ -373,7 +373,7 @@ private Result HandleInstallException(Exception ex) { Message = "The database configuration failed with the following message: " + ex.Message + - $"\n Please check log file for additional information (can be found in '{Constants.SystemDirectories.LogFiles}')", + $"\n Please check log file for additional information (can be found in '{nameof(LoggingSettings)}.{nameof(LoggingSettings.LoggingDirectory)}')", Success = false, Percentage = "90" }; diff --git a/src/Umbraco.Web.Common/Extensions/ServiceCollectionExtensions.cs b/src/Umbraco.Web.Common/Extensions/ServiceCollectionExtensions.cs index 9a9d606644dd..69ee0c9a1eb2 100644 --- a/src/Umbraco.Web.Common/Extensions/ServiceCollectionExtensions.cs +++ b/src/Umbraco.Web.Common/Extensions/ServiceCollectionExtensions.cs @@ -82,14 +82,15 @@ public static IServiceCollection AddLogger( IHostEnvironment hostEnvironment, IConfiguration configuration) { - // TODO: WEBSITE_RUN_FROM_PACKAGE - can't assume this DIR is writable - we have an IConfiguration instance so a later refactor should be easy enough. - var loggingDir = hostEnvironment.MapPathContentRoot(Constants.SystemDirectories.LogFiles); + LoggingSettings loggerSettings = GetLoggerSettings(configuration); + + var loggingDir = loggerSettings.GetAbsoluteLoggingPath(hostEnvironment); ILoggingConfiguration loggingConfig = new LoggingConfiguration(loggingDir); var umbracoFileConfiguration = new UmbracoFileConfiguration(configuration); - services.TryAddSingleton(umbracoFileConfiguration); - services.TryAddSingleton(loggingConfig); + services.TryAddSingleton(x => umbracoFileConfiguration); + services.TryAddSingleton(x => loggingConfig); services.TryAddSingleton(); /////////////////////////////////////////////// @@ -146,6 +147,13 @@ public static IServiceCollection AddLogger( return services; } + private static LoggingSettings GetLoggerSettings(IConfiguration configuration) + { + var loggerSettings = new LoggingSettings(); + configuration.GetSection(Constants.Configuration.ConfigLogging).Bind(loggerSettings); + return loggerSettings; + } + /// /// Called to create the to assign to the /// From 025b0cf14db27995056cc72bc74c216b9f5f5d07 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Mon, 28 Nov 2022 13:45:34 +0100 Subject: [PATCH 2/5] Clean up --- src/Umbraco.Core/Configuration/Models/LoggingSettings.cs | 8 ++++---- .../Migrations/Install/DatabaseBuilder.cs | 2 +- .../Extensions/ServiceCollectionExtensions.cs | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Umbraco.Core/Configuration/Models/LoggingSettings.cs b/src/Umbraco.Core/Configuration/Models/LoggingSettings.cs index a6b4fa361912..4ce8fda54d5f 100644 --- a/src/Umbraco.Core/Configuration/Models/LoggingSettings.cs +++ b/src/Umbraco.Core/Configuration/Models/LoggingSettings.cs @@ -14,7 +14,7 @@ namespace Umbraco.Cms.Core.Configuration.Models; public class LoggingSettings { internal const string StaticMaxLogAge = "1.00:00:00"; // TimeSpan.FromHours(24); - internal const string StaticLoggingDirectory = Constants.SystemDirectories.LogFiles; + internal const string StaticDirectory = Constants.SystemDirectories.LogFiles; /// /// Gets or sets a value for the maximum age of a log file. @@ -25,12 +25,12 @@ public class LoggingSettings /// /// Gets or sets the folder to use for log files /// - [DefaultValue(StaticLoggingDirectory)] - public string LoggingDirectory { get; set; } = StaticLoggingDirectory; + [DefaultValue(StaticDirectory)] + public string Directory { get; set; } = StaticDirectory; public string GetAbsoluteLoggingPath(IHostEnvironment hostEnvironment) { - var dir = LoggingDirectory; + var dir = Directory; if (dir.StartsWith("~/")) { hostEnvironment.MapPathContentRoot(dir); diff --git a/src/Umbraco.Infrastructure/Migrations/Install/DatabaseBuilder.cs b/src/Umbraco.Infrastructure/Migrations/Install/DatabaseBuilder.cs index 1218880fd6c5..bd3fc6849dd4 100644 --- a/src/Umbraco.Infrastructure/Migrations/Install/DatabaseBuilder.cs +++ b/src/Umbraco.Infrastructure/Migrations/Install/DatabaseBuilder.cs @@ -373,7 +373,7 @@ private Result HandleInstallException(Exception ex) { Message = "The database configuration failed with the following message: " + ex.Message + - $"\n Please check log file for additional information (can be found in '{nameof(LoggingSettings)}.{nameof(LoggingSettings.LoggingDirectory)}')", + $"\n Please check log file for additional information (can be found in '{nameof(LoggingSettings)}.{nameof(LoggingSettings.Directory)}')", Success = false, Percentage = "90" }; diff --git a/src/Umbraco.Web.Common/Extensions/ServiceCollectionExtensions.cs b/src/Umbraco.Web.Common/Extensions/ServiceCollectionExtensions.cs index 69ee0c9a1eb2..a5e30f9011e8 100644 --- a/src/Umbraco.Web.Common/Extensions/ServiceCollectionExtensions.cs +++ b/src/Umbraco.Web.Common/Extensions/ServiceCollectionExtensions.cs @@ -89,8 +89,8 @@ public static IServiceCollection AddLogger( var umbracoFileConfiguration = new UmbracoFileConfiguration(configuration); - services.TryAddSingleton(x => umbracoFileConfiguration); - services.TryAddSingleton(x => loggingConfig); + services.TryAddSingleton(umbracoFileConfiguration); + services.TryAddSingleton(loggingConfig); services.TryAddSingleton(); /////////////////////////////////////////////// From 36b02eee819f46677f644c5116daf7d4900a07cb Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Mon, 28 Nov 2022 14:38:37 +0100 Subject: [PATCH 3/5] Missing return statement --- src/Umbraco.Core/Configuration/Models/LoggingSettings.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Core/Configuration/Models/LoggingSettings.cs b/src/Umbraco.Core/Configuration/Models/LoggingSettings.cs index 4ce8fda54d5f..90498991a4f8 100644 --- a/src/Umbraco.Core/Configuration/Models/LoggingSettings.cs +++ b/src/Umbraco.Core/Configuration/Models/LoggingSettings.cs @@ -33,7 +33,7 @@ public string GetAbsoluteLoggingPath(IHostEnvironment hostEnvironment) var dir = Directory; if (dir.StartsWith("~/")) { - hostEnvironment.MapPathContentRoot(dir); + return hostEnvironment.MapPathContentRoot(dir); } return dir; From 3b3788e884b279eefa438a9a2640e588053503a9 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Mon, 28 Nov 2022 14:39:08 +0100 Subject: [PATCH 4/5] Apply suggestions from code review Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com> --- .../Logging/Serilog/LoggerConfigExtensions.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Infrastructure/Logging/Serilog/LoggerConfigExtensions.cs b/src/Umbraco.Infrastructure/Logging/Serilog/LoggerConfigExtensions.cs index 6fb9905959d3..59e4eeb10540 100644 --- a/src/Umbraco.Infrastructure/Logging/Serilog/LoggerConfigExtensions.cs +++ b/src/Umbraco.Infrastructure/Logging/Serilog/LoggerConfigExtensions.cs @@ -127,7 +127,7 @@ public static LoggerConfiguration MinimalConfiguration( /// /// The log level you wish the JSON file to collect - default is Verbose (highest) /// The number of days to keep log files. Default is set to null which means all logs are kept - [Obsolete("Will be removed in the Umbraco 13.")] + [Obsolete("Will be removed in Umbraco 13.")] public static LoggerConfiguration OutputDefaultTextFile( this LoggerConfiguration logConfig, Umbraco.Cms.Core.Hosting.IHostingEnvironment hostingEnvironment, @@ -222,7 +222,7 @@ public static LoggerConfiguration UmbracoFile( /// The log level you wish the JSON file to collect - default is Verbose (highest) /// /// The number of days to keep log files. Default is set to null which means all logs are kept - [Obsolete("Will be removed in the Umbraco 13.")] + [Obsolete("Will be removed in Umbraco 13.")] public static LoggerConfiguration OutputDefaultJsonFile( this LoggerConfiguration logConfig, Umbraco.Cms.Core.Hosting.IHostingEnvironment hostingEnvironment, From 1d591a8e8d6d0501446eb3748e605223eb6e1170 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Mon, 28 Nov 2022 14:39:24 +0100 Subject: [PATCH 5/5] Update src/Umbraco.Core/Constants-SystemDirectories.cs Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com> --- src/Umbraco.Core/Constants-SystemDirectories.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Core/Constants-SystemDirectories.cs b/src/Umbraco.Core/Constants-SystemDirectories.cs index 27d66e18c6be..d0e4488e0ea5 100644 --- a/src/Umbraco.Core/Constants-SystemDirectories.cs +++ b/src/Umbraco.Core/Constants-SystemDirectories.cs @@ -60,7 +60,7 @@ public static class SystemDirectories /// /// The default folder where Umbraco log files are stored /// - [Obsolete("Use LoggingSettings.GetLoggingDirectory() instead")] + [Obsolete("Use LoggingSettings.GetLoggingDirectory() instead, will be removed in Umbraco 13.")] public const string LogFiles = Umbraco + "/Logs"; [Obsolete("Use PluginIcons instead")]