1717#nullable enable
1818
1919using System . Collections ;
20- using System . Text ;
21- using Microsoft . Extensions . DependencyInjection ;
20+ using System . Diagnostics ;
2221using Microsoft . Extensions . Logging ;
22+ using Microsoft . Extensions . Logging . Abstractions ;
2323using Microsoft . Extensions . Options ;
2424using OpenTelemetry . Internal ;
25- using OpenTelemetry . Resources ;
2625
2726namespace OpenTelemetry . Logs
2827{
@@ -32,15 +31,9 @@ namespace OpenTelemetry.Logs
3231 [ ProviderAlias ( "OpenTelemetry" ) ]
3332 public class OpenTelemetryLoggerProvider : BaseProvider , ILoggerProvider , ISupportExternalScope
3433 {
35- internal readonly bool IncludeAttributes ;
36- internal readonly bool IncludeFormattedMessage ;
37- internal readonly bool IncludeScopes ;
38- internal readonly bool IncludeTraceState ;
39- internal readonly bool ParseStateValues ;
40- internal BaseProcessor < LogRecord > ? Processor ;
41- internal Resource Resource ;
34+ internal readonly LoggerProvider Provider ;
35+ private readonly bool ownsProvider ;
4236 private readonly Hashtable loggers = new ( ) ;
43- private ILogRecordPool ? threadStaticPool = LogRecordThreadStaticPool . Instance ;
4437 private bool disposed ;
4538
4639 static OpenTelemetryLoggerProvider ( )
@@ -54,60 +47,50 @@ static OpenTelemetryLoggerProvider()
5447 /// Initializes a new instance of the <see cref="OpenTelemetryLoggerProvider"/> class.
5548 /// </summary>
5649 /// <param name="options"><see cref="OpenTelemetryLoggerOptions"/>.</param>
50+ // todo: [Obsolete("Use the Sdk.CreateLoggerProviderBuilder method instead this ctor will be removed in a future version.")]
5751 public OpenTelemetryLoggerProvider ( IOptionsMonitor < OpenTelemetryLoggerOptions > options )
58- : this ( options ? . CurrentValue ?? throw new ArgumentNullException ( nameof ( options ) ) )
5952 {
60- }
53+ Guard . ThrowIfNull ( options ) ;
6154
62- internal OpenTelemetryLoggerProvider ( IServiceProvider serviceProvider )
63- : this (
64- serviceProvider : serviceProvider ?? throw new ArgumentNullException ( nameof ( serviceProvider ) ) ,
65- options : serviceProvider ? . GetRequiredService < IOptionsMonitor < OpenTelemetryLoggerOptions > > ( ) . CurrentValue ! )
66- {
67- }
55+ var optionsInstance = options . CurrentValue ;
6856
69- internal OpenTelemetryLoggerProvider ( )
70- : this ( new OpenTelemetryLoggerOptions ( ) )
71- {
72- }
57+ this . Provider = Sdk
58+ . CreateLoggerProviderBuilder ( )
59+ . ConfigureBuilder ( ( sp , builder ) =>
60+ {
61+ if ( optionsInstance . ResourceBuilder != null )
62+ {
63+ builder . SetResourceBuilder ( optionsInstance . ResourceBuilder ) ;
64+ }
7365
74- internal OpenTelemetryLoggerProvider ( Action < OpenTelemetryLoggerOptions > configure )
75- : this ( BuildOptions ( configure ) )
76- {
66+ foreach ( var processor in optionsInstance . Processors )
67+ {
68+ builder . AddProcessor ( processor ) ;
69+ }
70+ } )
71+ . Build ( ) ;
72+
73+ this . Options = optionsInstance . Copy ( ) ;
74+ this . ownsProvider = true ;
7775 }
7876
79- internal OpenTelemetryLoggerProvider ( OpenTelemetryLoggerOptions options , IServiceProvider ? serviceProvider = null )
77+ internal OpenTelemetryLoggerProvider (
78+ LoggerProvider loggerProvider ,
79+ OpenTelemetryLoggerOptions options ,
80+ bool disposeProvider )
8081 {
81- OpenTelemetrySdkEventSource . Log . OpenTelemetryLoggerProviderEvent ( "Building OpenTelemetryLoggerProvider." ) ;
82-
83- Guard . ThrowIfNull ( options ) ;
84-
85- this . ServiceProvider = serviceProvider ;
86-
87- this . IncludeAttributes = options . IncludeAttributes ;
88- this . IncludeFormattedMessage = options . IncludeFormattedMessage ;
89- this . IncludeScopes = options . IncludeScopes ;
90- this . IncludeTraceState = options . IncludeTraceState ;
91- this . ParseStateValues = options . ParseStateValues ;
92-
93- var resourceBuilder = options . ResourceBuilder ;
94- resourceBuilder . ServiceProvider = serviceProvider ;
95- this . Resource = resourceBuilder . Build ( ) ;
82+ Debug . Assert ( loggerProvider != null , "loggerProvider was null" ) ;
83+ Debug . Assert ( options != null , "options was null" ) ;
9684
97- foreach ( var processor in options . Processors )
98- {
99- this . AddProcessor ( processor ) ;
100- }
101-
102- OpenTelemetrySdkEventSource . Log . OpenTelemetryLoggerProviderEvent ( "OpenTelemetryLoggerProvider built successfully." ) ;
85+ this . Provider = loggerProvider ! ;
86+ this . Options = options ! . Copy ( ) ;
87+ this . ownsProvider = disposeProvider ;
10388 }
10489
105- internal IServiceProvider ? ServiceProvider { get ; }
90+ internal OpenTelemetryLoggerOptions Options { get ; }
10691
10792 internal IExternalScopeProvider ? ScopeProvider { get ; private set ; }
10893
109- internal ILogRecordPool LogRecordPool => this . threadStaticPool ?? LogRecordSharedPool . Current ;
110-
11194 /// <inheritdoc/>
11295 void ISupportExternalScope . SetScopeProvider ( IExternalScopeProvider scopeProvider )
11396 {
@@ -128,17 +111,25 @@ void ISupportExternalScope.SetScopeProvider(IExternalScopeProvider scopeProvider
128111 /// <inheritdoc/>
129112 public ILogger CreateLogger ( string categoryName )
130113 {
131- if ( this . loggers [ categoryName ] is not OpenTelemetryLogger logger )
114+ if ( this . loggers [ categoryName ] is not ILogger logger )
132115 {
133116 lock ( this . loggers )
134117 {
135- logger = ( this . loggers [ categoryName ] as OpenTelemetryLogger ) ! ;
118+ logger = ( this . loggers [ categoryName ] as ILogger ) ! ;
136119 if ( logger == null )
137120 {
138- logger = new OpenTelemetryLogger ( categoryName , this )
121+ var loggerProviderSdk = this . Provider as LoggerProviderSdk ;
122+ if ( loggerProviderSdk == null )
123+ {
124+ logger = NullLogger . Instance ;
125+ }
126+ else
139127 {
140- ScopeProvider = this . ScopeProvider ,
141- } ;
128+ logger = new OpenTelemetryLogger ( loggerProviderSdk , this . Options , categoryName )
129+ {
130+ ScopeProvider = this . ScopeProvider ,
131+ } ;
132+ }
142133
143134 this . loggers [ categoryName ] = logger ;
144135 }
@@ -148,126 +139,17 @@ public ILogger CreateLogger(string categoryName)
148139 return logger ;
149140 }
150141
151- /// <summary>
152- /// Flushes all the processors registered under <see
153- /// cref="OpenTelemetryLoggerProvider"/>, blocks the current thread
154- /// until flush completed, shutdown signaled or timed out.
155- /// </summary>
156- /// <param name="timeoutMilliseconds">
157- /// The number (non-negative) of milliseconds to wait, or
158- /// <c>Timeout.Infinite</c> to wait indefinitely.
159- /// </param>
160- /// <returns>
161- /// Returns <c>true</c> when force flush succeeded; otherwise, <c>false</c>.
162- /// </returns>
163- /// <exception cref="ArgumentOutOfRangeException">
164- /// Thrown when the <c>timeoutMilliseconds</c> is smaller than -1.
165- /// </exception>
166- /// <remarks>
167- /// This function guarantees thread-safety.
168- /// </remarks>
169- internal bool ForceFlush ( int timeoutMilliseconds = Timeout . Infinite )
170- {
171- OpenTelemetrySdkEventSource . Log . OpenTelemetryLoggerProviderForceFlushInvoked ( timeoutMilliseconds ) ;
172- return this . Processor ? . ForceFlush ( timeoutMilliseconds ) ?? true ;
173- }
174-
175- /// <summary>
176- /// Add a processor to the <see cref="OpenTelemetryLoggerProvider"/>.
177- /// </summary>
178- /// <remarks>
179- /// Note: The supplied <paramref name="processor"/> will be
180- /// automatically disposed when then the <see
181- /// cref="OpenTelemetryLoggerProvider"/> is disposed.
182- /// </remarks>
183- /// <param name="processor">Log processor to add.</param>
184- /// <returns>The supplied <see cref="OpenTelemetryLoggerOptions"/> for chaining.</returns>
185- internal OpenTelemetryLoggerProvider AddProcessor ( BaseProcessor < LogRecord > processor )
186- {
187- OpenTelemetrySdkEventSource . Log . OpenTelemetryLoggerProviderEvent ( "Started adding processor." ) ;
188-
189- Guard . ThrowIfNull ( processor ) ;
190-
191- processor . SetParentProvider ( this ) ;
192-
193- StringBuilder processorAdded = new StringBuilder ( ) ;
194-
195- if ( this . threadStaticPool != null && this . ContainsBatchProcessor ( processor ) )
196- {
197- OpenTelemetrySdkEventSource . Log . OpenTelemetryLoggerProviderEvent ( "Using shared thread pool." ) ;
198-
199- this . threadStaticPool = null ;
200- }
201-
202- if ( this . Processor == null )
203- {
204- processorAdded . Append ( "Setting processor to " ) ;
205- processorAdded . Append ( processor ) ;
206-
207- this . Processor = processor ;
208- }
209- else if ( this . Processor is CompositeProcessor < LogRecord > compositeProcessor )
210- {
211- processorAdded . Append ( "Adding processor " ) ;
212- processorAdded . Append ( processor ) ;
213- processorAdded . Append ( " to composite processor" ) ;
214-
215- compositeProcessor . AddProcessor ( processor ) ;
216- }
217- else
218- {
219- processorAdded . Append ( "Creating new composite processor with processor " ) ;
220- processorAdded . Append ( this . Processor ) ;
221- processorAdded . Append ( " and adding new processor " ) ;
222- processorAdded . Append ( processor ) ;
223-
224- var newCompositeProcessor = new CompositeProcessor < LogRecord > ( new [ ]
225- {
226- this . Processor ,
227- } ) ;
228- newCompositeProcessor . SetParentProvider ( this ) ;
229- newCompositeProcessor . AddProcessor ( processor ) ;
230- this . Processor = newCompositeProcessor ;
231- }
232-
233- OpenTelemetrySdkEventSource . Log . OpenTelemetryLoggerProviderEvent ( $ "Completed adding processor = \" { processorAdded } \" .") ;
234-
235- return this ;
236- }
237-
238- internal bool ContainsBatchProcessor ( BaseProcessor < LogRecord > processor )
239- {
240- if ( processor is BatchExportProcessor < LogRecord > )
241- {
242- return true ;
243- }
244- else if ( processor is CompositeProcessor < LogRecord > compositeProcessor )
245- {
246- var current = compositeProcessor . Head ;
247- while ( current != null )
248- {
249- if ( this . ContainsBatchProcessor ( current . Value ) )
250- {
251- return true ;
252- }
253-
254- current = current . Next ;
255- }
256- }
257-
258- return false ;
259- }
260-
261142 /// <inheritdoc/>
262143 protected override void Dispose ( bool disposing )
263144 {
264145 if ( ! this . disposed )
265146 {
266147 if ( disposing )
267148 {
268- // Wait for up to 5 seconds grace period
269- this . Processor ? . Shutdown ( 5000 ) ;
270- this . Processor ? . Dispose ( ) ;
149+ if ( this . ownsProvider )
150+ {
151+ this . Provider . Dispose ( ) ;
152+ }
271153 }
272154
273155 this . disposed = true ;
@@ -276,12 +158,5 @@ protected override void Dispose(bool disposing)
276158
277159 base . Dispose ( disposing ) ;
278160 }
279-
280- private static OpenTelemetryLoggerOptions BuildOptions ( Action < OpenTelemetryLoggerOptions > configure )
281- {
282- var options = new OpenTelemetryLoggerOptions ( ) ;
283- configure ? . Invoke ( options ) ;
284- return options ;
285- }
286161 }
287162}
0 commit comments