Skip to content

Commit 2adf5c7

Browse files
authored
Initial version of an Auto Instrumentation plugin (#118)
* Initial version of an Auto Instrumentation Plugin * do not package plugin for now * formatting * license header
1 parent e4dccf0 commit 2adf5c7

16 files changed

+223
-73
lines changed

Elastic.OpenTelemetry.sln

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AppHost", "examples\AppHost
4141
EndProject
4242
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceDefaults", "examples\ServiceDefaults\ServiceDefaults.csproj", "{A3D1ED4D-863B-45D7-9829-305DD33B4CE5}"
4343
EndProject
44+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elastic.OpenTelemetry.AutoInstrumentationPlugin", "src\Elastic.OpenTelemetry.AutoInstrumentationPlugin\Elastic.OpenTelemetry.AutoInstrumentationPlugin.csproj", "{B61D749B-21E5-430D-B50D-CA02EBAA7F2F}"
45+
EndProject
4446
Global
4547
GlobalSection(SolutionConfigurationPlatforms) = preSolution
4648
Debug|Any CPU = Debug|Any CPU
@@ -95,6 +97,10 @@ Global
9597
{A3D1ED4D-863B-45D7-9829-305DD33B4CE5}.Debug|Any CPU.Build.0 = Debug|Any CPU
9698
{A3D1ED4D-863B-45D7-9829-305DD33B4CE5}.Release|Any CPU.ActiveCfg = Release|Any CPU
9799
{A3D1ED4D-863B-45D7-9829-305DD33B4CE5}.Release|Any CPU.Build.0 = Release|Any CPU
100+
{B61D749B-21E5-430D-B50D-CA02EBAA7F2F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
101+
{B61D749B-21E5-430D-B50D-CA02EBAA7F2F}.Debug|Any CPU.Build.0 = Debug|Any CPU
102+
{B61D749B-21E5-430D-B50D-CA02EBAA7F2F}.Release|Any CPU.ActiveCfg = Release|Any CPU
103+
{B61D749B-21E5-430D-B50D-CA02EBAA7F2F}.Release|Any CPU.Build.0 = Release|Any CPU
98104
EndGlobalSection
99105
GlobalSection(SolutionProperties) = preSolution
100106
HideSolutionNode = FALSE
@@ -109,6 +115,7 @@ Global
109115
{863CAB86-5EB0-4E9F-B01D-F51687EC6597} = {4E95C87B-655B-4BC3-8F2A-DF06B7AAB7E9}
110116
{206203BD-3EBA-4E9A-8881-1189D95AB037} = {4E95C87B-655B-4BC3-8F2A-DF06B7AAB7E9}
111117
{A3D1ED4D-863B-45D7-9829-305DD33B4CE5} = {4E95C87B-655B-4BC3-8F2A-DF06B7AAB7E9}
118+
{B61D749B-21E5-430D-B50D-CA02EBAA7F2F} = {E622CFF2-C6C4-40FB-BE42-7C4F2B38B75A}
112119
EndGlobalSection
113120
GlobalSection(ExtensibilityGlobals) = postSolution
114121
SolutionGuid = {573B2B5F-8CBB-4D52-A55A-4E65E282AAFB}

examples/Example.AspNetCore.Mvc/Example.AspNetCore.Mvc.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
</ItemGroup>
1313

1414
<ItemGroup>
15-
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.8.1" />
15+
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.9.0" />
1616
</ItemGroup>
1717

1818
</Project>

examples/Example.Console/Example.Console.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
</PropertyGroup>
99

1010
<ItemGroup>
11-
<PackageReference Include="OpenTelemetry.Exporter.Console" Version="1.8.1" />
12-
<PackageReference Include="OpenTelemetry.Instrumentation.StackExchangeRedis" Version="1.0.0-rc9.14" />
11+
<PackageReference Include="OpenTelemetry.Exporter.Console" Version="1.9.0" />
12+
<PackageReference Include="OpenTelemetry.Instrumentation.StackExchangeRedis" Version="1.0.0-rc9.15" />
1313
</ItemGroup>
1414

1515
<ItemGroup>

examples/Example.MinimalApi/Example.MinimalApi.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
</ItemGroup>
1313

1414
<ItemGroup>
15-
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.8.1" />
15+
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.9.0" />
1616
</ItemGroup>
1717

1818
</Project>

examples/Example.WorkerService/Example.WorkerService.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
<ItemGroup>
1111
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
12-
<PackageReference Include="OpenTelemetry.Exporter.Console" Version="1.8.1" />
12+
<PackageReference Include="OpenTelemetry.Exporter.Console" Version="1.9.0" />
1313
</ItemGroup>
1414

1515
<ItemGroup>

examples/ServiceDefaults/ServiceDefaults.csproj

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@
1212

1313
<PackageReference Include="Microsoft.Extensions.Http.Resilience" Version="8.2.0" />
1414
<PackageReference Include="Microsoft.Extensions.ServiceDiscovery" Version="8.0.0-preview.4.24156.9" />
15-
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.8.1" />
16-
<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.8.1" />
17-
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.8.1" />
18-
<PackageReference Include="OpenTelemetry.Instrumentation.GrpcNetClient" Version="1.8.0-beta.1" />
19-
<PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.8.1" />
20-
<PackageReference Include="OpenTelemetry.Instrumentation.Process" Version="0.5.0-beta.5" />
21-
<PackageReference Include="OpenTelemetry.Instrumentation.Runtime" Version="1.8.0" />
15+
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.9.0" />
16+
<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.9.0" />
17+
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.9.0" />
18+
<PackageReference Include="OpenTelemetry.Instrumentation.GrpcNetClient" Version="1.9.0-beta.1" />
19+
<PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.9.0" />
20+
<PackageReference Include="OpenTelemetry.Instrumentation.Process" Version="0.5.0-beta.6" />
21+
<PackageReference Include="OpenTelemetry.Instrumentation.Runtime" Version="1.9.0" />
2222
</ItemGroup>
2323

2424
<ItemGroup>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFrameworks>netstandard2.0;netstandard2.1;net8.0;net6.0;net462</TargetFrameworks>
5+
<TargetFramework>net8.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
<IsPackable>False</IsPackable>
9+
</PropertyGroup>
10+
11+
<ItemGroup>
12+
<ProjectReference Include="..\Elastic.OpenTelemetry\Elastic.OpenTelemetry.csproj" />
13+
</ItemGroup>
14+
15+
<ItemGroup>
16+
<Content Remove="README.md" />
17+
</ItemGroup>
18+
</Project>
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// Licensed to Elasticsearch B.V under one or more agreements.
2+
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
3+
// See the LICENSE file in the project root for more information
4+
5+
using System.Diagnostics.Tracing;
6+
using Elastic.OpenTelemetry.Configuration;
7+
using Elastic.OpenTelemetry.Extensions;
8+
using Microsoft.Extensions.Logging;
9+
using OpenTelemetry.Logs;
10+
using OpenTelemetry.Metrics;
11+
using OpenTelemetry.Resources;
12+
using OpenTelemetry.Trace;
13+
14+
namespace Elastic.OpenTelemetry.AutoInstrumentationPlugin;
15+
16+
/// <summary>
17+
/// Elastic Distribution for OpenTelemetry .NET plugin for Auto Instrumentation.
18+
/// <para>Ensures all signals are rich enough to report to Elastic</para>
19+
/// </summary>
20+
// ReSharper disable once UnusedType.Global
21+
public class ElasticAutoInstrumentationPlugin
22+
{
23+
private readonly ILogger _logger;
24+
private readonly EventListener _eventListener;
25+
26+
/// <inheritdoc cref="ElasticAutoInstrumentationPlugin"/>
27+
public ElasticAutoInstrumentationPlugin()
28+
{
29+
var options = new ElasticOpenTelemetryBuilderOptions();
30+
var (eventListener, logger) = ElasticOpenTelemetryBuilder.Bootstrap(options);
31+
32+
_logger = logger;
33+
_eventListener = eventListener;
34+
}
35+
36+
/// To access TracerProvider right after TracerProviderBuilder.Build() is executed.
37+
public void TracerProviderInitialized(TracerProvider tracerProvider)
38+
{
39+
}
40+
41+
/// To access MeterProvider right after MeterProviderBuilder.Build() is executed.
42+
public void MeterProviderInitialized(MeterProvider meterProvider)
43+
{
44+
}
45+
46+
/// To configure tracing SDK before Auto Instrumentation configured SDK
47+
public TracerProviderBuilder BeforeConfigureTracerProvider(TracerProviderBuilder builder) =>
48+
builder.UseElasticDefaults(_logger);
49+
50+
51+
/// To configure tracing SDK after Auto Instrumentation configured SDK
52+
public TracerProviderBuilder AfterConfigureTracerProvider(TracerProviderBuilder builder) =>
53+
builder;
54+
55+
/// To configure metrics SDK before Auto Instrumentation configured SDK
56+
public MeterProviderBuilder BeforeConfigureMeterProvider(MeterProviderBuilder builder) =>
57+
builder.UseElasticDefaults(_logger);
58+
59+
/// To configure metrics SDK after Auto Instrumentation configured SDK
60+
public MeterProviderBuilder AfterConfigureMeterProvider(MeterProviderBuilder builder) =>
61+
builder;
62+
63+
64+
/// To configure logs SDK (the method name is the same as for other logs options)
65+
public void ConfigureLogsOptions(OpenTelemetryLoggerOptions options) =>
66+
options.UseElasticDefaults(_logger);
67+
68+
/// To configure Resource
69+
public ResourceBuilder ConfigureResource(ResourceBuilder builder) =>
70+
builder.UseElasticDefaults(_logger);
71+
}

src/Elastic.OpenTelemetry/Elastic.OpenTelemetry.csproj

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,14 @@
1818
</PropertyGroup>
1919

2020
<ItemGroup>
21-
<PackageReference Include="OpenTelemetry" Version="1.8.1" />
22-
<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.8.1" />
23-
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.8.1" />
24-
<PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.8.1" />
25-
<PackageReference Include="OpenTelemetry.Instrumentation.GrpcNetClient" Version="1.8.0-beta.1" />
26-
<PackageReference Include="OpenTelemetry.Instrumentation.EntityFrameworkCore" Version="1.0.0-beta.11" />
27-
<PackageReference Include="OpenTelemetry.Instrumentation.Runtime" Version="1.8.0" />
28-
<PackageReference Include="OpenTelemetry.Instrumentation.Process" Version="0.5.0-beta.5" />
21+
<PackageReference Include="OpenTelemetry" Version="1.9.0" />
22+
<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.9.0" />
23+
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.9.0" />
24+
<PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.9.0" />
25+
<PackageReference Include="OpenTelemetry.Instrumentation.GrpcNetClient" Version="1.9.0-beta.1" />
26+
<PackageReference Include="OpenTelemetry.Instrumentation.EntityFrameworkCore" Version="1.0.0-beta.12" />
27+
<PackageReference Include="OpenTelemetry.Instrumentation.Runtime" Version="1.9.0" />
28+
<PackageReference Include="OpenTelemetry.Instrumentation.Process" Version="0.5.0-beta.6" />
2929
<PackageReference Include="Polyfill" Version="4.4.0" PrivateAssets="all" IncludeAssets="runtime; build; native; contentfiles; analyzers; buildtransitive" />
3030
</ItemGroup>
3131

src/Elastic.OpenTelemetry/ElasticOpenTelemetryBuilder.cs

Lines changed: 29 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// See the LICENSE file in the project root for more information
44

55
using System.Diagnostics;
6+
using System.Diagnostics.Tracing;
67
using Elastic.OpenTelemetry.Configuration;
78
using Elastic.OpenTelemetry.Diagnostics;
89
using Elastic.OpenTelemetry.Diagnostics.Logging;
@@ -48,6 +49,23 @@ public class ElasticOpenTelemetryBuilder : IOpenTelemetryBuilder
4849
/// <inheritdoc cref="IOpenTelemetryBuilder.Services"/>
4950
public IServiceCollection Services { get; }
5051

52+
/// <summary>
53+
/// Shared bootstrap routine for the Elastic OpenTelemetry Distribution.
54+
/// Used to ensure auto instrumentation and manual instrumentation bootstrap the same way.
55+
/// </summary>
56+
public static (EventListener, ILogger) Bootstrap(ElasticOpenTelemetryBuilderOptions options)
57+
{
58+
var logger = new CompositeLogger(options);
59+
60+
// Enables logging of OpenTelemetry-SDK event source events
61+
var eventListener = new LoggingEventListener(logger, options.DistroOptions);
62+
63+
logger.LogAgentPreamble();
64+
logger.LogElasticOpenTelemetryBuilderInitialized(Environment.NewLine, new StackTrace(true));
65+
options.DistroOptions.LogConfigSources(logger);
66+
return (eventListener, logger);
67+
}
68+
5169
/// <summary>
5270
/// Creates an instance of the <see cref="ElasticOpenTelemetryBuilder" /> configured with default options.
5371
/// </summary>
@@ -61,14 +79,10 @@ public ElasticOpenTelemetryBuilder()
6179
/// </summary>
6280
public ElasticOpenTelemetryBuilder(ElasticOpenTelemetryBuilderOptions options)
6381
{
64-
Logger = new CompositeLogger(options);
82+
var (eventListener, logger) = Bootstrap(options);
6583

66-
// Enables logging of OpenTelemetry-SDK event source events
67-
EventListener = new LoggingEventListener(Logger, options.DistroOptions);
68-
69-
Logger.LogAgentPreamble();
70-
Logger.LogElasticOpenTelemetryBuilderInitialized(Environment.NewLine, new StackTrace(true));
71-
options.DistroOptions.LogConfigSources(Logger);
84+
Logger = (CompositeLogger)logger;
85+
EventListener = (LoggingEventListener)eventListener;
7286

7387
Services = options.Services ?? new ServiceCollection();
7488

@@ -81,6 +95,9 @@ public ElasticOpenTelemetryBuilder(ElasticOpenTelemetryBuilderOptions options)
8195
var openTelemetry =
8296
Microsoft.Extensions.DependencyInjection.OpenTelemetryServicesExtensions.AddOpenTelemetry(Services);
8397

98+
// We always add this so we can identify a distro is being used, even if all Elastic defaults are disabled.
99+
openTelemetry.ConfigureResource(r => r.UseElasticDefaults());
100+
84101
if (options.DistroOptions.EnabledDefaults.Equals(ElasticOpenTelemetryOptions.EnabledElasticDefaults.None))
85102
{
86103
Logger.LogNoElasticDefaults();
@@ -90,52 +107,23 @@ public ElasticOpenTelemetryBuilder(ElasticOpenTelemetryBuilderOptions options)
90107
return;
91108
}
92109

93-
openTelemetry.ConfigureResource(r => r.AddElasticResourceDefaults(Logger));
110+
openTelemetry.ConfigureResource(r => r.UseElasticDefaults(Logger));
94111

95112
//https://github.com/open-telemetry/opentelemetry-dotnet/pull/5400
96113
if (!options.DistroOptions.SkipOtlpExporter)
97114
openTelemetry.UseOtlpExporter();
98115

99116
if (options.DistroOptions.EnabledDefaults.HasFlag(ElasticOpenTelemetryOptions.EnabledElasticDefaults.Logging))
100117
{
101-
// TODO: Move to WithLogging once it gets stable.
102-
Services.Configure<OpenTelemetryLoggerOptions>(logging =>
103-
{
104-
logging.IncludeFormattedMessage = true;
105-
logging.IncludeScopes = true;
106-
});
107-
108-
// Note: We use this log method for now as the WithLogging method is not yet stable.
109-
Logger.LogConfiguredSignalProvider("logging", nameof(OpenTelemetryLoggerOptions));
118+
//TODO Move to WithLogging once it gets stable
119+
Services.Configure<OpenTelemetryLoggerOptions>(logging => logging.UseElasticDefaults());
110120
}
111121

112122
if (options.DistroOptions.EnabledDefaults.HasFlag(ElasticOpenTelemetryOptions.EnabledElasticDefaults.Tracing))
113-
{
114-
openTelemetry.WithTracing(tracing =>
115-
{
116-
tracing
117-
.AddHttpClientInstrumentation()
118-
.AddGrpcClientInstrumentation()
119-
.AddEntityFrameworkCoreInstrumentation();
120-
121-
tracing.AddElasticProcessors(Logger);
122-
});
123-
124-
Logger.LogConfiguredSignalProvider("tracing", nameof(TracerProviderBuilder));
125-
}
123+
openTelemetry.WithTracing(tracing => tracing.UseElasticDefaults(Logger));
126124

127125
if (options.DistroOptions.EnabledDefaults.HasFlag(ElasticOpenTelemetryOptions.EnabledElasticDefaults.Metrics))
128-
{
129-
openTelemetry.WithMetrics(metrics =>
130-
{
131-
metrics
132-
.AddProcessInstrumentation()
133-
.AddRuntimeInstrumentation()
134-
.AddHttpClientInstrumentation();
135-
136-
Logger.LogConfiguredSignalProvider("metrics", nameof(MeterProviderBuilder));
137-
});
138-
}
126+
openTelemetry.WithMetrics(metrics => metrics.UseElasticDefaults(Logger));
139127
}
140128
}
141129

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Licensed to Elasticsearch B.V under one or more agreements.
2+
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
3+
// See the LICENSE file in the project root for more information
4+
5+
using Microsoft.Extensions.Logging;
6+
using Microsoft.Extensions.Logging.Abstractions;
7+
using OpenTelemetry.Metrics;
8+
9+
namespace Elastic.OpenTelemetry.Extensions;
10+
11+
/// <summary>
12+
/// Elastic extensions for <see cref="MeterProviderBuilder"/>.
13+
/// </summary>
14+
public static class MeterProviderBuilderExtensions
15+
{
16+
/// <summary> Use Elastic distribution defaults for <see cref="MeterProviderBuilder"/> </summary>
17+
public static MeterProviderBuilder UseElasticDefaults(this MeterProviderBuilder builder, ILogger? logger = null)
18+
{
19+
logger ??= NullLogger.Instance;
20+
21+
builder
22+
.AddProcessInstrumentation()
23+
.AddRuntimeInstrumentation()
24+
.AddHttpClientInstrumentation();
25+
26+
logger.LogConfiguredSignalProvider("metrics", nameof(MeterProviderBuilder));
27+
28+
return builder;
29+
}
30+
}

src/Elastic.OpenTelemetry/Extensions/OpenTelemetryBuilderExtensions.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
33
// See the LICENSE file in the project root for more information
44

5+
using Elastic.OpenTelemetry.Diagnostics.Logging;
56
using Microsoft.Extensions.DependencyInjection;
67
using Microsoft.Extensions.Logging;
78
using OpenTelemetry;
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Licensed to Elasticsearch B.V under one or more agreements.
2+
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
3+
// See the LICENSE file in the project root for more information
4+
5+
using Microsoft.Extensions.Logging;
6+
using Microsoft.Extensions.Logging.Abstractions;
7+
using OpenTelemetry.Logs;
8+
9+
namespace Elastic.OpenTelemetry.Extensions;
10+
11+
/// <summary>
12+
/// Elastic extensions for <see cref="OpenTelemetryLoggerOptions"/>.
13+
/// </summary>
14+
public static class OpenTelemetryLoggerOptionsExtensions
15+
{
16+
/// <summary>
17+
/// Ensures Elastic distro options are set for <see cref="OpenTelemetryLoggerOptions"/>
18+
/// </summary>
19+
public static void UseElasticDefaults(this OpenTelemetryLoggerOptions options, ILogger? logger = null)
20+
{
21+
logger ??= NullLogger.Instance;
22+
options.IncludeFormattedMessage = true;
23+
options.IncludeScopes = true;
24+
logger.LogConfiguredSignalProvider("logging", nameof(OpenTelemetryLoggerOptions));
25+
}
26+
}

0 commit comments

Comments
 (0)