Skip to content

Commit 660d5b5

Browse files
authored
[sdk-logs] Update ILogger integration to use LoggerProvider (#4473)
1 parent ce71d13 commit 660d5b5

File tree

9 files changed

+367
-542
lines changed

9 files changed

+367
-542
lines changed

src/OpenTelemetry/Logs/ILogger/OpenTelemetryLogger.cs

Lines changed: 190 additions & 171 deletions
Large diffs are not rendered by default.

src/OpenTelemetry/Logs/ILogger/OpenTelemetryLoggerOptions.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ namespace OpenTelemetry.Logs
2828
public class OpenTelemetryLoggerOptions
2929
{
3030
internal readonly List<BaseProcessor<LogRecord>> Processors = new();
31-
internal ResourceBuilder ResourceBuilder = ResourceBuilder.CreateDefault();
31+
internal ResourceBuilder? ResourceBuilder;
3232

3333
/// <summary>
3434
/// Gets or sets a value indicating whether or not formatted log message
@@ -111,5 +111,17 @@ public OpenTelemetryLoggerOptions SetResourceBuilder(ResourceBuilder resourceBui
111111
this.ResourceBuilder = resourceBuilder;
112112
return this;
113113
}
114+
115+
internal OpenTelemetryLoggerOptions Copy()
116+
{
117+
return new()
118+
{
119+
IncludeFormattedMessage = this.IncludeFormattedMessage,
120+
IncludeScopes = this.IncludeScopes,
121+
ParseStateValues = this.ParseStateValues,
122+
IncludeAttributes = this.IncludeAttributes,
123+
IncludeTraceState = this.IncludeTraceState,
124+
};
125+
}
114126
}
115127
}

src/OpenTelemetry/Logs/ILogger/OpenTelemetryLoggerProvider.cs

Lines changed: 51 additions & 176 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,11 @@
1717
#nullable enable
1818

1919
using System.Collections;
20-
using System.Text;
21-
using Microsoft.Extensions.DependencyInjection;
20+
using System.Diagnostics;
2221
using Microsoft.Extensions.Logging;
22+
using Microsoft.Extensions.Logging.Abstractions;
2323
using Microsoft.Extensions.Options;
2424
using OpenTelemetry.Internal;
25-
using OpenTelemetry.Resources;
2625

2726
namespace 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

Comments
 (0)