diff --git a/core/Azure.Mcp.Core/tests/Azure.Mcp.Core.UnitTests/Areas/Server/Commands/ServiceCollectionExtensionsSerializedTests.cs b/core/Azure.Mcp.Core/tests/Azure.Mcp.Core.UnitTests/Areas/Server/Commands/ServiceCollectionExtensionsSerializedTests.cs index a592650e83..055ab07cb7 100644 --- a/core/Azure.Mcp.Core/tests/Azure.Mcp.Core.UnitTests/Areas/Server/Commands/ServiceCollectionExtensionsSerializedTests.cs +++ b/core/Azure.Mcp.Core/tests/Azure.Mcp.Core.UnitTests/Areas/Server/Commands/ServiceCollectionExtensionsSerializedTests.cs @@ -33,7 +33,7 @@ public void InitializeConfigurationAndOptions_Defaults() var services = SetupBaseServices(); // Act - ServiceCollectionExtensions.InitializeConfigurationAndOptions(services); + ServiceCollectionExtensions.InitializeConfigurationOptionsAndOpenTelemetry(services); // Assert var provider = services.BuildServiceProvider(); @@ -64,7 +64,7 @@ public void InitializeConfigurationAndOptions_HttpTransport() var services = SetupBaseServices().AddSingleton(Options.Create(serviceStartOptions)); // Act - ServiceCollectionExtensions.InitializeConfigurationAndOptions(services); + ServiceCollectionExtensions.InitializeConfigurationOptionsAndOpenTelemetry(services); var provider = services.BuildServiceProvider(); // Assert @@ -88,7 +88,7 @@ public void InitializeConfigurationAndOptions_Stdio() // Act Environment.SetEnvironmentVariable("AZURE_MCP_COLLECT_TELEMETRY", "false"); - ServiceCollectionExtensions.InitializeConfigurationAndOptions(services); + ServiceCollectionExtensions.InitializeConfigurationOptionsAndOpenTelemetry(services); var provider = services.BuildServiceProvider(); // Assert @@ -121,7 +121,7 @@ public void InitializeConfigurationAndOptions_WithSupportLoggingFolder_DisablesT // Act Environment.SetEnvironmentVariable("AZURE_MCP_COLLECT_TELEMETRY", null); - ServiceCollectionExtensions.InitializeConfigurationAndOptions(services); + ServiceCollectionExtensions.InitializeConfigurationOptionsAndOpenTelemetry(services); var provider = services.BuildServiceProvider(); // Assert @@ -145,7 +145,7 @@ public void InitializeConfigurationAndOptions_WithSupportLoggingFolderAndEnvVarT // Act Environment.SetEnvironmentVariable("AZURE_MCP_COLLECT_TELEMETRY", "true"); - ServiceCollectionExtensions.InitializeConfigurationAndOptions(services); + ServiceCollectionExtensions.InitializeConfigurationOptionsAndOpenTelemetry(services); var provider = services.BuildServiceProvider(); // Assert @@ -171,7 +171,7 @@ public void InitializeConfigurationAndOptions_WithEmptyOrWhitespaceSupportLoggin // Act Environment.SetEnvironmentVariable("AZURE_MCP_COLLECT_TELEMETRY", null); - ServiceCollectionExtensions.InitializeConfigurationAndOptions(services); + ServiceCollectionExtensions.InitializeConfigurationOptionsAndOpenTelemetry(services); var provider = services.BuildServiceProvider(); // Assert diff --git a/core/Azure.Mcp.Core/tests/Azure.Mcp.Core.UnitTests/Extensions/OpenTelemetryExtensionsTests.cs b/core/Azure.Mcp.Core/tests/Azure.Mcp.Core.UnitTests/Extensions/OpenTelemetryExtensionsTests.cs index 1b9a6d37ad..52f0448216 100644 --- a/core/Azure.Mcp.Core/tests/Azure.Mcp.Core.UnitTests/Extensions/OpenTelemetryExtensionsTests.cs +++ b/core/Azure.Mcp.Core/tests/Azure.Mcp.Core.UnitTests/Extensions/OpenTelemetryExtensionsTests.cs @@ -2,8 +2,10 @@ // Licensed under the MIT License. using Azure.Mcp.Core.Extensions; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Mcp.Core.Services.Telemetry; +using NSubstitute; using Xunit; namespace Azure.Mcp.Core.UnitTests.Extensions; @@ -24,7 +26,7 @@ public void ConfigureOpenTelemetry_RegistersTelemetryService() var services = new ServiceCollection(); // Act - services.ConfigureOpenTelemetry(); + services.ConfigureOpenTelemetry(Substitute.For()); // Assert - Verify that the telemetry service descriptor is registered Assert.Contains(services, sd => sd.ServiceType == typeof(ITelemetryService)); diff --git a/core/Microsoft.Mcp.Core/src/Areas/Server/Commands/ServiceCollectionExtensions.cs b/core/Microsoft.Mcp.Core/src/Areas/Server/Commands/ServiceCollectionExtensions.cs index a9f9cfcd74..fae9a5c4cd 100644 --- a/core/Microsoft.Mcp.Core/src/Areas/Server/Commands/ServiceCollectionExtensions.cs +++ b/core/Microsoft.Mcp.Core/src/Areas/Server/Commands/ServiceCollectionExtensions.cs @@ -248,9 +248,13 @@ public static IServiceCollection AddAzureMcpServer(this IServiceCollection servi /// Using configures . /// /// Service Collection to add configuration logic to. - public static void InitializeConfigurationAndOptions(this IServiceCollection services) + public static void InitializeConfigurationOptionsAndOpenTelemetry(this IServiceCollection services) { +#if DEBUG + var environment = Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT") ?? "Development"; +#else var environment = Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT") ?? "Production"; +#endif var configuration = new ConfigurationBuilder() .AddJsonFile("appsettings.json", optional: false) .AddJsonFile($"appsettings.{environment}.json", optional: true) @@ -272,11 +276,8 @@ public static void InitializeConfigurationAndOptions(this IServiceCollection ser // Assembly.GetEntryAssembly is used to retrieve the version of the server application as that is // the assembly that will run the tool calls. - var entryAssembly = Assembly.GetEntryAssembly(); - if (entryAssembly == null) - { - throw new InvalidOperationException("Entry assembly must be a managed assembly."); - } + var entryAssembly = Assembly.GetEntryAssembly() + ?? throw new InvalidOperationException("Entry assembly must be a managed assembly."); options.Version = AssemblyHelper.GetAssemblyVersion(entryAssembly); @@ -293,5 +294,7 @@ public static void InitializeConfigurationAndOptions(this IServiceCollection ser // over any other settings. options.IsTelemetryEnabled = rootConfiguration.GetValue("AZURE_MCP_COLLECT_TELEMETRY", true); }); + + services.ConfigureOpenTelemetry(configuration); } } diff --git a/core/Microsoft.Mcp.Core/src/Extensions/OpenTelemetryExtensions.cs b/core/Microsoft.Mcp.Core/src/Extensions/OpenTelemetryExtensions.cs index dd0f7aa524..a93da203a4 100644 --- a/core/Microsoft.Mcp.Core/src/Extensions/OpenTelemetryExtensions.cs +++ b/core/Microsoft.Mcp.Core/src/Extensions/OpenTelemetryExtensions.cs @@ -5,6 +5,7 @@ using System.Runtime.InteropServices; using Azure.Monitor.OpenTelemetry.Exporter; using Microsoft.Extensions.Azure; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; @@ -25,7 +26,7 @@ public static class OpenTelemetryExtensions /// private const string MicrosoftOwnedAppInsightsConnectionString = "InstrumentationKey=21e003c0-efee-4d3f-8a98-1868515aa2c9;IngestionEndpoint=https://centralus-2.in.applicationinsights.azure.com/;LiveEndpoint=https://centralus.livediagnostics.monitor.azure.com/;ApplicationId=f14f6a2d-6405-4f88-bd58-056f25fe274f"; - public static void ConfigureOpenTelemetry(this IServiceCollection services) + public static void ConfigureOpenTelemetry(this IServiceCollection services, IConfiguration configuration) { services.AddSingleton(); @@ -46,10 +47,10 @@ public static void ConfigureOpenTelemetry(this IServiceCollection services) services.AddSingleton(); } - EnableAzureMonitor(services); + EnableAzureMonitor(services, configuration); } - private static void EnableAzureMonitor(this IServiceCollection services) + private static void EnableAzureMonitor(this IServiceCollection services, IConfiguration configuration) { #if DEBUG services.AddSingleton(sp => @@ -80,7 +81,7 @@ private static void EnableAzureMonitor(this IServiceCollection services) .AddTelemetrySdk(); }); - var userProvidedAppInsightsConnectionString = Environment.GetEnvironmentVariable("APPLICATIONINSIGHTS_CONNECTION_STRING"); + var userProvidedAppInsightsConnectionString = configuration["APPLICATIONINSIGHTS_CONNECTION_STRING"]; if (!string.IsNullOrWhiteSpace(userProvidedAppInsightsConnectionString)) { @@ -92,7 +93,7 @@ private static void EnableAzureMonitor(this IServiceCollection services) #if RELEASE // This environment variable can be used to disable Microsoft telemetry collection. // By default, Microsoft telemetry is enabled. - var microsoftTelemetry = Environment.GetEnvironmentVariable("AZURE_MCP_COLLECT_TELEMETRY_MICROSOFT"); + var microsoftTelemetry = configuration["AZURE_MCP_COLLECT_TELEMETRY_MICROSOFT"]; bool shouldCollectMicrosoftTelemetry = string.IsNullOrWhiteSpace(microsoftTelemetry) || (bool.TryParse(microsoftTelemetry, out var shouldCollect) && shouldCollect); @@ -102,7 +103,7 @@ private static void EnableAzureMonitor(this IServiceCollection services) } #endif - var enableOtlp = Environment.GetEnvironmentVariable("AZURE_MCP_ENABLE_OTLP_EXPORTER"); + var enableOtlp = configuration["AZURE_MCP_ENABLE_OTLP_EXPORTER"]; if (!string.IsNullOrEmpty(enableOtlp) && bool.TryParse(enableOtlp, out var shouldEnable) && shouldEnable) { otelBuilder.WithTracing(tracing => tracing.AddOtlpExporter()) diff --git a/servers/Azure.Mcp.Server/src/Program.cs b/servers/Azure.Mcp.Server/src/Program.cs index d6d36ea515..44876da106 100644 --- a/servers/Azure.Mcp.Server/src/Program.cs +++ b/servers/Azure.Mcp.Server/src/Program.cs @@ -211,8 +211,7 @@ internal static void ConfigureServices(IServiceCollection services) { var thisAssembly = typeof(Program).Assembly; - services.InitializeConfigurationAndOptions(); - services.ConfigureOpenTelemetry(); + services.InitializeConfigurationOptionsAndOpenTelemetry(); services.AddMemoryCache(); services.AddSingleton(); diff --git a/servers/Azure.Mcp.Server/src/appsettings.Development.json b/servers/Azure.Mcp.Server/src/appsettings.Development.json index e880ced716..23c0cd8761 100644 --- a/servers/Azure.Mcp.Server/src/appsettings.Development.json +++ b/servers/Azure.Mcp.Server/src/appsettings.Development.json @@ -1,8 +1,8 @@ { - // Generally, AZURE_MCP_COLLECT_TELEMETRY will be set as an environment variable. - // For Development purposes, we never want to publish telemetry so it is explicitly - // set here. - "AZURE_MCP_COLLECT_TELEMETRY": "false", + // Disable AZURE_MCP_COLLECT_TELEMETRY_MICROSOFT to prevent development telemetry from being collected by Microsoft + // instrumentation. This is to avoid polluting production telemetry with development data. + "AZURE_MCP_COLLECT_TELEMETRY_MICROSOFT": "false", + "AZURE_MCP_ENABLE_OTLP_EXPORTER": "true", "Logging": { "LogLevel": { "Default": "Debug", diff --git a/servers/Fabric.Mcp.Server/src/Program.cs b/servers/Fabric.Mcp.Server/src/Program.cs index 1e74889300..6c54075862 100644 --- a/servers/Fabric.Mcp.Server/src/Program.cs +++ b/servers/Fabric.Mcp.Server/src/Program.cs @@ -139,8 +139,7 @@ private static void WriteResponse(CommandResponse response) /// A service collection. internal static void ConfigureServices(IServiceCollection services) { - services.InitializeConfigurationAndOptions(); - services.ConfigureOpenTelemetry(); + services.InitializeConfigurationOptionsAndOpenTelemetry(); services.AddMemoryCache(); services.AddSingleton(); diff --git a/servers/Template.Mcp.Server/src/Program.cs b/servers/Template.Mcp.Server/src/Program.cs index aff1aab000..26d779f75c 100644 --- a/servers/Template.Mcp.Server/src/Program.cs +++ b/servers/Template.Mcp.Server/src/Program.cs @@ -135,8 +135,7 @@ private static void WriteResponse(CommandResponse response) /// A service collection. internal static void ConfigureServices(IServiceCollection services) { - services.InitializeConfigurationAndOptions(); - services.ConfigureOpenTelemetry(); + services.InitializeConfigurationOptionsAndOpenTelemetry(); services.AddMemoryCache(); services.AddSingleton();