1
- // Copyright 2018 Serilog Contributors
1
+ // Copyright 2019 Serilog Contributors
2
2
//
3
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
4
// you may not use this file except in compliance with the License.
15
15
using System ;
16
16
using Microsoft . Extensions . Hosting ;
17
17
using Microsoft . Extensions . Logging ;
18
- using Serilog . Hosting ;
19
18
using Microsoft . Extensions . DependencyInjection ;
19
+ using Serilog . Extensions . Logging ;
20
20
21
21
namespace Serilog
22
22
{
@@ -30,49 +30,103 @@ public static class SerilogHostBuilderExtensions
30
30
/// </summary>
31
31
/// <param name="builder">The host builder to configure.</param>
32
32
/// <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
35
35
/// 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 )
38
45
{
39
46
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
+
42
68
return builder ;
43
69
}
44
70
45
- /// <summary>
46
- /// Sets Serilog as the logging provider.
47
- /// </summary>
71
+ /// <summary>Sets Serilog as the logging provider.</summary>
48
72
/// <remarks>
49
73
/// A <see cref="HostBuilderContext"/> is supplied so that configuration and hosting information can be used.
50
74
/// The logger will be shut down when application services are disposed.
51
75
/// </remarks>
52
76
/// <param name="builder">The host builder to configure.</param>
53
77
/// <param name="configureLogger">The delegate for configuring the <see cref="LoggerConfiguration" /> that will be used to construct a <see cref="Logger" />.</param>
54
78
/// <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 )
57
88
{
58
89
if ( builder == null ) throw new ArgumentNullException ( nameof ( builder ) ) ;
59
90
if ( configureLogger == null ) throw new ArgumentNullException ( nameof ( configureLogger ) ) ;
91
+
60
92
builder . ConfigureServices ( ( context , collection ) =>
61
93
{
62
94
var loggerConfiguration = new LoggerConfiguration ( ) ;
95
+
96
+ LoggerProviderCollection loggerProviders = null ;
97
+ if ( writeToProviders )
98
+ {
99
+ loggerProviders = new LoggerProviderCollection ( ) ;
100
+ loggerConfiguration . WriteTo . Providers ( loggerProviders ) ;
101
+ }
102
+
63
103
configureLogger ( context , loggerConfiguration ) ;
64
104
var logger = loggerConfiguration . CreateLogger ( ) ;
105
+
106
+ ILogger registeredLogger = null ;
65
107
if ( preserveStaticLogger )
66
108
{
67
- collection . AddSingleton < ILoggerFactory > ( services => new SerilogLoggerFactory ( logger , true ) ) ;
109
+ registeredLogger = logger ;
68
110
}
69
- else
111
+ else
70
112
{
71
113
// Passing a `null` logger to `SerilogLoggerFactory` results in disposal via
72
114
// `Log.CloseAndFlush()`, which additionally replaces the static logger with a no-op.
73
115
Log . Logger = logger ;
74
- collection . AddSingleton < ILoggerFactory > ( services => new SerilogLoggerFactory ( null , true ) ) ;
75
116
}
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
+ } ) ;
76
130
} ) ;
77
131
return builder ;
78
132
}
0 commit comments