1212// See the License for the specific language governing permissions and
1313// limitations under the License.
1414
15+ // ReSharper disable once RedundantUsingDirective
1516using System . Net . Http ;
16- using Serilog . Configuration ;
17- using Serilog . Sinks . OpenTelemetry ;
18- using Serilog . Sinks . OpenTelemetry . Exporters ;
17+
1918using Serilog . Collections ;
19+ using Serilog . Configuration ;
2020using Serilog . Core ;
2121using Serilog . Events ;
22+ using Serilog . Sinks . OpenTelemetry ;
23+ using Serilog . Sinks . OpenTelemetry . Configuration ;
24+ using Serilog . Sinks . OpenTelemetry . Exporters ;
25+ // ReSharper disable MemberCanBePrivate.Global
2226
2327namespace Serilog ;
2428
@@ -27,42 +31,72 @@ namespace Serilog;
2731/// </summary>
2832public static class OpenTelemetryLoggerConfigurationExtensions
2933{
34+ // ReSharper disable once ReturnTypeCanBeNotNullable
3035 static HttpMessageHandler ? CreateDefaultHttpMessageHandler ( ) =>
3136#if FEATURE_SOCKETS_HTTP_HANDLER
3237 new SocketsHttpHandler { ActivityHeadersPropagator = null } ;
3338#else
3439 null ;
3540#endif
36-
41+
3742 /// <summary>
3843 /// Send log events to an OTLP exporter.
3944 /// </summary>
4045 /// <param name="loggerSinkConfiguration">
4146 /// The `WriteTo` configuration object.
4247 /// </param>
4348 /// <param name="configure">The configuration callback.</param>
49+ /// <param name="ignoreEnvironment">If false the configuration will be overridden with values
50+ /// from the <see href="https://opentelemetry.io/docs/languages/sdk-configuration/otlp-exporter/">OTLP Exporter
51+ /// Configuration environment variables</see>, if present.</param>
4452 public static LoggerConfiguration OpenTelemetry (
4553 this LoggerSinkConfiguration loggerSinkConfiguration ,
46- Action < BatchedOpenTelemetrySinkOptions > configure )
54+ Action < BatchedOpenTelemetrySinkOptions > configure ,
55+ bool ignoreEnvironment = false )
4756 {
4857 if ( configure == null ) throw new ArgumentNullException ( nameof ( configure ) ) ;
4958
5059 var options = new BatchedOpenTelemetrySinkOptions ( ) ;
5160 configure ( options ) ;
5261
62+ if ( ! ignoreEnvironment )
63+ {
64+ OpenTelemetryEnvironment . Configure ( options , Environment . GetEnvironmentVariable ) ;
65+ }
66+
5367 var exporter = Exporter . Create (
54- endpoint : options . Endpoint ,
68+ logsEndpoint : options . LogsEndpoint ,
69+ tracesEndpoint : options . TracesEndpoint ,
5570 protocol : options . Protocol ,
5671 headers : new Dictionary < string , string > ( options . Headers ) ,
5772 httpMessageHandler : options . HttpMessageHandler ?? CreateDefaultHttpMessageHandler ( ) ) ;
5873
59- var openTelemetrySink = new OpenTelemetrySink (
60- exporter : exporter ,
61- formatProvider : options . FormatProvider ,
62- resourceAttributes : new Dictionary < string , object > ( options . ResourceAttributes ) ,
63- includedData : options . IncludedData ) ;
74+ ILogEventSink ? logsSink = null , tracesSink = null ;
75+
76+ if ( options . LogsEndpoint != null )
77+ {
78+ var openTelemetryLogsSink = new OpenTelemetryLogsSink (
79+ exporter : exporter ,
80+ formatProvider : options . FormatProvider ,
81+ resourceAttributes : new Dictionary < string , object > ( options . ResourceAttributes ) ,
82+ includedData : options . IncludedData ) ;
6483
65- return loggerSinkConfiguration . Sink ( openTelemetrySink , options . BatchingOptions , options . RestrictedToMinimumLevel , options . LevelSwitch ) ;
84+ logsSink = LoggerSinkConfiguration . CreateSink ( wt => wt . Sink ( openTelemetryLogsSink , options . BatchingOptions ) ) ;
85+ }
86+
87+ if ( options . TracesEndpoint != null )
88+ {
89+ var openTelemetryTracesSink = new OpenTelemetryTracesSink (
90+ exporter : exporter ,
91+ resourceAttributes : new Dictionary < string , object > ( options . ResourceAttributes ) ,
92+ includedData : options . IncludedData ) ;
93+
94+ tracesSink = LoggerSinkConfiguration . CreateSink ( wt => wt . Sink ( openTelemetryTracesSink , options . BatchingOptions ) ) ;
95+ }
96+
97+ var sink = new OpenTelemetrySink ( exporter , logsSink , tracesSink ) ;
98+
99+ return loggerSinkConfiguration . Sink ( sink , options . RestrictedToMinimumLevel , options . LevelSwitch ) ;
66100 }
67101
68102 /// <summary>
@@ -117,7 +151,7 @@ public static LoggerConfiguration OpenTelemetry(
117151 resourceAttributes ? . AddTo ( options . ResourceAttributes ) ;
118152 } ) ;
119153 }
120-
154+
121155 /// <summary>
122156 /// Audit to an OTLP exporter, waiting for each event to be acknowledged, and propagating errors to the caller.
123157 /// </summary>
@@ -132,20 +166,35 @@ public static LoggerConfiguration OpenTelemetry(
132166 if ( configure == null ) throw new ArgumentNullException ( nameof ( configure ) ) ;
133167
134168 var options = new OpenTelemetrySinkOptions ( ) ;
135-
136169 configure ( options ) ;
137170
138171 var exporter = Exporter . Create (
139- endpoint : options . Endpoint ,
172+ logsEndpoint : options . LogsEndpoint ,
173+ tracesEndpoint : options . TracesEndpoint ,
140174 protocol : options . Protocol ,
141175 headers : new Dictionary < string , string > ( options . Headers ) ,
142176 httpMessageHandler : options . HttpMessageHandler ?? CreateDefaultHttpMessageHandler ( ) ) ;
143177
144- var sink = new OpenTelemetrySink (
145- exporter : exporter ,
146- formatProvider : options . FormatProvider ,
147- resourceAttributes : new Dictionary < string , object > ( options . ResourceAttributes ) ,
148- includedData : options . IncludedData ) ;
178+ ILogEventSink ? logsSink = null , tracesSink = null ;
179+
180+ if ( options . LogsEndpoint != null )
181+ {
182+ logsSink = new OpenTelemetryLogsSink (
183+ exporter : exporter ,
184+ formatProvider : options . FormatProvider ,
185+ resourceAttributes : new Dictionary < string , object > ( options . ResourceAttributes ) ,
186+ includedData : options . IncludedData ) ;
187+ }
188+
189+ if ( options . TracesEndpoint != null )
190+ {
191+ tracesSink = new OpenTelemetryTracesSink (
192+ exporter : exporter ,
193+ resourceAttributes : new Dictionary < string , object > ( options . ResourceAttributes ) ,
194+ includedData : options . IncludedData ) ;
195+ }
196+
197+ var sink = new OpenTelemetrySink ( exporter , logsSink , tracesSink ) ;
149198
150199 return loggerAuditSinkConfiguration . Sink ( sink , options . RestrictedToMinimumLevel , options . LevelSwitch ) ;
151200 }
0 commit comments