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)