diff --git a/CHANGELOG.md b/CHANGELOG.md index 9aaff3a6e..f75ae5309 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ This component adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.h - Support for .NET9. - Support for [RabbitMQ.Client](https://www.nuget.org/packages/RabbitMQ.Client/) traces instrumentation for versions `7.0.0`+. +- Support for SqlClient metrics. ### Changed diff --git a/docs/config.md b/docs/config.md index 3bf904fe5..19e352cfc 100644 --- a/docs/config.md +++ b/docs/config.md @@ -181,18 +181,25 @@ due to lack of stable semantic convention. Metrics are stable, but particular instrumentation are in Experimental status due to lack of stable semantic convention. -| ID | Instrumented library | Documentation | Supported versions | Instrumentation type | Status | -|---------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------|----------------------|-----------------------------------------------------------------------------------------------------------------------------------| -| `ASPNET` | ASP.NET Framework \[1\] **Not supported on .NET** | [ASP.NET metrics](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/Instrumentation.AspNet-1.9.0-beta.1/src/OpenTelemetry.Instrumentation.AspNet/README.md#list-of-metrics-produced) | * | source & bytecode | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) | -| `ASPNETCORE` | ASP.NET Core **Not supported on .NET Framework** | [ASP.NET Core metrics](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/Instrumentation.AspNetCore-1.10.0/src/OpenTelemetry.Instrumentation.AspNetCore/README.md#list-of-metrics-produced) | * | source | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) | -| `HTTPCLIENT` | [System.Net.Http.HttpClient](https://docs.microsoft.com/dotnet/api/system.net.http.httpclient) and [System.Net.HttpWebRequest](https://docs.microsoft.com/dotnet/api/system.net.httpwebrequest) | [HttpClient metrics](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/Instrumentation.Http-1.10.0/src/OpenTelemetry.Instrumentation.Http/README.md#list-of-metrics-produced) | * | source | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) | -| `NETRUNTIME` | [OpenTelemetry.Instrumentation.Runtime](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Runtime) | [Runtime metrics](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/Instrumentation.Runtime-1.10.0/src/OpenTelemetry.Instrumentation.Runtime/README.md#metrics) | * | source | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) | -| `PROCESS` | [OpenTelemetry.Instrumentation.Process](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Process) | [Process metrics](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/Instrumentation.Process-1.10.0-beta.1/src/OpenTelemetry.Instrumentation.Process/README.md#metrics) | * | source | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) | -| `NSERVICEBUS` | [NServiceBus](https://www.nuget.org/packages/NServiceBus) | [NServiceBus metrics](https://docs.particular.net/samples/open-telemetry/prometheus-grafana/#reporting-metric-values) | ≥8.0.0 & < 10.0.0 | source & bytecode | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) | +| ID | Instrumented library | Documentation | Supported versions | Instrumentation type | Status | +|---------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------|----------------------|-----------------------------------------------------------------------------------------------------------------------------------| +| `ASPNET` | ASP.NET Framework \[1\] **Not supported on .NET** | [ASP.NET metrics](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/Instrumentation.AspNet-1.9.0-beta.1/src/OpenTelemetry.Instrumentation.AspNet/README.md#list-of-metrics-produced) | * | source & bytecode | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) | +| `ASPNETCORE` | ASP.NET Core **Not supported on .NET Framework** | [ASP.NET Core metrics](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/Instrumentation.AspNetCore-1.10.0/src/OpenTelemetry.Instrumentation.AspNetCore/README.md#list-of-metrics-produced) | * | source | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) | +| `HTTPCLIENT` | [System.Net.Http.HttpClient](https://docs.microsoft.com/dotnet/api/system.net.http.httpclient) and [System.Net.HttpWebRequest](https://docs.microsoft.com/dotnet/api/system.net.httpwebrequest) | [HttpClient metrics](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/Instrumentation.Http-1.10.0/src/OpenTelemetry.Instrumentation.Http/README.md#list-of-metrics-produced) | * | source | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) | +| `NETRUNTIME` | [OpenTelemetry.Instrumentation.Runtime](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Runtime) | [Runtime metrics](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/Instrumentation.Runtime-1.10.0/src/OpenTelemetry.Instrumentation.Runtime/README.md#metrics) | * | source | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) | +| `NSERVICEBUS` | [NServiceBus](https://www.nuget.org/packages/NServiceBus) | [NServiceBus metrics](https://docs.particular.net/samples/open-telemetry/prometheus-grafana/#reporting-metric-values) | ≥8.0.0 & < 10.0.0 | source & bytecode | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) | +| `PROCESS` | [OpenTelemetry.Instrumentation.Process](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.Process) | [Process metrics](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/Instrumentation.Process-1.10.0-beta.1/src/OpenTelemetry.Instrumentation.Process/README.md#metrics) | * | source | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) | +| `SQLCLIENT` | [Microsoft.Data.SqlClient](https://www.nuget.org/packages/Microsoft.Data.SqlClient), [System.Data.SqlClient](https://www.nuget.org/packages/System.Data.SqlClient) \[2\] and `System.Data` (shipped with .NET Framework) | [SqlClient metrics](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/releases/tag/Instrumentation.SqlClient-1.10.0-beta.1) | * \[3\] | source | [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md) | \[1\]: The ASP.NET metrics are generated only if the `AspNet` trace instrumentation is also enabled. +\[2\]: `System.Data.SqlClient` is [deprecated](https://www.nuget.org/packages/System.Data.SqlClient/4.9.0#readme-body-tab). + +\[3\]: `Microsoft.Data.SqlClient` v3.* is not supported on .NET Framework, + due to [issue](https://github.com/open-telemetry/opentelemetry-dotnet/issues/4243). + `System.Data.SqlClient` is supported from version 4.8.5. + ### Logs instrumentations **Status**: [Experimental](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/versioning-and-stability.md). diff --git a/src/OpenTelemetry.AutoInstrumentation/Configurations/DelayedInitialization.cs b/src/OpenTelemetry.AutoInstrumentation/Configurations/DelayedInitialization.cs index 931a94b00..c026b8c1b 100644 --- a/src/OpenTelemetry.AutoInstrumentation/Configurations/DelayedInitialization.cs +++ b/src/OpenTelemetry.AutoInstrumentation/Configurations/DelayedInitialization.cs @@ -43,7 +43,7 @@ internal static class DelayedInitialization [MethodImpl(MethodImplOptions.NoInlining)] public static void AddSqlClient(LazyInstrumentationLoader lazyInstrumentationLoader, PluginManager pluginManager, TracerSettings tracerSettings) { - new SqlClientInitializer(lazyInstrumentationLoader, pluginManager, tracerSettings); + new SqlClientTracerInitializer(lazyInstrumentationLoader, pluginManager, tracerSettings); } #if NET @@ -89,5 +89,11 @@ internal static class DelayedInitialization { new HttpClientMetricsInitializer(lazyInstrumentationLoader); } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void AddSqlClient(LazyInstrumentationLoader lazyInstrumentationLoader, PluginManager pluginManager) + { + new SqlClientMetricsInitializer(lazyInstrumentationLoader, pluginManager); + } } } diff --git a/src/OpenTelemetry.AutoInstrumentation/Configurations/EnvironmentConfigurationMetricHelper.cs b/src/OpenTelemetry.AutoInstrumentation/Configurations/EnvironmentConfigurationMetricHelper.cs index 0199f7bc9..338f7eaf8 100644 --- a/src/OpenTelemetry.AutoInstrumentation/Configurations/EnvironmentConfigurationMetricHelper.cs +++ b/src/OpenTelemetry.AutoInstrumentation/Configurations/EnvironmentConfigurationMetricHelper.cs @@ -44,6 +44,7 @@ internal static class EnvironmentConfigurationMetricHelper .AddMeter("Microsoft.AspNetCore.Diagnostics") .AddMeter("Microsoft.AspNetCore.RateLimiting"), #endif + MetricInstrumentation.SqlClient => Wrappers.AddSqlClientInstrumentation(builder, lazyInstrumentationLoader, pluginManager), _ => null, }; } @@ -115,6 +116,13 @@ internal static class EnvironmentConfigurationMetricHelper return builder.AddProcessInstrumentation(); } + [MethodImpl(MethodImplOptions.NoInlining)] + public static MeterProviderBuilder AddSqlClientInstrumentation(MeterProviderBuilder builder, LazyInstrumentationLoader lazyInstrumentationLoader, PluginManager pluginManager) + { + DelayedInitialization.Metrics.AddSqlClient(lazyInstrumentationLoader, pluginManager); + return builder.AddMeter("OpenTelemetry.Instrumentation.SqlClient"); + } + // Exporters [MethodImpl(MethodImplOptions.NoInlining)] diff --git a/src/OpenTelemetry.AutoInstrumentation/Configurations/MetricInstrumentation.cs b/src/OpenTelemetry.AutoInstrumentation/Configurations/MetricInstrumentation.cs index cfb66f4b5..8d9ecc513 100644 --- a/src/OpenTelemetry.AutoInstrumentation/Configurations/MetricInstrumentation.cs +++ b/src/OpenTelemetry.AutoInstrumentation/Configurations/MetricInstrumentation.cs @@ -39,6 +39,11 @@ internal enum MetricInstrumentation /// /// ASP.NET Core instrumentation. /// - AspNetCore = 6 + AspNetCore = 6, #endif + + /// + /// SqlClient instrumentation. + /// + SqlClient = 7 } diff --git a/src/OpenTelemetry.AutoInstrumentation/Instrumentation.cs b/src/OpenTelemetry.AutoInstrumentation/Instrumentation.cs index 74ad28e3a..b1973df75 100644 --- a/src/OpenTelemetry.AutoInstrumentation/Instrumentation.cs +++ b/src/OpenTelemetry.AutoInstrumentation/Instrumentation.cs @@ -296,6 +296,9 @@ internal static class Instrumentation break; case MetricInstrumentation.NServiceBus: break; + case MetricInstrumentation.SqlClient: + DelayedInitialization.Metrics.AddSqlClient(lazyInstrumentationLoader, pluginManager); + break; default: Logger.Warning($"Configured metric instrumentation type is not supported: {instrumentation}"); if (FailFastSettings.Value.FailFast) diff --git a/src/OpenTelemetry.AutoInstrumentation/Loading/Initializers/SqlClientInitializer.cs b/src/OpenTelemetry.AutoInstrumentation/Loading/Initializers/SqlClientInitializer.cs index 887b4fe87..b25e5ec2f 100644 --- a/src/OpenTelemetry.AutoInstrumentation/Loading/Initializers/SqlClientInitializer.cs +++ b/src/OpenTelemetry.AutoInstrumentation/Loading/Initializers/SqlClientInitializer.cs @@ -1,23 +1,12 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -using System.Reflection; -using OpenTelemetry.AutoInstrumentation.Configurations; -using OpenTelemetry.AutoInstrumentation.Plugins; - namespace OpenTelemetry.AutoInstrumentation.Loading.Initializers; -internal class SqlClientInitializer +internal abstract class SqlClientInitializer { - private readonly PluginManager _pluginManager; - private readonly TracerSettings _tracerSettings; - - private int _initialized; - - public SqlClientInitializer(LazyInstrumentationLoader lazyInstrumentationLoader, PluginManager pluginManager, TracerSettings tracerSettings) + protected SqlClientInitializer(LazyInstrumentationLoader lazyInstrumentationLoader) { - _pluginManager = pluginManager; - _tracerSettings = tracerSettings; lazyInstrumentationLoader.Add(new GenericInitializer("System.Data.SqlClient", InitializeOnFirstCall)); lazyInstrumentationLoader.Add(new GenericInitializer("Microsoft.Data.SqlClient", InitializeOnFirstCall)); @@ -26,30 +15,5 @@ internal class SqlClientInitializer #endif } - private void InitializeOnFirstCall(ILifespanManager lifespanManager) - { - if (Interlocked.Exchange(ref _initialized, value: 1) != default) - { - // InitializeOnFirstCall() was already called before - return; - } - - var instrumentationType = Type.GetType("OpenTelemetry.Instrumentation.SqlClient.SqlClientInstrumentation, OpenTelemetry.Instrumentation.SqlClient")!; - - var options = new OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions - { - SetDbStatementForText = _tracerSettings.InstrumentationOptions.SqlClientSetDbStatementForText - }; - _pluginManager.ConfigureTracesOptions(options); - - var propertyInfo = instrumentationType.GetProperty("TracingOptions", BindingFlags.Static | BindingFlags.Public); - propertyInfo?.SetValue(null, options); - - var instrumentation = instrumentationType.InvokeMember("AddTracingHandle", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, Type.DefaultBinder, null, []); - - if (instrumentation != null) - { - lifespanManager.Track(instrumentation); - } - } + protected abstract void InitializeOnFirstCall(ILifespanManager lifespanManager); } diff --git a/src/OpenTelemetry.AutoInstrumentation/Loading/Initializers/SqlClientMetricsInitializer.cs b/src/OpenTelemetry.AutoInstrumentation/Loading/Initializers/SqlClientMetricsInitializer.cs new file mode 100644 index 000000000..73514c6d3 --- /dev/null +++ b/src/OpenTelemetry.AutoInstrumentation/Loading/Initializers/SqlClientMetricsInitializer.cs @@ -0,0 +1,37 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Reflection; +using OpenTelemetry.AutoInstrumentation.Plugins; + +namespace OpenTelemetry.AutoInstrumentation.Loading.Initializers; + +internal sealed class SqlClientMetricsInitializer : SqlClientInitializer +{ + private readonly PluginManager _pluginManager; + + private int _initialized; + + public SqlClientMetricsInitializer(LazyInstrumentationLoader lazyInstrumentationLoader, PluginManager pluginManager) + : base(lazyInstrumentationLoader) + { + _pluginManager = pluginManager; + } + + protected override void InitializeOnFirstCall(ILifespanManager lifespanManager) + { + if (Interlocked.Exchange(ref _initialized, value: 1) != default) + { + // InitializeOnFirstCall() was already called before + return; + } + + var instrumentationType = Type.GetType("OpenTelemetry.Instrumentation.SqlClient.SqlClientInstrumentation, OpenTelemetry.Instrumentation.SqlClient")!; + var instrumentation = instrumentationType.InvokeMember("AddMetricHandle", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, Type.DefaultBinder, null, []); + + if (instrumentation != null) + { + lifespanManager.Track(instrumentation); + } + } +} diff --git a/src/OpenTelemetry.AutoInstrumentation/Loading/Initializers/SqlClientTracerInitializer.cs b/src/OpenTelemetry.AutoInstrumentation/Loading/Initializers/SqlClientTracerInitializer.cs new file mode 100644 index 000000000..24578c81c --- /dev/null +++ b/src/OpenTelemetry.AutoInstrumentation/Loading/Initializers/SqlClientTracerInitializer.cs @@ -0,0 +1,50 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using System.Reflection; +using OpenTelemetry.AutoInstrumentation.Configurations; +using OpenTelemetry.AutoInstrumentation.Plugins; + +namespace OpenTelemetry.AutoInstrumentation.Loading.Initializers; + +internal sealed class SqlClientTracerInitializer : SqlClientInitializer +{ + private readonly PluginManager _pluginManager; + private readonly TracerSettings _tracerSettings; + + private int _initialized; + + public SqlClientTracerInitializer(LazyInstrumentationLoader lazyInstrumentationLoader, PluginManager pluginManager, TracerSettings tracerSettings) + : base(lazyInstrumentationLoader) + { + _pluginManager = pluginManager; + _tracerSettings = tracerSettings; + } + + protected override void InitializeOnFirstCall(ILifespanManager lifespanManager) + { + if (Interlocked.Exchange(ref _initialized, value: 1) != default) + { + // InitializeOnFirstCall() was already called before + return; + } + + var instrumentationType = Type.GetType("OpenTelemetry.Instrumentation.SqlClient.SqlClientInstrumentation, OpenTelemetry.Instrumentation.SqlClient")!; + + var options = new OpenTelemetry.Instrumentation.SqlClient.SqlClientTraceInstrumentationOptions + { + SetDbStatementForText = _tracerSettings.InstrumentationOptions.SqlClientSetDbStatementForText + }; + _pluginManager.ConfigureTracesOptions(options); + + var propertyInfo = instrumentationType.GetProperty("TracingOptions", BindingFlags.Static | BindingFlags.Public); + propertyInfo?.SetValue(null, options); + + var instrumentation = instrumentationType.InvokeMember("AddTracingHandle", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, Type.DefaultBinder, null, []); + + if (instrumentation != null) + { + lifespanManager.Track(instrumentation); + } + } +} diff --git a/test/IntegrationTests/SqlClientMicrosoftTests.cs b/test/IntegrationTests/SqlClientMicrosoftTests.cs index 01c662c41..1bef83782 100644 --- a/test/IntegrationTests/SqlClientMicrosoftTests.cs +++ b/test/IntegrationTests/SqlClientMicrosoftTests.cs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 using IntegrationTests.Helpers; +using OpenTelemetry.AutoInstrumentation.Configurations; using Xunit.Abstractions; namespace IntegrationTests; @@ -38,4 +39,38 @@ public class SqlClientMicrosoftTests : TestHelper collector.AssertExpectations(); } + + [SkippableTheory] + [Trait("Category", "EndToEnd")] + [Trait("Containers", "Linux")] + [MemberData(nameof(LibraryVersion.SqlClientMicrosoft), MemberType = typeof(LibraryVersion))] + public void SubmitMetrics(string packageVersion) + { + // Skip the test if fixture does not support current platform + _sqlServerFixture.SkipIfUnsupportedPlatform(); + + using var collector = new MockMetricsCollector(Output); + SetExporter(collector); + + collector.Expect("OpenTelemetry.Instrumentation.SqlClient"); + + SetEnvironmentVariable("LONG_RUNNING", "true"); + SetEnvironmentVariable("OTEL_METRIC_EXPORT_INTERVAL", "100"); + SetEnvironmentVariable(ConfigurationKeys.Traces.TracesEnabled, bool.FalseString); // make sure that traces instrumentation is not needed + + using var process = StartTestApplication(new TestSettings + { + Arguments = $"{_sqlServerFixture.Password} {_sqlServerFixture.Port}", + PackageVersion = packageVersion + }); + + try + { + collector.AssertExpectations(); + } + finally + { + process?.Kill(); + } + } } diff --git a/test/IntegrationTests/SqlClientSystemDataTests.cs b/test/IntegrationTests/SqlClientSystemDataTests.cs index b3e9f6335..5b98a9982 100644 --- a/test/IntegrationTests/SqlClientSystemDataTests.cs +++ b/test/IntegrationTests/SqlClientSystemDataTests.cs @@ -3,7 +3,7 @@ #if NETFRAMEWORK using IntegrationTests.Helpers; -using Xunit; +using OpenTelemetry.AutoInstrumentation.Configurations; using Xunit.Abstractions; namespace IntegrationTests; @@ -27,5 +27,30 @@ public class SqlClientSystemDataTests : TestHelper collector.AssertExpectations(); } + + [Fact] + [Trait("Category", "EndToEnd")] + public void SubmitMetrics() + { + using var collector = new MockMetricsCollector(Output); + SetExporter(collector); + + collector.Expect("OpenTelemetry.Instrumentation.SqlClient"); + + SetEnvironmentVariable("LONG_RUNNING", "true"); + SetEnvironmentVariable("OTEL_METRIC_EXPORT_INTERVAL", "100"); + SetEnvironmentVariable(ConfigurationKeys.Traces.TracesEnabled, bool.FalseString); // make sure that traces instrumentation is not needed + + using var process = StartTestApplication(); + + try + { + collector.AssertExpectations(); + } + finally + { + process?.Kill(); + } + } } #endif diff --git a/test/IntegrationTests/SqlClientSystemTests.cs b/test/IntegrationTests/SqlClientSystemTests.cs index 983792efa..c3ce5a88d 100644 --- a/test/IntegrationTests/SqlClientSystemTests.cs +++ b/test/IntegrationTests/SqlClientSystemTests.cs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 using IntegrationTests.Helpers; +using OpenTelemetry.AutoInstrumentation.Configurations; using Xunit.Abstractions; namespace IntegrationTests; @@ -62,4 +63,38 @@ public class SqlClientSystemTests : TestHelper collector.AssertExpectations(); } + + [SkippableTheory] + [Trait("Category", "EndToEnd")] + [Trait("Containers", "Linux")] + [MemberData(nameof(LibraryVersion.SqlClientSystem), MemberType = typeof(LibraryVersion))] + public void SubmitMetrics(string packageVersion) + { + // Skip the test if fixture does not support current platform + _sqlServerFixture.SkipIfUnsupportedPlatform(); + + using var collector = new MockMetricsCollector(Output); + SetExporter(collector); + + collector.Expect("OpenTelemetry.Instrumentation.SqlClient"); + + SetEnvironmentVariable("LONG_RUNNING", "true"); + SetEnvironmentVariable("OTEL_METRIC_EXPORT_INTERVAL", "100"); + SetEnvironmentVariable(ConfigurationKeys.Traces.TracesEnabled, bool.FalseString); // make sure that traces instrumentation is not needed + + using var process = StartTestApplication(new TestSettings + { + Arguments = $"{_sqlServerFixture.Password} {_sqlServerFixture.Port}", + PackageVersion = packageVersion + }); + + try + { + collector.AssertExpectations(); + } + finally + { + process?.Kill(); + } + } } diff --git a/test/OpenTelemetry.AutoInstrumentation.Tests/Configurations/SettingsTests.cs b/test/OpenTelemetry.AutoInstrumentation.Tests/Configurations/SettingsTests.cs index 4b0ee71a8..d319d2ee0 100644 --- a/test/OpenTelemetry.AutoInstrumentation.Tests/Configurations/SettingsTests.cs +++ b/test/OpenTelemetry.AutoInstrumentation.Tests/Configurations/SettingsTests.cs @@ -345,6 +345,7 @@ public class SettingsTests : IDisposable #if NET [InlineData("ASPNETCORE", MetricInstrumentation.AspNetCore)] #endif + [InlineData("SQLCLIENT", MetricInstrumentation.SqlClient)] internal void MeterSettings_Instrumentations_SupportedValues(string meterInstrumentation, MetricInstrumentation expectedMetricInstrumentation) { Environment.SetEnvironmentVariable(ConfigurationKeys.Metrics.MetricsInstrumentationEnabled, "false"); diff --git a/test/test-applications/integrations/TestApplication.SqlClient.Microsoft/Program.cs b/test/test-applications/integrations/TestApplication.SqlClient.Microsoft/Program.cs index 453bab158..2c877b24f 100644 --- a/test/test-applications/integrations/TestApplication.SqlClient.Microsoft/Program.cs +++ b/test/test-applications/integrations/TestApplication.SqlClient.Microsoft/Program.cs @@ -1,6 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +using System.Diagnostics; using Microsoft.Data.SqlClient; using TestApplication.Shared; @@ -32,6 +33,19 @@ public class Program { await ExecuteAsyncCommands(connection); } + + // The "LONG_RUNNING" environment variable is used by tests that access/receive + // data that takes time to be produced. + var longRunning = Environment.GetEnvironmentVariable("LONG_RUNNING"); + if (longRunning == "true") + { + // In this case it is necessary to ensure that the test has a chance to read the + // expected data, only by keeping the application alive for some time that can + // be ensured. Anyway, tests that set "LONG_RUNNING" env var to true are expected + // to kill the process directly. + Console.WriteLine("LONG_RUNNING is true, waiting for process to be killed..."); + Process.GetCurrentProcess().WaitForExit(); + } } private static void ExecuteCommands(SqlConnection connection) diff --git a/test/test-applications/integrations/TestApplication.SqlClient.System.NetFramework/Program.cs b/test/test-applications/integrations/TestApplication.SqlClient.System.NetFramework/Program.cs index 8cf1f3f5d..1afcf6a14 100644 --- a/test/test-applications/integrations/TestApplication.SqlClient.System.NetFramework/Program.cs +++ b/test/test-applications/integrations/TestApplication.SqlClient.System.NetFramework/Program.cs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 using System.Data.SqlClient; +using System.Diagnostics; using TestApplication.Shared; namespace TestApplication.SqlClient.System; @@ -31,6 +32,19 @@ public class Program { await ExecuteAsyncCommands(connection); } + + // The "LONG_RUNNING" environment variable is used by tests that access/receive + // data that takes time to be produced. + var longRunning = Environment.GetEnvironmentVariable("LONG_RUNNING"); + if (longRunning == "true") + { + // In this case it is necessary to ensure that the test has a chance to read the + // expected data, only by keeping the application alive for some time that can + // be ensured. Anyway, tests that set "LONG_RUNNING" env var to true are expected + // to kill the process directly. + Console.WriteLine("LONG_RUNNING is true, waiting for process to be killed..."); + Process.GetCurrentProcess().WaitForExit(); + } } private static void ExecuteCommands(SqlConnection connection) diff --git a/test/test-applications/integrations/TestApplication.SqlClient.System/Program.cs b/test/test-applications/integrations/TestApplication.SqlClient.System/Program.cs index de1f0e333..7af1da69f 100644 --- a/test/test-applications/integrations/TestApplication.SqlClient.System/Program.cs +++ b/test/test-applications/integrations/TestApplication.SqlClient.System/Program.cs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 using System.Data.SqlClient; +using System.Diagnostics; using TestApplication.Shared; namespace TestApplication.SqlClient.System; @@ -33,6 +34,19 @@ public class Program { await ExecuteAsyncCommands(connection); } + + // The "LONG_RUNNING" environment variable is used by tests that access/receive + // data that takes time to be produced. + var longRunning = Environment.GetEnvironmentVariable("LONG_RUNNING"); + if (longRunning == "true") + { + // In this case it is necessary to ensure that the test has a chance to read the + // expected data, only by keeping the application alive for some time that can + // be ensured. Anyway, tests that set "LONG_RUNNING" env var to true are expected + // to kill the process directly. + Console.WriteLine("LONG_RUNNING is true, waiting for process to be killed..."); + Process.GetCurrentProcess().WaitForExit(); + } } private static void ExecuteCommands(SqlConnection connection)