5
5
6
6
using System ;
7
7
using Azure . Core ;
8
+ using Microsoft . Extensions . DependencyInjection ;
9
+ using Microsoft . Extensions . Options ;
8
10
using OpenTelemetry ;
9
11
using OpenTelemetry . Trace ;
10
12
@@ -16,27 +18,49 @@ namespace Azure.Monitor.OpenTelemetry.Exporter
16
18
public static class AzureMonitorExporterTraceExtensions
17
19
{
18
20
/// <summary>
19
- /// Registers an Azure Monitor trace exporter that will receive <see cref="System.Diagnostics.Activity"/> instances .
21
+ /// Adds Azure Monitor Trace exporter to the TracerProvider .
20
22
/// </summary>
21
23
/// <param name="builder"><see cref="TracerProviderBuilder"/> builder to use.</param>
22
- /// <param name="configure">Exporter configuration options .</param>
24
+ /// <param name="configure">Callback action for configuring <see cref="AzureMonitorExporterOptions"/> .</param>
23
25
/// <param name="credential"><see cref="TokenCredential" /></param>
26
+ /// <param name="name">Name which is used when retrieving options.</param>
24
27
/// <returns>The instance of <see cref="TracerProviderBuilder"/> to chain the calls.</returns>
25
- public static TracerProviderBuilder AddAzureMonitorTraceExporter ( this TracerProviderBuilder builder , Action < AzureMonitorExporterOptions > configure = null , TokenCredential credential = null )
28
+ public static TracerProviderBuilder AddAzureMonitorTraceExporter (
29
+ this TracerProviderBuilder builder ,
30
+ Action < AzureMonitorExporterOptions > configure = null ,
31
+ TokenCredential credential = null ,
32
+ string name = null )
26
33
{
27
34
if ( builder == null )
28
35
{
29
36
throw new ArgumentNullException ( nameof ( builder ) ) ;
30
37
}
31
38
32
- var options = new AzureMonitorExporterOptions ( ) ;
33
- configure ? . Invoke ( options ) ;
39
+ var finalOptionsName = name ?? Options . DefaultName ;
34
40
35
- // TODO: provide a way to turn off statsbeat
36
- // Statsbeat.InitializeAttachStatsbeat(options.ConnectionString);
41
+ if ( name != null && configure != null )
42
+ {
43
+ // If we are using named options we register the
44
+ // configuration delegate into options pipeline.
45
+ builder . ConfigureServices ( services => services . Configure ( finalOptionsName , configure ) ) ;
46
+ }
47
+
48
+ return builder . AddProcessor ( sp =>
49
+ {
50
+ var exporterOptions = sp . GetRequiredService < IOptionsMonitor < AzureMonitorExporterOptions > > ( ) . Get ( finalOptionsName ) ;
51
+
52
+ if ( name == null && configure != null )
53
+ {
54
+ // If we are NOT using named options, we execute the
55
+ // configuration delegate inline. The reason for this is
56
+ // AzureMonitorExporterOptions is shared by all signals. Without a
57
+ // name, delegates for all signals will mix together. See:
58
+ // https://github.com/open-telemetry/opentelemetry-dotnet/issues/4043
59
+ configure ( exporterOptions ) ;
60
+ }
37
61
38
- // TODO: Pick Simple vs Batching based on AzureMonitorExporterOptions
39
- return builder . AddProcessor ( new BatchActivityExportProcessor ( new AzureMonitorTraceExporter ( options , credential ) ) ) ;
62
+ return new BatchActivityExportProcessor ( new AzureMonitorTraceExporter ( exporterOptions , credential ) ) ;
63
+ } ) ;
40
64
}
41
65
}
42
66
}
0 commit comments