diff --git a/src/Umbraco.Core/Logging/ILoggingConfiguration.cs b/src/Umbraco.Core/Logging/ILoggingConfiguration.cs index 47e2d8fa7c..d21a08e688 100644 --- a/src/Umbraco.Core/Logging/ILoggingConfiguration.cs +++ b/src/Umbraco.Core/Logging/ILoggingConfiguration.cs @@ -7,7 +7,5 @@ /// The physical path where logs are stored /// string LogDirectory { get; } - string LogConfigurationFile { get; } - string UserLogConfigurationFile { get; } } } diff --git a/src/Umbraco.Core/Logging/LoggingConfiguration.cs b/src/Umbraco.Core/Logging/LoggingConfiguration.cs index c657c9d430..ecd806211c 100644 --- a/src/Umbraco.Core/Logging/LoggingConfiguration.cs +++ b/src/Umbraco.Core/Logging/LoggingConfiguration.cs @@ -4,17 +4,11 @@ namespace Umbraco.Core.Logging { public class LoggingConfiguration : ILoggingConfiguration { - public LoggingConfiguration(string logDirectory, string logConfigurationFile, string userLogConfigurationFile) + public LoggingConfiguration(string logDirectory) { LogDirectory = logDirectory ?? throw new ArgumentNullException(nameof(logDirectory)); - LogConfigurationFile = logConfigurationFile ?? throw new ArgumentNullException(nameof(logConfigurationFile)); - UserLogConfigurationFile = userLogConfigurationFile ?? throw new ArgumentNullException(nameof(userLogConfigurationFile)); } public string LogDirectory { get; } - - public string LogConfigurationFile { get; } - - public string UserLogConfigurationFile { get; } } } diff --git a/src/Umbraco.Infrastructure/Composing/HostBuilderExtensions.cs b/src/Umbraco.Infrastructure/Composing/HostBuilderExtensions.cs index f6d980f62a..ad7c75b94f 100644 --- a/src/Umbraco.Infrastructure/Composing/HostBuilderExtensions.cs +++ b/src/Umbraco.Infrastructure/Composing/HostBuilderExtensions.cs @@ -26,7 +26,6 @@ namespace Umbraco.Core.Composing /// /// public static IHostBuilder UseUmbraco(this IHostBuilder builder, UmbracoServiceProviderFactory umbracoServiceProviderFactory) - => builder.UseServiceProviderFactory(umbracoServiceProviderFactory) - .UseSerilog(); + => builder.UseServiceProviderFactory(umbracoServiceProviderFactory); } } diff --git a/src/Umbraco.Infrastructure/Logging/Serilog/LoggerConfigExtensions.cs b/src/Umbraco.Infrastructure/Logging/Serilog/LoggerConfigExtensions.cs index f2e028e6de..84270b95bf 100644 --- a/src/Umbraco.Infrastructure/Logging/Serilog/LoggerConfigExtensions.cs +++ b/src/Umbraco.Infrastructure/Logging/Serilog/LoggerConfigExtensions.cs @@ -7,7 +7,6 @@ using Serilog.Core; using Serilog.Events; using Serilog.Formatting; using Serilog.Formatting.Compact; -using Umbraco.Core.IO; using Umbraco.Core.Hosting; using Umbraco.Core.Logging.Serilog.Enrichers; @@ -48,6 +47,11 @@ namespace Umbraco.Core.Logging.Serilog .Enrich.With() .Enrich.FromLogContext(); // allows us to dynamically enrich + + logConfig.WriteTo.UmbracoFile( + Path.Combine(loggingConfiguration.LogDirectory, $"UmbracoTraceLog.{Environment.MachineName}..json") + ); + return logConfig; } @@ -61,7 +65,7 @@ namespace Umbraco.Core.Logging.Serilog public static LoggerConfiguration OutputDefaultTextFile( this LoggerConfiguration logConfig, IHostingEnvironment hostingEnvironment, - ILoggingConfiguration loggingConfiguration, LogEventLevel minimumLevel = LogEventLevel.Verbose, int? retainedFileCount = null) + 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 @@ -79,18 +83,25 @@ namespace Umbraco.Core.Logging.Serilog /// /// Used in config - If renamed or moved to other assembly the config file also has be updated. /// - public static LoggerConfiguration File(this LoggerSinkConfiguration configuration, ITextFormatter formatter, + public static LoggerConfiguration UmbracoFile(this LoggerSinkConfiguration configuration, string path, + ITextFormatter formatter = null, LogEventLevel restrictedToMinimumLevel = LogEventLevel.Verbose, LoggingLevelSwitch levelSwitch = null, long? fileSizeLimitBytes = 1073741824, TimeSpan? flushToDiskInterval = null, - RollingInterval rollingInterval = RollingInterval.Infinite, + RollingInterval rollingInterval = RollingInterval.Day, bool rollOnFileSizeLimit = false, int? retainedFileCountLimit = 31, Encoding encoding = null ) { + + if (formatter is null) + { + formatter = new CompactJsonFormatter(); + } + return configuration.Async( asyncConfiguration => asyncConfiguration.Map(AppDomainId, (_,mapConfiguration) => mapConfiguration.File( @@ -136,34 +147,5 @@ namespace Umbraco.Core.Logging.Serilog return logConfig; } - /// - /// Reads settings from /config/serilog.config - /// That allows the main logging pipeline to be configured - /// - /// A Serilog LoggerConfiguration - /// - public static LoggerConfiguration ReadFromConfigFile(this LoggerConfiguration logConfig, ILoggingConfiguration loggingConfiguration) - { - //Read from main serilog.config file - logConfig.ReadFrom.AppSettings(filePath: loggingConfiguration.LogConfigurationFile); - - return logConfig; - } - - /// - /// Reads settings from /config/serilog.user.config - /// That allows a separate logging pipeline to be configured that will not affect the main Umbraco log - /// - /// A Serilog LoggerConfiguration - /// - public static LoggerConfiguration ReadFromUserConfigFile(this LoggerConfiguration logConfig, ILoggingConfiguration loggingConfiguration) - { - //A nested logger - where any user configured sinks via config can not effect the main 'umbraco' logger above - logConfig.WriteTo.Logger(cfg => - cfg.ReadFrom.AppSettings(filePath: loggingConfiguration.UserLogConfigurationFile)); - - return logConfig; - } - } } diff --git a/src/Umbraco.Infrastructure/Logging/Serilog/SerilogLogger.cs b/src/Umbraco.Infrastructure/Logging/Serilog/SerilogLogger.cs new file mode 100644 index 0000000000..9e14a6407a --- /dev/null +++ b/src/Umbraco.Infrastructure/Logging/Serilog/SerilogLogger.cs @@ -0,0 +1,221 @@ +using System; +using System.IO; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; +using Serilog; +using Serilog.Events; +using Serilog.Extensions.Logging; +using Umbraco.Core.Hosting; + +namespace Umbraco.Core.Logging.Serilog +{ + + /// + /// Implements on top of Serilog. + /// + public class SerilogLogger : IDisposable + { + public global::Serilog.ILogger SerilogLog { get; } + + /// + /// Initialize a new instance of the class with a configuration file. + /// + /// + public SerilogLogger(FileInfo logConfigFile) + { + SerilogLog = new LoggerConfiguration() + .ReadFrom.AppSettings(filePath: logConfigFile.FullName) + .CreateLogger(); + } + + public SerilogLogger(LoggerConfiguration logConfig) + { + //Configure Serilog static global logger with config passed in + SerilogLog = logConfig.CreateLogger(); + } + + /// + /// Creates a logger with some pre-defined configuration and remainder from config file + /// + /// Used by UmbracoApplicationBase to get its logger. + public static SerilogLogger CreateWithDefaultConfiguration( + IHostingEnvironment hostingEnvironment, + ILoggingConfiguration loggingConfiguration, + IConfiguration configuration) + { + var loggerConfig = new LoggerConfiguration() + .MinimalConfiguration(hostingEnvironment, loggingConfiguration) + .ReadFrom.Configuration(configuration); + + return new SerilogLogger(loggerConfig); + } + + /// + /// Gets a contextualized logger. + /// + private global::Serilog.ILogger LoggerFor(Type reporting) + => SerilogLog.ForContext(reporting); + + /// + /// Maps Umbraco's log level to Serilog's. + /// + private LogEventLevel MapLevel(LogLevel level) + { + switch (level) + { + case LogLevel.Debug: + return LogEventLevel.Debug; + case LogLevel.Error: + return LogEventLevel.Error; + case LogLevel.Fatal: + return LogEventLevel.Fatal; + case LogLevel.Information: + return LogEventLevel.Information; + case LogLevel.Verbose: + return LogEventLevel.Verbose; + case LogLevel.Warning: + return LogEventLevel.Warning; + } + + throw new NotSupportedException($"LogLevel \"{level}\" is not supported."); + } + + /// + public bool IsEnabled(Type reporting, LogLevel level) + => LoggerFor(reporting).IsEnabled(MapLevel(level)); + + /// + public void Fatal(Type reporting, Exception exception, string message) + { + var logger = LoggerFor(reporting); + logger.Fatal(exception, message); + } + + /// + public void Fatal(Type reporting, Exception exception) + { + var logger = LoggerFor(reporting); + var message = "Exception."; + logger.Fatal(exception, message); + } + + /// + public void Fatal(Type reporting, string message) + { + LoggerFor(reporting).Fatal(message); + } + + /// + public void Fatal(Type reporting, string messageTemplate, params object[] propertyValues) + { + LoggerFor(reporting).Fatal(messageTemplate, propertyValues); + } + + /// + public void Fatal(Type reporting, Exception exception, string messageTemplate, params object[] propertyValues) + { + var logger = LoggerFor(reporting); + logger.Fatal(exception, messageTemplate, propertyValues); + } + + /// + public void Error(Type reporting, Exception exception, string message) + { + var logger = LoggerFor(reporting); + logger.Error(exception, message); + } + + /// + public void Error(Type reporting, Exception exception) + { + var logger = LoggerFor(reporting); + var message = "Exception"; + logger.Error(exception, message); + } + + /// + public void Error(Type reporting, string message) + { + LoggerFor(reporting).Error(message); + } + + /// + public void Error(Type reporting, string messageTemplate, params object[] propertyValues) + { + LoggerFor(reporting).Error(messageTemplate, propertyValues); + } + + /// + public void Error(Type reporting, Exception exception, string messageTemplate, params object[] propertyValues) + { + var logger = LoggerFor(reporting); + logger.Error(exception, messageTemplate, propertyValues); + } + + /// + public void Warn(Type reporting, string message) + { + LoggerFor(reporting).Warning(message); + } + + /// + public void Warn(Type reporting, string message, params object[] propertyValues) + { + LoggerFor(reporting).Warning(message, propertyValues); + } + + /// + public void Warn(Type reporting, Exception exception, string message) + { + LoggerFor(reporting).Warning(exception, message); + } + + /// + public void Warn(Type reporting, Exception exception, string messageTemplate, params object[] propertyValues) + { + LoggerFor(reporting).Warning(exception, messageTemplate, propertyValues); + } + + /// + public void Info(Type reporting, string message) + { + LoggerFor(reporting).Information(message); + } + + /// + public void Info(Type reporting, string messageTemplate, params object[] propertyValues) + { + LoggerFor(reporting).Information(messageTemplate, propertyValues); + } + + /// + public void Debug(Type reporting, string message) + { + LoggerFor(reporting).Debug(message); + } + + /// + public void Debug(Type reporting, string messageTemplate, params object[] propertyValues) + { + LoggerFor(reporting).Debug(messageTemplate, propertyValues); + } + + /// + public void Verbose(Type reporting, string message) + { + LoggerFor(reporting).Verbose(message); + } + + /// + public void Verbose(Type reporting, string messageTemplate, params object[] propertyValues) + { + LoggerFor(reporting).Verbose(messageTemplate, propertyValues); + } + + public void Dispose() + { + SerilogLog.DisposeIfDisposable(); + } + + } +} diff --git a/src/Umbraco.Infrastructure/Logging/Viewer/LogViewerComposer.cs b/src/Umbraco.Infrastructure/Logging/Viewer/LogViewerComposer.cs index f28b13ddbf..4a2aa63c69 100644 --- a/src/Umbraco.Infrastructure/Logging/Viewer/LogViewerComposer.cs +++ b/src/Umbraco.Infrastructure/Logging/Viewer/LogViewerComposer.cs @@ -11,16 +11,6 @@ namespace Umbraco.Core.Logging.Viewer { public void Compose(Composition composition) { - - - composition.RegisterUnique(factory => - { - var hostingEnvironment = factory.GetInstance(); - return new LoggingConfiguration( - Path.Combine(hostingEnvironment.ApplicationPhysicalPath, "App_Data", "Logs"), - Path.Combine(hostingEnvironment.ApplicationPhysicalPath, "config", "serilog.config"), - Path.Combine(hostingEnvironment.ApplicationPhysicalPath, "config", "serilog.user.config")); - }); composition.RegisterUnique(); composition.SetLogViewer(); composition.RegisterUnique(factory => diff --git a/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj b/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj index 5c27322a68..10f9a950e8 100644 --- a/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj +++ b/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj @@ -34,6 +34,7 @@ + diff --git a/src/Umbraco.Tests.Common/TestHelperBase.cs b/src/Umbraco.Tests.Common/TestHelperBase.cs index 285a20d064..c5107e9f25 100644 --- a/src/Umbraco.Tests.Common/TestHelperBase.cs +++ b/src/Umbraco.Tests.Common/TestHelperBase.cs @@ -146,9 +146,7 @@ namespace Umbraco.Tests.Common { hostingEnv = hostingEnv ?? GetHostingEnvironment(); return new LoggingConfiguration( - Path.Combine(hostingEnv.ApplicationPhysicalPath, "App_Data","Logs"), - Path.Combine(hostingEnv.ApplicationPhysicalPath, "config","serilog.config"), - Path.Combine(hostingEnv.ApplicationPhysicalPath, "config","serilog.user.config")); + Path.Combine(hostingEnv.ApplicationPhysicalPath, "umbraco","logs")); } } } diff --git a/src/Umbraco.Tests.Integration/RuntimeTests.cs b/src/Umbraco.Tests.Integration/RuntimeTests.cs index 5c52afe746..cc6e43b57d 100644 --- a/src/Umbraco.Tests.Integration/RuntimeTests.cs +++ b/src/Umbraco.Tests.Integration/RuntimeTests.cs @@ -123,7 +123,7 @@ namespace Umbraco.Tests.Integration // Add it! services.AddUmbracoConfiguration(hostContext.Configuration); - services.AddUmbracoCore(webHostEnvironment, umbracoContainer, GetType().Assembly, AppCaches.NoCache, testHelper.GetLoggingConfiguration(), out _); + services.AddUmbracoCore(webHostEnvironment, umbracoContainer, GetType().Assembly, AppCaches.NoCache, testHelper.GetLoggingConfiguration(), hostContext.Configuration,out _); }); var host = await hostBuilder.StartAsync(); @@ -163,7 +163,7 @@ namespace Umbraco.Tests.Integration // Add it! services.AddUmbracoConfiguration(hostContext.Configuration); - services.AddUmbracoCore(webHostEnvironment, umbracoContainer, GetType().Assembly, AppCaches.NoCache, testHelper.GetLoggingConfiguration(), out _); + services.AddUmbracoCore(webHostEnvironment, umbracoContainer, GetType().Assembly, AppCaches.NoCache, testHelper.GetLoggingConfiguration(),hostContext.Configuration, out _); }); var host = await hostBuilder.StartAsync(); diff --git a/src/Umbraco.Tests.Integration/TestServerTest/UmbracoBuilderExtensions.cs b/src/Umbraco.Tests.Integration/TestServerTest/UmbracoBuilderExtensions.cs index 176093cb59..d5cff21f7d 100644 --- a/src/Umbraco.Tests.Integration/TestServerTest/UmbracoBuilderExtensions.cs +++ b/src/Umbraco.Tests.Integration/TestServerTest/UmbracoBuilderExtensions.cs @@ -22,37 +22,38 @@ namespace Umbraco.Tests.Integration.TestServerTest Action dbInstallEventHandler) { return builder.AddWith(nameof(global::Umbraco.Web.Common.Builder.UmbracoBuilderExtensions.WithCore), - () => - { - builder.Services.AddUmbracoCore( - builder.WebHostEnvironment, - container, - typeof(UmbracoBuilderExtensions).Assembly, - AppCaches.NoCache, // Disable caches in integration tests - testHelper.GetLoggingConfiguration(), - (globalSettings, connectionStrings, umbVersion, ioHelper, logger, factory, profiler, hostingEnv, - backOfficeInfo, typeFinder, appCaches, dbProviderFactoryCreator) => - { - var runtime = UmbracoIntegrationTest.CreateTestRuntime( - globalSettings, - connectionStrings, - umbVersion, - ioHelper, - logger, - factory, - profiler, - hostingEnv, - backOfficeInfo, - typeFinder, - appCaches, - dbProviderFactoryCreator, - testHelper.MainDom, // SimpleMainDom - dbInstallEventHandler); // DB Installation event handler + () => + { + builder.Services.AddUmbracoCore( + builder.WebHostEnvironment, + container, + typeof(UmbracoBuilderExtensions).Assembly, + AppCaches.NoCache, // Disable caches in integration tests + testHelper.GetLoggingConfiguration(), + builder.Config, + // TODO: Yep that's extremely ugly + (globalSettings, connectionStrings, umbVersion, ioHelper, logger, factory, profiler, hostingEnv, backOfficeInfo, typeFinder, appCaches, dbProviderFactoryCreator) => + { + var runtime = UmbracoIntegrationTest.CreateTestRuntime( + globalSettings, + connectionStrings, + umbVersion, + ioHelper, + logger, + factory, + profiler, + hostingEnv, + backOfficeInfo, + typeFinder, + appCaches, + dbProviderFactoryCreator, + testHelper.MainDom, // SimpleMainDom + dbInstallEventHandler); // DB Installation event handler - return runtime; - }, - out _); - }); + return runtime; + }, + out _); + }); } } } diff --git a/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs b/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs index c65236387f..08fca1c141 100644 --- a/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs +++ b/src/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs @@ -236,6 +236,7 @@ namespace Umbraco.Tests.Integration.Testing GetType().Assembly, AppCaches.NoCache, // Disable caches for integration tests TestHelper.GetLoggingConfiguration(), + Configuration, CreateTestRuntime, out _); diff --git a/src/Umbraco.Web.Common/Builder/UmbracoBuilderExtensions.cs b/src/Umbraco.Web.Common/Builder/UmbracoBuilderExtensions.cs index 08b7670522..5b4876baca 100644 --- a/src/Umbraco.Web.Common/Builder/UmbracoBuilderExtensions.cs +++ b/src/Umbraco.Web.Common/Builder/UmbracoBuilderExtensions.cs @@ -26,7 +26,7 @@ namespace Umbraco.Web.Common.Builder => builder.AddWith(nameof(WithConfiguration), () => builder.Services.AddUmbracoConfiguration(builder.Config)); public static IUmbracoBuilder WithCore(this IUmbracoBuilder builder) - => builder.AddWith(nameof(WithCore), () => builder.Services.AddUmbracoCore(builder.WebHostEnvironment, out _)); + => builder.AddWith(nameof(WithCore), () => builder.Services.AddUmbracoCore(builder.WebHostEnvironment, builder.Config, out _)); public static IUmbracoBuilder WithMiniProfiler(this IUmbracoBuilder builder) => builder.AddWith(nameof(WithMiniProfiler), () => diff --git a/src/Umbraco.Web.Common/Extensions/UmbracoCoreServiceCollectionExtensions.cs b/src/Umbraco.Web.Common/Extensions/UmbracoCoreServiceCollectionExtensions.cs index 8b756e2f3a..4ab19d2751 100644 --- a/src/Umbraco.Web.Common/Extensions/UmbracoCoreServiceCollectionExtensions.cs +++ b/src/Umbraco.Web.Common/Extensions/UmbracoCoreServiceCollectionExtensions.cs @@ -103,19 +103,20 @@ namespace Umbraco.Extensions /// /// /// - /// /// /// + /// + /// /// - public static IServiceCollection AddUmbracoCore( - this IServiceCollection services, + public static IServiceCollection AddUmbracoCore(this IServiceCollection services, IWebHostEnvironment webHostEnvironment, IRegister umbContainer, Assembly entryAssembly, AppCaches appCaches, ILoggingConfiguration loggingConfiguration, + IConfiguration configuration, out IFactory factory) - => services.AddUmbracoCore(webHostEnvironment, umbContainer, entryAssembly, appCaches, loggingConfiguration, GetCoreRuntime, out factory); + => services.AddUmbracoCore(webHostEnvironment, umbContainer, entryAssembly, appCaches, loggingConfiguration, configuration, GetCoreRuntime, out factory); /// /// Adds the Umbraco Configuration requirements @@ -159,10 +160,11 @@ namespace Umbraco.Extensions /// /// /// + /// /// - public static IServiceCollection AddUmbracoCore(this IServiceCollection services, IWebHostEnvironment webHostEnvironment) + public static IServiceCollection AddUmbracoCore(this IServiceCollection services, IWebHostEnvironment webHostEnvironment, IConfiguration configuration) { - return services.AddUmbracoCore(webHostEnvironment, out _); + return services.AddUmbracoCore(webHostEnvironment, configuration, out _); } /// @@ -170,9 +172,10 @@ namespace Umbraco.Extensions /// /// /// + /// /// /// - public static IServiceCollection AddUmbracoCore(this IServiceCollection services, IWebHostEnvironment webHostEnvironment, out IFactory factory) + public static IServiceCollection AddUmbracoCore(this IServiceCollection services, IWebHostEnvironment webHostEnvironment, IConfiguration configuration, out IFactory factory) { if (!UmbracoServiceProviderFactory.IsActive) throw new InvalidOperationException("Ensure to add UseUmbraco() in your Program.cs after ConfigureWebHostDefaults to enable Umbraco's service provider factory"); @@ -180,12 +183,11 @@ namespace Umbraco.Extensions var umbContainer = UmbracoServiceProviderFactory.UmbracoContainer; var loggingConfig = new LoggingConfiguration( - Path.Combine(webHostEnvironment.ContentRootPath, "App_Data", "Logs"), - Path.Combine(webHostEnvironment.ContentRootPath, "config", "serilog.config"), - Path.Combine(webHostEnvironment.ContentRootPath, "config", "serilog.user.config")); + Path.Combine(webHostEnvironment.ContentRootPath, "umbraco", "logs")); IHttpContextAccessor httpContextAccessor = new HttpContextAccessor(); services.AddSingleton(httpContextAccessor); + services.AddSingleton(loggingConfig); var requestCache = new GenericDictionaryRequestAppCache(() => httpContextAccessor.HttpContext?.Items); var appCaches = new AppCaches( @@ -198,6 +200,7 @@ namespace Umbraco.Extensions Assembly.GetEntryAssembly(), appCaches, loggingConfig, + configuration, GetCoreRuntime, out factory); @@ -224,6 +227,7 @@ namespace Umbraco.Extensions Assembly entryAssembly, AppCaches appCaches, ILoggingConfiguration loggingConfiguration, + IConfiguration configuration, //TODO: Yep that's extremely ugly Func getRuntime, out IFactory factory) @@ -267,6 +271,7 @@ namespace Umbraco.Extensions hostingSettings, webHostEnvironment, loggingConfiguration, + configuration, out var logger, out var ioHelper, out var hostingEnvironment, out var backOfficeInfo, out var profiler); var umbracoVersion = new UmbracoVersion(); @@ -288,6 +293,13 @@ namespace Umbraco.Extensions factory = coreRuntime.Configure(container); + + services.Configure(hostingSettings => + { + hostingSettings.Debug = false; + }); + + return services; } @@ -339,6 +351,7 @@ namespace Umbraco.Extensions IOptionsMonitor hostingSettings, IWebHostEnvironment webHostEnvironment, ILoggingConfiguration loggingConfiguration, + IConfiguration configuration, out ILogger logger, out IIOHelper ioHelper, out Core.Hosting.IHostingEnvironment hostingEnvironment, @@ -350,8 +363,7 @@ namespace Umbraco.Extensions hostingEnvironment = new AspNetCoreHostingEnvironment(hostingSettings, webHostEnvironment); ioHelper = new IOHelper(hostingEnvironment); - logger = AddLogger(services, hostingEnvironment, loggingConfiguration); - + logger = AddLogger(services, hostingEnvironment, loggingConfiguration, configuration); backOfficeInfo = new AspNetCoreBackOfficeInfo(globalSettings); profiler = GetWebProfiler(hostingEnvironment); @@ -362,24 +374,29 @@ namespace Umbraco.Extensions /// Create and configure the logger /// /// - private static ILogger AddLogger(IServiceCollection services, Core.Hosting.IHostingEnvironment hostingEnvironment, ILoggingConfiguration loggingConfiguration) + private static ILogger AddLogger(IServiceCollection services, Core.Hosting.IHostingEnvironment hostingEnvironment, ILoggingConfiguration loggingConfiguration, IConfiguration configuration) { - // // Create a serilog logger - // var logger = SerilogLogger.CreateWithDefaultConfiguration(hostingEnvironment, loggingConfiguration); - // - // // Wire up all the bits that serilog needs. We need to use our own code since the Serilog ext methods don't cater to our needs since - // // we don't want to use the global serilog `Log` object and we don't have our own ILogger implementation before the HostBuilder runs which - // // is the only other option that these ext methods allow. - // // I have created a PR to make this nicer https://github.com/serilog/serilog-extensions-hosting/pull/19 but we'll need to wait for that. - // // Also see : https://github.com/serilog/serilog-extensions-hosting/blob/dev/src/Serilog.Extensions.Hosting/SerilogHostBuilderExtensions.cs - // - // services.AddSingleton(services => new SerilogLoggerFactory(logger.SerilogLog, false)); + // Create a serilog logger + var logger = SerilogLogger.CreateWithDefaultConfiguration(hostingEnvironment, loggingConfiguration, configuration); - var factory = LoggerFactory.Create(builder => + // This is nessasary to pick up all the loggins to MS ILogger. + Log.Logger = logger.SerilogLog; + + + // Wire up all the bits that serilog needs. We need to use our own code since the Serilog ext methods don't cater to our needs since + // we don't want to use the global serilog `Log` object and we don't have our own ILogger implementation before the HostBuilder runs which + // is the only other option that these ext methods allow. + // I have created a PR to make this nicer https://github.com/serilog/serilog-extensions-hosting/pull/19 but we'll need to wait for that. + // Also see : https://github.com/serilog/serilog-extensions-hosting/blob/dev/src/Serilog.Extensions.Hosting/SerilogHostBuilderExtensions.cs + + services.AddLogging(configure => { - builder.AddSerilog(); + configure.AddSerilog(logger.SerilogLog, false); }); + + //services.AddSingleton(services => new SerilogLoggerFactory(logger.SerilogLog, false)); + // // This won't (and shouldn't) take ownership of the logger. // services.AddSingleton(logger.SerilogLog); // @@ -391,8 +408,8 @@ namespace Umbraco.Extensions // // // Consumed by user code // services.AddSingleton(diagnosticContext); - - return factory.CreateLogger("FakeSiriLogger"); + var serviceProvider = services.BuildServiceProvider(); + return serviceProvider.GetRequiredService().CreateLogger("Generic Logger"); } private static IProfiler GetWebProfiler(Umbraco.Core.Hosting.IHostingEnvironment hostingEnvironment) diff --git a/src/Umbraco.Web.UI.NetCore/Program.cs b/src/Umbraco.Web.UI.NetCore/Program.cs index 30aced6469..4a7722597d 100644 --- a/src/Umbraco.Web.UI.NetCore/Program.cs +++ b/src/Umbraco.Web.UI.NetCore/Program.cs @@ -1,5 +1,6 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; using Umbraco.Core.Composing; namespace Umbraco.Web.UI.NetCore @@ -15,6 +16,10 @@ namespace Umbraco.Web.UI.NetCore public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) + .ConfigureLogging(x => + { + x.ClearProviders(); + }) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup(); }) .UseUmbraco(); } diff --git a/src/Umbraco.Web.UI.NetCore/Umbraco.Web.UI.NetCore.csproj b/src/Umbraco.Web.UI.NetCore/Umbraco.Web.UI.NetCore.csproj index 39937d1f3a..2c4dba2b3c 100644 --- a/src/Umbraco.Web.UI.NetCore/Umbraco.Web.UI.NetCore.csproj +++ b/src/Umbraco.Web.UI.NetCore/Umbraco.Web.UI.NetCore.csproj @@ -59,11 +59,11 @@ - - - + + + - + diff --git a/src/Umbraco.Web.UI.NetCore/Views/asda.cshtml b/src/Umbraco.Web.UI.NetCore/Views/asda.cshtml deleted file mode 100644 index 3fa17ab54c..0000000000 --- a/src/Umbraco.Web.UI.NetCore/Views/asda.cshtml +++ /dev/null @@ -1,4 +0,0 @@ -@inherits Umbraco.Web.Common.AspNetCore.UmbracoViewPage -@{ - Layout = null; -} \ No newline at end of file diff --git a/src/Umbraco.Web.UI.NetCore/appsettings.Development.json b/src/Umbraco.Web.UI.NetCore/appsettings.Development.json index 13f4c95bbd..e9174b55dd 100644 --- a/src/Umbraco.Web.UI.NetCore/appsettings.Development.json +++ b/src/Umbraco.Web.UI.NetCore/appsettings.Development.json @@ -1,4 +1,21 @@ { + "Serilog": { + "MinimumLevel": { + "Default": "Information" + }, + "WriteTo":[ + { + "Name": "Async", + "Args": { + "configure": [ + { + "Name": "Console" + } + ] + } + } + ] + }, "Umbraco": { "CMS": { "Global":{ diff --git a/src/Umbraco.Web.UI.NetCore/appsettings.json b/src/Umbraco.Web.UI.NetCore/appsettings.json index 1eb761e1ad..d962e4325a 100644 --- a/src/Umbraco.Web.UI.NetCore/appsettings.json +++ b/src/Umbraco.Web.UI.NetCore/appsettings.json @@ -2,6 +2,16 @@ "ConnectionStrings": { "umbracoDbDSN": "" }, + "Serilog": { + "MinimumLevel": { + "Default": "Information", + "Override": { + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information", + "System": "Warning" + } + } + }, "Umbraco": { "CMS": { "Content": { diff --git a/src/Umbraco.Web.UI.NetCore/config/serilog.Release.config b/src/Umbraco.Web.UI.NetCore/config/serilog.Release.config deleted file mode 100644 index 9aca408b36..0000000000 --- a/src/Umbraco.Web.UI.NetCore/config/serilog.Release.config +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Umbraco.Web.UI.NetCore/config/serilog.config b/src/Umbraco.Web.UI.NetCore/config/serilog.config deleted file mode 100644 index 1b357696b9..0000000000 --- a/src/Umbraco.Web.UI.NetCore/config/serilog.config +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Umbraco.Web.UI.NetCore/config/serilog.user.Release.config b/src/Umbraco.Web.UI.NetCore/config/serilog.user.Release.config deleted file mode 100644 index 8f207406e3..0000000000 --- a/src/Umbraco.Web.UI.NetCore/config/serilog.user.Release.config +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Umbraco.Web.UI.NetCore/config/serilog.user.config b/src/Umbraco.Web.UI.NetCore/config/serilog.user.config deleted file mode 100644 index 8f207406e3..0000000000 --- a/src/Umbraco.Web.UI.NetCore/config/serilog.user.config +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Umbraco.Web/UmbracoApplicationBase.cs b/src/Umbraco.Web/UmbracoApplicationBase.cs index a58a5b0987..50480f00ce 100644 --- a/src/Umbraco.Web/UmbracoApplicationBase.cs +++ b/src/Umbraco.Web/UmbracoApplicationBase.cs @@ -1,10 +1,13 @@ using System; +using System.Collections.Generic; using System.IO; using System.Reflection; using System.Threading; using System.Web; using System.Web.Hosting; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; using Serilog; using Serilog.Context; @@ -51,34 +54,18 @@ namespace Umbraco.Web var hostingEnvironment = new AspNetHostingEnvironment(Options.Create(hostingSettings)); var loggingConfiguration = new LoggingConfiguration( - Path.Combine(hostingEnvironment.ApplicationPhysicalPath, "App_Data\\Logs"), - Path.Combine(hostingEnvironment.ApplicationPhysicalPath, "config\\serilog.config"), - Path.Combine(hostingEnvironment.ApplicationPhysicalPath, "config\\serilog.user.config")); + Path.Combine(hostingEnvironment.ApplicationPhysicalPath, "App_Data\\Logs")); var ioHelper = new IOHelper(hostingEnvironment); - - // TODO: Configure Serilog somewhere else - var loggerConfig = new LoggerConfiguration(); - loggerConfig - .MinimalConfiguration(hostingEnvironment, loggingConfiguration) - .ReadFromConfigFile(loggingConfiguration) - .ReadFromUserConfigFile(loggingConfiguration); - Log.Logger = loggerConfig.CreateLogger(); - - _loggerFactory = LoggerFactory.Create(builder => - { - builder.AddSerilog(); - }); - - var logger = _loggerFactory.CreateLogger(); + var logger = SerilogLogger.CreateWithDefaultConfiguration(hostingEnvironment, loggingConfiguration, new ConfigurationRoot(new List())); var backOfficeInfo = new AspNetBackOfficeInfo(globalSettings, ioHelper, _loggerFactory.CreateLogger(), Options.Create(webRoutingSettings)); var profiler = GetWebProfiler(hostingEnvironment); - Umbraco.Composing.Current.Initialize(logger, + Umbraco.Composing.Current.Initialize(NullLogger.Instance, _loggerFactory, securitySettings, globalSettings, ioHelper, hostingEnvironment, backOfficeInfo, profiler); - Logger = logger; + Logger = NullLogger.Instance; } }