-
Notifications
You must be signed in to change notification settings - Fork 784
/
Copy pathOpenTelemetryLoggerProvider.cs
149 lines (127 loc) · 4.63 KB
/
OpenTelemetryLoggerProvider.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0
using System.Collections;
using System.Diagnostics;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using OpenTelemetry.Internal;
namespace OpenTelemetry.Logs;
/// <summary>
/// An <see cref="ILoggerProvider"/> implementation for exporting logs using OpenTelemetry.
/// </summary>
[ProviderAlias("OpenTelemetry")]
public class OpenTelemetryLoggerProvider : BaseProvider, ILoggerProvider, ISupportExternalScope
{
internal readonly LoggerProvider Provider;
private readonly bool ownsProvider;
private readonly Hashtable loggers = new();
private bool disposed;
static OpenTelemetryLoggerProvider()
{
// Accessing Sdk class is just to trigger its static ctor,
// which sets default Propagators and default Activity Id format
_ = Sdk.SuppressInstrumentation;
}
/// <summary>
/// Initializes a new instance of the <see cref="OpenTelemetryLoggerProvider"/> class.
/// </summary>
/// <param name="options"><see cref="OpenTelemetryLoggerOptions"/>.</param>
// todo: [Obsolete("Use the Sdk.CreateLoggerProviderBuilder method instead this ctor will be removed in a future version.")]
public OpenTelemetryLoggerProvider(IOptionsMonitor<OpenTelemetryLoggerOptions> options)
{
Guard.ThrowIfNull(options);
var optionsInstance = options.CurrentValue;
this.Provider = Sdk
.CreateLoggerProviderBuilder()
.ConfigureBuilder((sp, builder) =>
{
if (optionsInstance.ResourceBuilder != null)
{
builder.SetResourceBuilder(optionsInstance.ResourceBuilder);
}
foreach (var processorFactory in optionsInstance.ProcessorFactories)
{
builder.AddProcessor(processorFactory);
}
})
.Build();
this.Options = optionsInstance.Copy();
this.ownsProvider = true;
}
internal OpenTelemetryLoggerProvider(
LoggerProvider loggerProvider,
OpenTelemetryLoggerOptions options,
bool disposeProvider)
{
Debug.Assert(loggerProvider != null, "loggerProvider was null");
Debug.Assert(options != null, "options was null");
this.Provider = loggerProvider!;
this.Options = options!.Copy();
this.ownsProvider = disposeProvider;
}
internal OpenTelemetryLoggerOptions Options { get; }
internal IExternalScopeProvider? ScopeProvider { get; private set; }
/// <inheritdoc/>
void ISupportExternalScope.SetScopeProvider(IExternalScopeProvider scopeProvider)
{
this.ScopeProvider = scopeProvider;
lock (this.loggers)
{
foreach (DictionaryEntry entry in this.loggers)
{
if (entry.Value is OpenTelemetryLogger logger)
{
logger.ScopeProvider = scopeProvider;
}
}
}
}
/// <inheritdoc/>
public ILogger CreateLogger(string categoryName)
{
// Lock-free reading leveraging Hashtable's thread safety feature.
// https://learn.microsoft.com/dotnet/api/system.collections.hashtable#thread-safety
if (this.loggers[categoryName] is not ILogger logger)
{
lock (this.loggers)
{
logger = (this.loggers[categoryName] as ILogger)!;
if (logger == null)
{
var loggerProviderSdk = this.Provider as LoggerProviderSdk;
if (loggerProviderSdk == null)
{
logger = NullLogger.Instance;
}
else
{
logger = new OpenTelemetryLogger(loggerProviderSdk, this.Options, categoryName)
{
ScopeProvider = this.ScopeProvider,
};
}
this.loggers[categoryName] = logger;
}
}
}
return logger;
}
/// <inheritdoc/>
protected override void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
if (this.ownsProvider)
{
this.Provider.Dispose();
}
}
this.disposed = true;
OpenTelemetrySdkEventSource.Log.ProviderDisposed(nameof(OpenTelemetryLoggerProvider));
}
base.Dispose(disposing);
}
}