15
15
using System ;
16
16
using Microsoft . AspNetCore . Hosting ;
17
17
using Microsoft . Extensions . Logging ;
18
- using Serilog . AspNetCore ;
18
+ using Serilog . Extensions . Logging ;
19
19
using Microsoft . Extensions . DependencyInjection ;
20
20
21
21
namespace Serilog
@@ -33,12 +33,38 @@ public static class SerilogWebHostBuilderExtensions
33
33
/// <param name="dispose">When true, dispose <paramref name="logger"/> when the framework disposes the provider. If the
34
34
/// logger is not specified but <paramref name="dispose"/> is true, the <see cref="Log.CloseAndFlush()"/> method will be
35
35
/// called on the static <see cref="Log"/> class instead.</param>
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>
36
39
/// <returns>The web host builder.</returns>
37
- public static IWebHostBuilder UseSerilog ( this IWebHostBuilder builder , Serilog . ILogger logger = null , bool dispose = false )
40
+ public static IWebHostBuilder UseSerilog (
41
+ this IWebHostBuilder builder ,
42
+ ILogger logger = null ,
43
+ bool dispose = false ,
44
+ LoggerProviderCollection providers = null )
38
45
{
39
46
if ( builder == null ) throw new ArgumentNullException ( nameof ( builder ) ) ;
47
+
40
48
builder . ConfigureServices ( collection =>
41
- collection . AddSingleton < ILoggerFactory > ( services => new SerilogLoggerFactory ( logger , dispose ) ) ) ;
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
+
42
68
return builder ;
43
69
}
44
70
@@ -50,27 +76,56 @@ public static IWebHostBuilder UseSerilog(this IWebHostBuilder builder, Serilog.I
50
76
/// <param name="builder">The web host builder to configure.</param>
51
77
/// <param name="configureLogger">The delegate for configuring the <see cref="LoggerConfiguration" /> that will be used to construct a <see cref="Logger" />.</param>
52
78
/// <param name="preserveStaticLogger">Indicates whether to preserve the value of <see cref="Log.Logger"/>.</param>
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>
53
82
/// <returns>The web host builder.</returns>
54
- public static IWebHostBuilder UseSerilog ( this IWebHostBuilder builder , Action < WebHostBuilderContext , LoggerConfiguration > configureLogger , bool preserveStaticLogger = false )
83
+ public static IWebHostBuilder UseSerilog (
84
+ this IWebHostBuilder builder ,
85
+ Action < WebHostBuilderContext , LoggerConfiguration > configureLogger ,
86
+ bool preserveStaticLogger = false ,
87
+ bool writeToProviders = false )
55
88
{
56
89
if ( builder == null ) throw new ArgumentNullException ( nameof ( builder ) ) ;
57
90
if ( configureLogger == null ) throw new ArgumentNullException ( nameof ( configureLogger ) ) ;
58
91
builder . ConfigureServices ( ( context , collection ) =>
59
92
{
60
93
var loggerConfiguration = new LoggerConfiguration ( ) ;
94
+
95
+ LoggerProviderCollection loggerProviders = null ;
96
+ if ( writeToProviders )
97
+ {
98
+ loggerProviders = new LoggerProviderCollection ( ) ;
99
+ loggerConfiguration . WriteTo . Providers ( loggerProviders ) ;
100
+ }
101
+
61
102
configureLogger ( context , loggerConfiguration ) ;
62
103
var logger = loggerConfiguration . CreateLogger ( ) ;
104
+
105
+ ILogger registeredLogger = null ;
63
106
if ( preserveStaticLogger )
64
- {
65
- collection . AddSingleton < ILoggerFactory > ( services => new SerilogLoggerFactory ( logger , true ) ) ;
66
- }
67
- else
68
107
{
69
108
// Passing a `null` logger to `SerilogLoggerFactory` results in disposal via
70
109
// `Log.CloseAndFlush()`, which additionally replaces the static logger with a no-op.
71
110
Log . Logger = logger ;
72
- collection . AddSingleton < ILoggerFactory > ( services => new SerilogLoggerFactory ( null , true ) ) ;
73
111
}
112
+ else
113
+ {
114
+ registeredLogger = logger ;
115
+ }
116
+
117
+ collection . AddSingleton < ILoggerFactory > ( services =>
118
+ {
119
+ var factory = new SerilogLoggerFactory ( registeredLogger , true , loggerProviders ) ;
120
+
121
+ if ( writeToProviders )
122
+ {
123
+ foreach ( var provider in services . GetServices < ILoggerProvider > ( ) )
124
+ factory . AddProvider ( provider ) ;
125
+ }
126
+
127
+ return factory ;
128
+ } ) ;
74
129
} ) ;
75
130
return builder ;
76
131
}
0 commit comments