/// <summary> /// This configures Serilog with some defaults /// Such as adding ProcessID, Thread, AppDomain etc /// It is highly recommended that you keep/use this default in your own logging config customizations /// </summary> public static LoggerConfiguration MinimalConfiguration( this LoggerConfiguration logConfig, IHostEnvironment hostEnvironment, ILoggingConfiguration loggingConfiguration, UmbracoFileConfiguration umbracoFileConfiguration) { global::Serilog.Debugging.SelfLog.Enable(msg => System.Diagnostics.Debug.WriteLine(msg)); //Set this environment variable - so that it can be used in external config file //add key="serilog:write-to:RollingFile.pathFormat" value="%BASEDIR%\logs\log.txt" /> Environment.SetEnvironmentVariable("BASEDIR", hostEnvironment.MapPathContentRoot("/").TrimEnd("\\"), EnvironmentVariableTarget.Process); Environment.SetEnvironmentVariable("UMBLOGDIR", loggingConfiguration.LogDirectory, EnvironmentVariableTarget.Process); Environment.SetEnvironmentVariable("MACHINENAME", Environment.MachineName, EnvironmentVariableTarget.Process); logConfig.MinimumLevel.Verbose() //Set to highest level of logging (as any sinks may want to restrict it to Errors only) .Enrich.WithProcessId() .Enrich.WithProcessName() .Enrich.WithThreadId() .Enrich.WithProperty("ApplicationId", hostEnvironment.GetTemporaryApplicationId()) // Updated later by ApplicationIdEnricher .Enrich.WithProperty("MachineName", Environment.MachineName) .Enrich.With <Log4NetLevelMapperEnricher>() .Enrich.FromLogContext(); // allows us to dynamically enrich logConfig.WriteTo.UmbracoFile( path: umbracoFileConfiguration.GetPath(loggingConfiguration.LogDirectory), fileSizeLimitBytes: umbracoFileConfiguration.FileSizeLimitBytes, restrictedToMinimumLevel: umbracoFileConfiguration.RestrictedToMinimumLevel, rollingInterval: umbracoFileConfiguration.RollingInterval, flushToDiskInterval: umbracoFileConfiguration.FlushToDiskInterval, rollOnFileSizeLimit: umbracoFileConfiguration.RollOnFileSizeLimit, retainedFileCountLimit: umbracoFileConfiguration.RetainedFileCountLimit ); return(logConfig); }
/// <summary> /// Creates a logger with some pre-defined configuration and remainder from config file /// </summary> /// <remarks>Used by UmbracoApplicationBase to get its logger.</remarks> public static SerilogLogger CreateWithDefaultConfiguration( IHostingEnvironment hostingEnvironment, ILoggingConfiguration loggingConfiguration, IConfiguration configuration, out UmbracoFileConfiguration umbracoFileConfig) { var serilogConfig = new LoggerConfiguration() .MinimalConfiguration(hostingEnvironment, loggingConfiguration, configuration, out umbracoFileConfig) .ReadFrom.Configuration(configuration); return(new SerilogLogger(serilogConfig)); }
/// <summary> /// This configures Serilog with some defaults /// Such as adding ProcessID, Thread, AppDomain etc /// It is highly recommended that you keep/use this default in your own logging config customizations /// </summary> /// <param name="logConfig">A Serilog LoggerConfiguration</param> /// <param name="hostingEnvironment"></param> /// <param name="loggingConfiguration"></param> public static LoggerConfiguration MinimalConfiguration( this LoggerConfiguration logConfig, IHostingEnvironment hostingEnvironment, ILoggingConfiguration loggingConfiguration, IConfiguration configuration, out UmbracoFileConfiguration umbFileConfiguration) { global::Serilog.Debugging.SelfLog.Enable(msg => System.Diagnostics.Debug.WriteLine(msg)); //Set this environment variable - so that it can be used in external config file //add key="serilog:write-to:RollingFile.pathFormat" value="%BASEDIR%\logs\log.txt" /> Environment.SetEnvironmentVariable("BASEDIR", hostingEnvironment.MapPathContentRoot("/").TrimEnd("\\"), EnvironmentVariableTarget.Process); Environment.SetEnvironmentVariable("UMBLOGDIR", loggingConfiguration.LogDirectory, EnvironmentVariableTarget.Process); Environment.SetEnvironmentVariable("MACHINENAME", Environment.MachineName, EnvironmentVariableTarget.Process); logConfig.MinimumLevel.Verbose() //Set to highest level of logging (as any sinks may want to restrict it to Errors only) .Enrich.WithProcessId() .Enrich.WithProcessName() .Enrich.WithThreadId() .Enrich.WithProperty(AppDomainId, AppDomain.CurrentDomain.Id) .Enrich.WithProperty("AppDomainAppId", hostingEnvironment.ApplicationId.ReplaceNonAlphanumericChars(string.Empty)) .Enrich.WithProperty("MachineName", Environment.MachineName) .Enrich.With <Log4NetLevelMapperEnricher>() .Enrich.FromLogContext(); // allows us to dynamically enrich //This is not optimal, but seems to be the only way if we do not make an Serilog.Sink.UmbracoFile sink all the way. var umbracoFileConfiguration = new UmbracoFileConfiguration(configuration); umbFileConfiguration = umbracoFileConfiguration; logConfig.WriteTo.UmbracoFile( path: umbracoFileConfiguration.GetPath(loggingConfiguration.LogDirectory), fileSizeLimitBytes: umbracoFileConfiguration.FileSizeLimitBytes, restrictedToMinimumLevel: umbracoFileConfiguration.RestrictedToMinimumLevel, rollingInterval: umbracoFileConfiguration.RollingInterval, flushToDiskInterval: umbracoFileConfiguration.FlushToDiskInterval, rollOnFileSizeLimit: umbracoFileConfiguration.RollOnFileSizeLimit, retainedFileCountLimit: umbracoFileConfiguration.RetainedFileCountLimit ); return(logConfig); }
public LogLevelLoader(UmbracoFileConfiguration umbracoFileConfig) => _umbracoFileConfig = umbracoFileConfig;
/// <summary> /// Create and configure the logger. /// </summary> /// <remarks> /// Additional Serilog services are registered during <see cref="HostBuilderExtensions.ConfigureUmbracoDefaults" />. /// </remarks> public static IServiceCollection AddLogger( this IServiceCollection services, 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); ILoggingConfiguration loggingConfig = new LoggingConfiguration(loggingDir); var umbracoFileConfiguration = new UmbracoFileConfiguration(configuration); services.TryAddSingleton(umbracoFileConfiguration); services.TryAddSingleton(loggingConfig); services.TryAddSingleton <ILogEventEnricher, ApplicationIdEnricher>(); /////////////////////////////////////////////// // Bootstrap logger setup /////////////////////////////////////////////// LoggerConfiguration serilogConfig = new LoggerConfiguration() .MinimalConfiguration(hostEnvironment, loggingConfig, umbracoFileConfiguration) .ReadFrom.Configuration(configuration); Log.Logger = serilogConfig.CreateBootstrapLogger(); /////////////////////////////////////////////// // Runtime logger setup /////////////////////////////////////////////// services.AddSingleton(sp => { var logger = new RegisteredReloadableLogger(Log.Logger as ReloadableLogger); logger.Reload(cfg => { cfg.MinimalConfiguration(hostEnvironment, loggingConfig, umbracoFileConfiguration) .ReadFrom.Configuration(configuration) .ReadFrom.Services(sp); return(cfg); }); return(logger); }); services.AddSingleton <ILogger>(sp => { ILogger logger = sp.GetRequiredService <RegisteredReloadableLogger>().Logger; return(logger.ForContext(new NoopEnricher())); }); services.AddSingleton <ILoggerFactory>(sp => { ILogger logger = sp.GetRequiredService <RegisteredReloadableLogger>().Logger; return(new SerilogLoggerFactory(logger)); }); // Registered to provide two services... var diagnosticContext = new DiagnosticContext(Log.Logger); // Consumed by e.g. middleware services.TryAddSingleton(diagnosticContext); // Consumed by user code services.TryAddSingleton <IDiagnosticContext>(diagnosticContext); return(services); }