12
12
using Serilog . Core ;
13
13
using Serilog . Events ;
14
14
using FrameworkLogger = Microsoft . Extensions . Logging . ILogger ;
15
+ using System . Collections . Generic ;
15
16
16
17
namespace Serilog . Extensions . Logging
17
18
{
@@ -21,17 +22,49 @@ namespace Serilog.Extensions.Logging
21
22
public class SerilogLoggerProvider : ILoggerProvider , ILogEventEnricher
22
23
{
23
24
internal const string OriginalFormatPropertyName = "{OriginalFormat}" ;
25
+ internal const string ScopePropertyName = "Scope" ;
24
26
25
27
// May be null; if it is, Log.Logger will be lazily used
26
28
readonly ILogger _logger ;
27
29
readonly Action _dispose ;
30
+ readonly bool _includeNamedScopes ;
31
+
32
+ /// <summary>
33
+ /// Construct a <see cref="SerilogLoggerProvider"/>.
34
+ /// </summary>
35
+ public SerilogLoggerProvider ( )
36
+ : this ( null )
37
+ {
38
+ }
39
+
40
+ /// <summary>
41
+ /// Construct a <see cref="SerilogLoggerProvider"/>.
42
+ /// </summary>
43
+ /// <param name="logger">A Serilog logger to pipe events through; if null, the static <see cref="Log"/> class will be used.</param>
44
+ public SerilogLoggerProvider ( ILogger logger )
45
+ : this ( logger , false )
46
+ {
47
+ }
28
48
29
49
/// <summary>
30
50
/// Construct a <see cref="SerilogLoggerProvider"/>.
31
51
/// </summary>
32
52
/// <param name="logger">A Serilog logger to pipe events through; if null, the static <see cref="Log"/> class will be used.</param>
33
53
/// <param name="dispose">If true, the provided logger or static log class will be disposed/closed when the provider is disposed.</param>
34
- public SerilogLoggerProvider ( ILogger logger = null , bool dispose = false )
54
+ public SerilogLoggerProvider ( ILogger logger , bool dispose )
55
+ : this ( logger , dispose , false )
56
+ {
57
+ }
58
+
59
+ /// <summary>
60
+ /// Construct a <see cref="SerilogLoggerProvider"/>.
61
+ /// </summary>
62
+ /// <param name="logger">A Serilog logger to pipe events through; if null, the static <see cref="Log"/> class will be used.</param>
63
+ /// <param name="dispose">If true, the provided logger or static log class will be disposed/closed when the provider is disposed.</param>
64
+ /// <param name="includeNamedScopes">Indicates whether a <code>Scope</code> property should be generated when
65
+ /// <see cref="Microsoft.Extensions.Logging.ILogger.BeginScope"/> is called with <see cref="string"/> arguments. The
66
+ /// default is false.</param>
67
+ public SerilogLoggerProvider ( ILogger logger , bool dispose , bool includeNamedScopes )
35
68
{
36
69
if ( logger != null )
37
70
_logger = logger . ForContext ( new [ ] { this } ) ;
@@ -43,6 +76,8 @@ public SerilogLoggerProvider(ILogger logger = null, bool dispose = false)
43
76
else
44
77
_dispose = Log . CloseAndFlush ;
45
78
}
79
+
80
+ _includeNamedScopes = includeNamedScopes ;
46
81
}
47
82
48
83
/// <inheritdoc />
@@ -64,6 +99,25 @@ public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
64
99
{
65
100
scope . Enrich ( logEvent , propertyFactory ) ;
66
101
}
102
+
103
+ if ( _includeNamedScopes )
104
+ {
105
+ List < ScalarValue > names = null ;
106
+ for ( var scope = CurrentScope ; scope != null ; scope = scope . Parent )
107
+ {
108
+ string name ;
109
+ if ( scope . TryGetName ( out name ) )
110
+ {
111
+ names = names ?? new List < ScalarValue > ( ) ;
112
+ names . Insert ( 0 , new ScalarValue ( name ) ) ;
113
+ }
114
+ }
115
+
116
+ if ( names != null )
117
+ {
118
+ logEvent . AddPropertyIfAbsent ( new LogEventProperty ( ScopePropertyName , new SequenceValue ( names ) ) ) ;
119
+ }
120
+ }
67
121
}
68
122
69
123
#if ASYNCLOCAL
0 commit comments