1212using Serilog . Core ;
1313using Serilog . Events ;
1414using FrameworkLogger = Microsoft . Extensions . Logging . ILogger ;
15+ using System . Collections . Generic ;
1516
1617namespace Serilog . Extensions . Logging
1718{
@@ -21,17 +22,49 @@ namespace Serilog.Extensions.Logging
2122 public class SerilogLoggerProvider : ILoggerProvider , ILogEventEnricher
2223 {
2324 internal const string OriginalFormatPropertyName = "{OriginalFormat}" ;
25+ internal const string ScopePropertyName = "Scope" ;
2426
2527 // May be null; if it is, Log.Logger will be lazily used
2628 readonly ILogger _logger ;
2729 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+ }
2848
2949 /// <summary>
3050 /// Construct a <see cref="SerilogLoggerProvider"/>.
3151 /// </summary>
3252 /// <param name="logger">A Serilog logger to pipe events through; if null, the static <see cref="Log"/> class will be used.</param>
3353 /// <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 )
3568 {
3669 if ( logger != null )
3770 _logger = logger . ForContext ( new [ ] { this } ) ;
@@ -43,6 +76,8 @@ public SerilogLoggerProvider(ILogger logger = null, bool dispose = false)
4376 else
4477 _dispose = Log . CloseAndFlush ;
4578 }
79+
80+ _includeNamedScopes = includeNamedScopes ;
4681 }
4782
4883 /// <inheritdoc />
@@ -64,6 +99,25 @@ public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
6499 {
65100 scope . Enrich ( logEvent , propertyFactory ) ;
66101 }
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+ }
67121 }
68122
69123#if ASYNCLOCAL
0 commit comments