1- // Copyright 2018 Serilog Contributors
1+ // Copyright 2019 Serilog Contributors
22//
33// Licensed under the Apache License, Version 2.0 (the "License");
44// you may not use this file except in compliance with the License.
1515using System ;
1616using Microsoft . Extensions . Hosting ;
1717using Microsoft . Extensions . Logging ;
18- using Serilog . Hosting ;
1918using Microsoft . Extensions . DependencyInjection ;
19+ using Serilog . Extensions . Logging ;
2020
2121namespace Serilog
2222{
@@ -30,49 +30,103 @@ public static class SerilogHostBuilderExtensions
3030 /// </summary>
3131 /// <param name="builder">The host builder to configure.</param>
3232 /// <param name="logger">The Serilog logger; if not supplied, the static <see cref="Serilog.Log"/> will be used.</param>
33- /// <param name="dispose">When <c> true</c> , dispose <paramref name="logger"/> when the framework disposes the provider. If the
34- /// logger is not specified but <paramref name="dispose"/> is <c> true</c> , the <see cref="Log.CloseAndFlush()"/> method will be
33+ /// <param name="dispose">When true, dispose <paramref name="logger"/> when the framework disposes the provider. If the
34+ /// logger is not specified but <paramref name="dispose"/> is true, the <see cref="Log.CloseAndFlush()"/> method will be
3535 /// called on the static <see cref="Log"/> class instead.</param>
36- /// <returns>The (generic) host builder.</returns>
37- public static IHostBuilder UseSerilog ( this IHostBuilder builder , Serilog . ILogger logger = null , bool dispose = false )
36+ /// <param name="providers">A <see cref="LoggerProviderCollection"/> registered in the Serilog pipeline using the
37+ /// <c>WriteTo.Providers()</c> configuration method, enabling other <see cref="ILoggerProvider"/>s to receive events. By
38+ /// default, only Serilog sinks will receive events.</param>
39+ /// <returns>The host builder.</returns>
40+ public static IHostBuilder UseSerilog (
41+ this IHostBuilder builder ,
42+ ILogger logger = null ,
43+ bool dispose = false ,
44+ LoggerProviderCollection providers = null )
3845 {
3946 if ( builder == null ) throw new ArgumentNullException ( nameof ( builder ) ) ;
40- builder . ConfigureServices ( ( context , collection ) =>
41- collection . AddSingleton < ILoggerFactory > ( services => new SerilogLoggerFactory ( logger , dispose ) ) ) ;
47+
48+ builder . ConfigureServices ( ( _ , collection ) =>
49+ {
50+ if ( providers != null )
51+ {
52+ collection . AddSingleton < ILoggerFactory > ( services =>
53+ {
54+ var factory = new SerilogLoggerFactory ( logger , dispose , providers ) ;
55+
56+ foreach ( var provider in services . GetServices < ILoggerProvider > ( ) )
57+ factory . AddProvider ( provider ) ;
58+
59+ return factory ;
60+ } ) ;
61+ }
62+ else
63+ {
64+ collection . AddSingleton < ILoggerFactory > ( services => new SerilogLoggerFactory ( logger , dispose ) ) ;
65+ }
66+ } ) ;
67+
4268 return builder ;
4369 }
4470
45- /// <summary>
46- /// Sets Serilog as the logging provider.
47- /// </summary>
71+ /// <summary>Sets Serilog as the logging provider.</summary>
4872 /// <remarks>
4973 /// A <see cref="HostBuilderContext"/> is supplied so that configuration and hosting information can be used.
5074 /// The logger will be shut down when application services are disposed.
5175 /// </remarks>
5276 /// <param name="builder">The host builder to configure.</param>
5377 /// <param name="configureLogger">The delegate for configuring the <see cref="LoggerConfiguration" /> that will be used to construct a <see cref="Logger" />.</param>
5478 /// <param name="preserveStaticLogger">Indicates whether to preserve the value of <see cref="Log.Logger"/>.</param>
55- /// <returns>The (generic) host builder.</returns>
56- public static IHostBuilder UseSerilog ( this IHostBuilder builder , Action < HostBuilderContext , LoggerConfiguration > configureLogger , bool preserveStaticLogger = false )
79+ /// <param name="writeToProviders">By default, Serilog does not write events to <see cref="ILoggerProvider"/>s registered through
80+ /// the Microsoft.Extensions.Logging API. Normally, equivalent Serilog sinks are used in place of providers. Specify
81+ /// <c>true</c> to write events to all providers.</param>
82+ /// <returns>The host builder.</returns>
83+ public static IHostBuilder UseSerilog (
84+ this IHostBuilder builder ,
85+ Action < HostBuilderContext , LoggerConfiguration > configureLogger ,
86+ bool preserveStaticLogger = false ,
87+ bool writeToProviders = false )
5788 {
5889 if ( builder == null ) throw new ArgumentNullException ( nameof ( builder ) ) ;
5990 if ( configureLogger == null ) throw new ArgumentNullException ( nameof ( configureLogger ) ) ;
91+
6092 builder . ConfigureServices ( ( context , collection ) =>
6193 {
6294 var loggerConfiguration = new LoggerConfiguration ( ) ;
95+
96+ LoggerProviderCollection loggerProviders = null ;
97+ if ( writeToProviders )
98+ {
99+ loggerProviders = new LoggerProviderCollection ( ) ;
100+ loggerConfiguration . WriteTo . Providers ( loggerProviders ) ;
101+ }
102+
63103 configureLogger ( context , loggerConfiguration ) ;
64104 var logger = loggerConfiguration . CreateLogger ( ) ;
105+
106+ ILogger registeredLogger = null ;
65107 if ( preserveStaticLogger )
66108 {
67- collection . AddSingleton < ILoggerFactory > ( services => new SerilogLoggerFactory ( logger , true ) ) ;
109+ registeredLogger = logger ;
68110 }
69- else
111+ else
70112 {
71113 // Passing a `null` logger to `SerilogLoggerFactory` results in disposal via
72114 // `Log.CloseAndFlush()`, which additionally replaces the static logger with a no-op.
73115 Log . Logger = logger ;
74- collection . AddSingleton < ILoggerFactory > ( services => new SerilogLoggerFactory ( null , true ) ) ;
75116 }
117+
118+ collection . AddSingleton < ILoggerFactory > ( services =>
119+ {
120+ var factory = new SerilogLoggerFactory ( registeredLogger , true , loggerProviders ) ;
121+
122+ if ( writeToProviders )
123+ {
124+ foreach ( var provider in services . GetServices < ILoggerProvider > ( ) )
125+ factory . AddProvider ( provider ) ;
126+ }
127+
128+ return factory ;
129+ } ) ;
76130 } ) ;
77131 return builder ;
78132 }
0 commit comments