diff --git a/eng/Packages.Data.props b/eng/Packages.Data.props
index 787499b26756..f29622214146 100644
--- a/eng/Packages.Data.props
+++ b/eng/Packages.Data.props
@@ -117,6 +117,8 @@
+
+
diff --git a/sdk/monitor/Azure.Monitor.OpenTelemetry/Azure.Monitor.OpenTelemetry.sln b/sdk/monitor/Azure.Monitor.OpenTelemetry/Azure.Monitor.OpenTelemetry.sln
index d51c6475f74b..8fb447278d8e 100644
--- a/sdk/monitor/Azure.Monitor.OpenTelemetry/Azure.Monitor.OpenTelemetry.sln
+++ b/sdk/monitor/Azure.Monitor.OpenTelemetry/Azure.Monitor.OpenTelemetry.sln
@@ -16,6 +16,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Dependent Projects", "Depen
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Azure.Monitor.OpenTelemetry.Exporter", "..\Azure.Monitor.OpenTelemetry.Exporter\src\Azure.Monitor.OpenTelemetry.Exporter.csproj", "{4158B8A7-971D-4A57-B4C8-5077BFD10AE6}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Azure.Monitor.OpenTelemetry.Demo", "tests\Azure.Monitor.OpenTelemetry.Demo\Azure.Monitor.OpenTelemetry.Demo.csproj", "{6F094CAA-F6BB-4A9C-9D1F-1165F0758C99}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -30,6 +32,10 @@ Global
{4158B8A7-971D-4A57-B4C8-5077BFD10AE6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4158B8A7-971D-4A57-B4C8-5077BFD10AE6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4158B8A7-971D-4A57-B4C8-5077BFD10AE6}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6F094CAA-F6BB-4A9C-9D1F-1165F0758C99}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6F094CAA-F6BB-4A9C-9D1F-1165F0758C99}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6F094CAA-F6BB-4A9C-9D1F-1165F0758C99}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6F094CAA-F6BB-4A9C-9D1F-1165F0758C99}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/sdk/monitor/Azure.Monitor.OpenTelemetry/api/Azure.Monitor.OpenTelemetry.netstandard2.0.cs b/sdk/monitor/Azure.Monitor.OpenTelemetry/api/Azure.Monitor.OpenTelemetry.netstandard2.0.cs
new file mode 100644
index 000000000000..fa4004097bad
--- /dev/null
+++ b/sdk/monitor/Azure.Monitor.OpenTelemetry/api/Azure.Monitor.OpenTelemetry.netstandard2.0.cs
@@ -0,0 +1,18 @@
+namespace Azure.Monitor.OpenTelemetry
+{
+ public static partial class AzureMonitorOpenTelemetryExtensions
+ {
+ public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddAzureMonitorOpenTelemetry(this Microsoft.Extensions.DependencyInjection.IServiceCollection services) { throw null; }
+ public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddAzureMonitorOpenTelemetry(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, Azure.Monitor.OpenTelemetry.AzureMonitorOpenTelemetryOptions options) { throw null; }
+ public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddAzureMonitorOpenTelemetry(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Action configureAzureMonitorOpenTelemetry) { throw null; }
+ }
+ public partial class AzureMonitorOpenTelemetryOptions
+ {
+ public AzureMonitorOpenTelemetryOptions() { }
+ public Azure.Monitor.OpenTelemetry.Exporter.AzureMonitorExporterOptions AzureMonitorExporterOptions { get { throw null; } set { } }
+ public string ConnectionString { get { throw null; } set { } }
+ public bool EnableLogs { get { throw null; } set { } }
+ public bool EnableMetrics { get { throw null; } set { } }
+ public bool EnableTraces { get { throw null; } set { } }
+ }
+}
diff --git a/sdk/monitor/Azure.Monitor.OpenTelemetry/src/Azure.Monitor.OpenTelemetry.csproj b/sdk/monitor/Azure.Monitor.OpenTelemetry/src/Azure.Monitor.OpenTelemetry.csproj
index 7ade99189371..99bcb095fca1 100644
--- a/sdk/monitor/Azure.Monitor.OpenTelemetry/src/Azure.Monitor.OpenTelemetry.csproj
+++ b/sdk/monitor/Azure.Monitor.OpenTelemetry/src/Azure.Monitor.OpenTelemetry.csproj
@@ -8,6 +8,11 @@
true
+
+
+
+
+
diff --git a/sdk/monitor/Azure.Monitor.OpenTelemetry/src/AzureMonitorOpenTelemetryExtensions.cs b/sdk/monitor/Azure.Monitor.OpenTelemetry/src/AzureMonitorOpenTelemetryExtensions.cs
new file mode 100644
index 000000000000..7e305b3fe352
--- /dev/null
+++ b/sdk/monitor/Azure.Monitor.OpenTelemetry/src/AzureMonitorOpenTelemetryExtensions.cs
@@ -0,0 +1,47 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using System;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace Azure.Monitor.OpenTelemetry
+{
+ ///
+ /// Extension methods for setting up Azure Monitor OpenTelemetry in an .
+ ///
+ public static class AzureMonitorOpenTelemetryExtensions
+ {
+ ///
+ /// Adds Azure Monitor OpenTelemetry into service collection.
+ ///
+ /// The to add services to.
+ /// The so that additional calls can be chained.
+ public static IServiceCollection AddAzureMonitorOpenTelemetry(this IServiceCollection services)
+ {
+ return services.AddAzureMonitorOpenTelemetry(o => o = new AzureMonitorOpenTelemetryOptions());
+ }
+
+ ///
+ /// Adds Azure Monitor OpenTelemetry into service collection.
+ ///
+ /// The to add services to.
+ /// The instance for configuration.
+ /// The so that additional calls can be chained.
+ public static IServiceCollection AddAzureMonitorOpenTelemetry(this IServiceCollection services, AzureMonitorOpenTelemetryOptions options)
+ {
+ options ??= new AzureMonitorOpenTelemetryOptions();
+ return services.AddAzureMonitorOpenTelemetry(o => o.Clone(options));
+ }
+
+ ///
+ /// Adds Azure Monitor OpenTelemetry into service collection.
+ ///
+ /// .
+ /// Callback action for configuring .
+ /// .
+ public static IServiceCollection AddAzureMonitorOpenTelemetry(this IServiceCollection services, Action configureAzureMonitorOpenTelemetry)
+ {
+ return AzureMonitorOpenTelemetryImplementations.AddAzureMonitorOpenTelemetryWithAction(services, configureAzureMonitorOpenTelemetry);
+ }
+ }
+}
diff --git a/sdk/monitor/Azure.Monitor.OpenTelemetry/src/AzureMonitorOpenTelemetryImplementations.cs b/sdk/monitor/Azure.Monitor.OpenTelemetry/src/AzureMonitorOpenTelemetryImplementations.cs
new file mode 100644
index 000000000000..4b7e894c6ab8
--- /dev/null
+++ b/sdk/monitor/Azure.Monitor.OpenTelemetry/src/AzureMonitorOpenTelemetryImplementations.cs
@@ -0,0 +1,143 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using System;
+using Azure.Monitor.OpenTelemetry.Exporter;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Options;
+using OpenTelemetry.Metrics;
+using OpenTelemetry.Trace;
+
+namespace Azure.Monitor.OpenTelemetry
+{
+ internal class AzureMonitorOpenTelemetryImplementations
+ {
+ internal static IServiceCollection AddAzureMonitorOpenTelemetryWithAction(IServiceCollection services, Action configureAzureMonitorOpenTelemetry)
+ {
+ if (services == null)
+ {
+ throw new ArgumentNullException(nameof(services));
+ }
+
+ if (configureAzureMonitorOpenTelemetry != null)
+ {
+ services.Configure(configureAzureMonitorOpenTelemetry);
+ }
+
+ var builder = services.AddOpenTelemetry();
+
+ builder.WithTracing(b => b
+ .AddAspNetCoreInstrumentation()
+ .AddAzureMonitorTraceExporter());
+
+ builder.WithMetrics(b => b
+ .AddAspNetCoreInstrumentation()
+ .AddAzureMonitorMetricExporter());
+
+ ServiceDescriptor? sdkTracerProviderServiceRegistration = null;
+ ServiceDescriptor? sdkMeterProviderServiceRegistration = null;
+
+ foreach (var service in services)
+ {
+ if (service.ServiceType == typeof(TracerProvider))
+ {
+ sdkTracerProviderServiceRegistration = service;
+ }
+ else if (service.ServiceType == typeof(MeterProvider))
+ {
+ sdkMeterProviderServiceRegistration = service;
+ }
+ }
+
+ if (sdkTracerProviderServiceRegistration?.ImplementationFactory == null ||
+ sdkMeterProviderServiceRegistration?.ImplementationFactory == null)
+ {
+ throw new InvalidOperationException("OpenTelemetry SDK has changed its registration mechanism.");
+ }
+
+ // We looped through the registered services so that we can take over
+ // the SDK registrations.
+
+ services.Remove(sdkTracerProviderServiceRegistration);
+ services.Remove(sdkMeterProviderServiceRegistration);
+
+ // Now we register our own services for TracerProvider & MeterProvider
+ // so that we can return no-op versions when it isn't enabled.
+
+ services.AddSingleton(sp =>
+ {
+ var options = sp.GetRequiredService>().Get("");
+ if (!options.EnableTraces)
+ {
+ return new NoopTracerProvider();
+ }
+ else
+ {
+ SetValueToExporterOptions(sp, options);
+ var sdkProviderWrapper = sp.GetRequiredService();
+ sdkProviderWrapper.SdkTracerProvider = (TracerProvider)sdkTracerProviderServiceRegistration.ImplementationFactory(sp);
+ return sdkProviderWrapper.SdkTracerProvider;
+ }
+ });
+
+ services.AddSingleton(sp =>
+ {
+ var options = sp.GetRequiredService>().Get("");
+ if (!options.EnableMetrics)
+ {
+ return new NoopMeterProvider();
+ }
+ else
+ {
+ SetValueToExporterOptions(sp, options);
+ var sdkProviderWrapper = sp.GetRequiredService();
+ sdkProviderWrapper.SdkMeterProvider = (MeterProvider)sdkMeterProviderServiceRegistration.ImplementationFactory(sp);
+ return sdkProviderWrapper.SdkMeterProvider;
+ }
+ });
+
+ // SdkProviderWrapper is here to make sure the SDK services get properly
+ // shutdown when the service provider is disposed.
+ services.AddSingleton();
+
+ return services;
+ }
+
+ private static void SetValueToExporterOptions(IServiceProvider sp, AzureMonitorOpenTelemetryOptions options)
+ {
+ var exporterOptions = sp.GetRequiredService>().Get("");
+ var defaultOptions = new AzureMonitorExporterOptions();
+
+ if (ReferenceEquals(exporterOptions, defaultOptions))
+ {
+ exporterOptions.ConnectionString = options.AzureMonitorExporterOptions.ConnectionString;
+ exporterOptions.DisableOfflineStorage = options.AzureMonitorExporterOptions.DisableOfflineStorage;
+ exporterOptions.StorageDirectory = options.AzureMonitorExporterOptions.StorageDirectory;
+ }
+ else if (exporterOptions.ConnectionString == null)
+ {
+ exporterOptions.ConnectionString = options.AzureMonitorExporterOptions.ConnectionString;
+ }
+ }
+
+ private sealed class NoopTracerProvider : TracerProvider
+ {
+ }
+
+ private sealed class NoopMeterProvider : MeterProvider
+ {
+ }
+
+ private sealed class SdkProviderWrapper : IDisposable
+ {
+ public TracerProvider? SdkTracerProvider;
+ public MeterProvider? SdkMeterProvider;
+
+ public void Dispose()
+ {
+ this.SdkTracerProvider?.Dispose();
+ this.SdkMeterProvider?.Dispose();
+ }
+ }
+ }
+}
diff --git a/sdk/monitor/Azure.Monitor.OpenTelemetry/src/AzureMonitorOpenTelemetryOptions.cs b/sdk/monitor/Azure.Monitor.OpenTelemetry/src/AzureMonitorOpenTelemetryOptions.cs
new file mode 100644
index 000000000000..25eac898722c
--- /dev/null
+++ b/sdk/monitor/Azure.Monitor.OpenTelemetry/src/AzureMonitorOpenTelemetryOptions.cs
@@ -0,0 +1,68 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+#nullable disable
+
+using System.Runtime.Serialization;
+using Azure.Monitor.OpenTelemetry.Exporter;
+
+namespace Azure.Monitor.OpenTelemetry
+{
+ ///
+ /// Options that allow users to configure the Azure Monitor OpenTelemetry.
+ ///
+ public class AzureMonitorOpenTelemetryOptions
+ {
+ ///
+ /// Gets or sets a value of Azure Monitor Exporter Options.
+ ///
+ public AzureMonitorExporterOptions AzureMonitorExporterOptions { get; set; } = new AzureMonitorExporterOptions();
+
+ ///
+ /// The Connection String provides users with a single configuration setting to identify the Azure Monitor resource and endpoint.
+ ///
+ ///
+ /// (https://docs.microsoft.com/azure/azure-monitor/app/sdk-connection-string).
+ ///
+ public string ConnectionString
+ {
+ get
+ {
+ return AzureMonitorExporterOptions.ConnectionString;
+ }
+ set
+ {
+ AzureMonitorExporterOptions.ConnectionString = value;
+ }
+ }
+
+ ///
+ /// Gets or sets a value indicating whether Logs should be enabled.
+ ///
+ public bool EnableLogs { get; set; } = true;
+
+ ///
+ /// Gets or sets a value indicating whether Metrics should be enabled.
+ ///
+ public bool EnableMetrics { get; set; } = true;
+
+ ///
+ /// Gets or sets a value indicating whether Traces should be enabled.
+ ///
+ public bool EnableTraces { get; set; } = true;
+
+ internal AzureMonitorOpenTelemetryOptions Clone(AzureMonitorOpenTelemetryOptions options)
+ {
+ if (options != null)
+ {
+ AzureMonitorExporterOptions = options.AzureMonitorExporterOptions;
+ ConnectionString = options.ConnectionString;
+ EnableLogs = options.EnableLogs;
+ EnableMetrics = options.EnableMetrics;
+ EnableTraces = options.EnableTraces;
+ }
+
+ return this;
+ }
+ }
+}
diff --git a/sdk/monitor/Azure.Monitor.OpenTelemetry/tests/Azure.Monitor.OpenTelemetry.Demo/Azure.Monitor.OpenTelemetry.Demo.csproj b/sdk/monitor/Azure.Monitor.OpenTelemetry/tests/Azure.Monitor.OpenTelemetry.Demo/Azure.Monitor.OpenTelemetry.Demo.csproj
new file mode 100644
index 000000000000..4422db4c9ccb
--- /dev/null
+++ b/sdk/monitor/Azure.Monitor.OpenTelemetry/tests/Azure.Monitor.OpenTelemetry.Demo/Azure.Monitor.OpenTelemetry.Demo.csproj
@@ -0,0 +1,11 @@
+
+
+
+ $(RequiredTargetFrameworks)
+
+
+
+
+
+
+
diff --git a/sdk/monitor/Azure.Monitor.OpenTelemetry/tests/Azure.Monitor.OpenTelemetry.Demo/Program.cs b/sdk/monitor/Azure.Monitor.OpenTelemetry/tests/Azure.Monitor.OpenTelemetry.Demo/Program.cs
new file mode 100644
index 000000000000..6fc8f8a8f2d6
--- /dev/null
+++ b/sdk/monitor/Azure.Monitor.OpenTelemetry/tests/Azure.Monitor.OpenTelemetry.Demo/Program.cs
@@ -0,0 +1,21 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+#if NET6_0_OR_GREATER
+using System.Diagnostics;
+using Azure.Monitor.OpenTelemetry;
+using Microsoft.AspNetCore.Builder;
+
+var builder = WebApplication.CreateBuilder(args);
+
+// builder.Services.AddAzureMonitorOpenTelemetry();
+builder.Services.AddAzureMonitorOpenTelemetry(o =>
+{
+ o.ConnectionString = "InstrumentationKey=00000000-0000-0000-0000-000000000000";
+});
+
+var app = builder.Build();
+app.MapGet("/", () => $"Hello World! OpenTelemetry Trace: {Activity.Current?.Id}");
+
+app.Run();
+#endif
diff --git a/sdk/monitor/Azure.Monitor.OpenTelemetry/tests/Azure.Monitor.OpenTelemetry.Demo/ProgramNet461Compat.cs b/sdk/monitor/Azure.Monitor.OpenTelemetry/tests/Azure.Monitor.OpenTelemetry.Demo/ProgramNet461Compat.cs
new file mode 100644
index 000000000000..846e70386afe
--- /dev/null
+++ b/sdk/monitor/Azure.Monitor.OpenTelemetry/tests/Azure.Monitor.OpenTelemetry.Demo/ProgramNet461Compat.cs
@@ -0,0 +1,16 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+#if NET461
+
+namespace Azure.Monitor.OpenTelemetry.Demo
+{
+ public partial class Program
+ {
+ public static void Main(string[] args)
+ {
+ }
+ }
+}
+
+#endif