Skip to content

Commit

Permalink
StackExchange.Redis instrumentation for .NET Core 3.1+ (#979)
Browse files Browse the repository at this point in the history
* Cleanup conditional references

* StackExchange.Redis intrumentation

* code review feedback

* Support from 2.0.405

* GraphQL - typo fixes in defined integrations

* remove launch settings

* typo fix in tests

* cleanup file header

Co-authored-by: Chris Ventura <[email protected]>
  • Loading branch information
Kielek and nrcventura authored Jul 28, 2022
1 parent 7d0c440 commit 076306d
Show file tree
Hide file tree
Showing 20 changed files with 688 additions and 10 deletions.
6 changes: 6 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,12 @@ updates:
- ".NET"
- "do NOT merge"

- package-ecosystem: nuget
directory: /test/test-applications/integrations/TestApplication.StackExchangeRedis
schedule:
interval: "daily"
open-pull-requests-limit: 20

- package-ecosystem: nuget
directory: /test/test-applications/mocks/OpenTelemetry.AutoInstrumentation.Mock
schedule:
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm

- Add MySql.Data traces instrumentation.
- Add Npgsql traces instrumentation.
- Add StackExchange.Redis traces instrumentation.
- Add configuration option `none` to `OTEL_DOTNET_AUTO_TRACES_ENABLED_INSTRUMENTATIONS`
and `OTEL_DOTNET_AUTO_METRICS_ENABLED_INSTRUMENTATIONS`.

Expand Down
15 changes: 15 additions & 0 deletions OpenTelemetry.AutoInstrumentation.sln
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestApplication.Shared", "t
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestApplication.MySqlData", "test\test-applications\integrations\TestApplication.MySqlData\TestApplication.MySqlData.csproj", "{E7C2D2CF-C965-449D-A02C-02F7837D0C6D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestApplication.StackExchangeRedis", "test\test-applications\integrations\TestApplication.StackExchangeRedis\TestApplication.StackExchangeRedis.csproj", "{671EB8F0-E164-4E9F-B423-27AF4B59D360}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -557,6 +559,18 @@ Global
{E7C2D2CF-C965-449D-A02C-02F7837D0C6D}.Release|x64.Build.0 = Release|x64
{E7C2D2CF-C965-449D-A02C-02F7837D0C6D}.Release|x86.ActiveCfg = Release|x86
{E7C2D2CF-C965-449D-A02C-02F7837D0C6D}.Release|x86.Build.0 = Release|x86
{671EB8F0-E164-4E9F-B423-27AF4B59D360}.Debug|Any CPU.ActiveCfg = Debug|x64
{671EB8F0-E164-4E9F-B423-27AF4B59D360}.Debug|Any CPU.Build.0 = Debug|x64
{671EB8F0-E164-4E9F-B423-27AF4B59D360}.Debug|x64.ActiveCfg = Debug|x64
{671EB8F0-E164-4E9F-B423-27AF4B59D360}.Debug|x64.Build.0 = Debug|x64
{671EB8F0-E164-4E9F-B423-27AF4B59D360}.Debug|x86.ActiveCfg = Debug|x86
{671EB8F0-E164-4E9F-B423-27AF4B59D360}.Debug|x86.Build.0 = Debug|x86
{671EB8F0-E164-4E9F-B423-27AF4B59D360}.Release|Any CPU.ActiveCfg = Release|x64
{671EB8F0-E164-4E9F-B423-27AF4B59D360}.Release|Any CPU.Build.0 = Release|x64
{671EB8F0-E164-4E9F-B423-27AF4B59D360}.Release|x64.ActiveCfg = Release|x64
{671EB8F0-E164-4E9F-B423-27AF4B59D360}.Release|x64.Build.0 = Release|x64
{671EB8F0-E164-4E9F-B423-27AF4B59D360}.Release|x86.ActiveCfg = Release|x86
{671EB8F0-E164-4E9F-B423-27AF4B59D360}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -602,6 +616,7 @@ Global
{DC54F01E-1D5C-4ECF-B5B9-14EECD2B4CF6} = {E409ADD3-9574-465C-AB09-4324D205CC7C}
{CB4EA9F4-EE1B-4009-B3CD-215DCE8BE214} = {82A3CE96-0935-45E5-A9AA-A93A5B63500B}
{E7C2D2CF-C965-449D-A02C-02F7837D0C6D} = {E409ADD3-9574-465C-AB09-4324D205CC7C}
{671EB8F0-E164-4E9F-B423-27AF4B59D360} = {E409ADD3-9574-465C-AB09-4324D205CC7C}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {160A1D00-1F5B-40F8-A155-621B4459D78F}
Expand Down
1 change: 1 addition & 0 deletions docs/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ for more details.
| `MySqlData` | [MySql.Data](https://www.nuget.org/packages/MySql.Data) **Not supported on .NET Framework** | ≥6.10.7 | source |
| `Npgsql` | [Npgsql](https://www.nuget.org/packages/Npgsql) | ≥6.0.0 | source |
| `SqlClient` | [Microsoft.Data.SqlClient](https://www.nuget.org/packages/Microsoft.Data.SqlClient) and [System.Data.SqlClient](https://www.nuget.org/packages/System.Data.SqlClient) | * | source |
| `StackExchangeRedis` | [StackExchange.Redis](https://www.nuget.org/packages/StackExchange.Redis) **Not supported on .NET Framework** | ≥2.0.405 < 3.0.0 | source & binary |

### Instrumented metrics libraries and frameworks

Expand Down
155 changes: 153 additions & 2 deletions integrations.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
"type": "GraphQL.Execution.ExecutionStrategy",
"method": "ExecuteAsync",
"signature_types": [
"System.Threading.Tasks.Task`1<GraphQL.ExecutionResult>",
"System.Threading.Tasks.Task`1[GraphQL.ExecutionResult]",
"GraphQL.Execution.ExecutionContext"
],
"minimum_major": 2,
Expand All @@ -60,7 +60,7 @@
"type": "GraphQL.Execution.SubscriptionExecutionStrategy",
"method": "ExecuteAsync",
"signature_types": [
"System.Threading.Tasks.Task`1<GraphQL.ExecutionResult>",
"System.Threading.Tasks.Task`1[GraphQL.ExecutionResult]",
"GraphQL.Execution.ExecutionContext"
],
"minimum_major": 2,
Expand Down Expand Up @@ -105,5 +105,156 @@
}
}
]
},
{
"name": "StackExchangeRedis",
"method_replacements": [
{
"caller": {},
"target": {
"assembly": "StackExchange.Redis",
"type": "StackExchange.Redis.ConnectionMultiplexer",
"method": "ConnectImpl",
"signature_types": [
"StackExchange.Redis.ConnectionMultiplexer",
"System.Object",
"System.IO.TextWriter"
],
"minimum_major": 2,
"minimum_minor": 0,
"minimum_patch": 0,
"maximum_major": 2,
"maximum_minor": 65535,
"maximum_patch": 65535
},
"wrapper": {
"assembly": "OpenTelemetry.AutoInstrumentation",
"type": "OpenTelemetry.AutoInstrumentation.Instrumentations.StackExchangeRedis.StackExchangeRedisIntegration",
"action": "CallTargetModification"
}
},
{
"caller": {},
"target": {
"assembly": "StackExchange.Redis",
"type": "StackExchange.Redis.ConnectionMultiplexer",
"method": "ConnectImpl",
"signature_types": [
"StackExchange.Redis.ConnectionMultiplexer",
"StackExchange.Redis.ConfigurationOptions",
"System.IO.TextWriter"
],
"minimum_major": 2,
"minimum_minor": 0,
"minimum_patch": 0,
"maximum_major": 2,
"maximum_minor": 65535,
"maximum_patch": 65535
},
"wrapper": {
"assembly": "OpenTelemetry.AutoInstrumentation",
"type": "OpenTelemetry.AutoInstrumentation.Instrumentations.StackExchangeRedis.StackExchangeRedisIntegration",
"action": "CallTargetModification"
}
},
{
"caller": {},
"target": {
"assembly": "StackExchange.Redis",
"type": "StackExchange.Redis.ConnectionMultiplexer",
"method": "ConnectImpl",
"signature_types": [
"StackExchange.Redis.ConnectionMultiplexer",
"StackExchange.Redis.ConfigurationOptions",
"System.IO.TextWriter",
"System.Nullable`1[StackExchange.Redis.ServerType]"
],
"minimum_major": 2,
"minimum_minor": 0,
"minimum_patch": 0,
"maximum_major": 2,
"maximum_minor": 65535,
"maximum_patch": 65535
},
"wrapper": {
"assembly": "OpenTelemetry.AutoInstrumentation",
"type": "OpenTelemetry.AutoInstrumentation.Instrumentations.StackExchangeRedis.StackExchangeRedisIntegration",
"action": "CallTargetModification"
}
},
{
"caller": {},
"target": {
"assembly": "StackExchange.Redis",
"type": "StackExchange.Redis.ConnectionMultiplexer",
"method": "ConnectImplAsync",
"signature_types": [
"System.Threading.Tasks.Task`1[StackExchange.Redis.ConnectionMultiplexer]",
"System.Object",
"System.IO.TextWriter"
],
"minimum_major": 2,
"minimum_minor": 0,
"minimum_patch": 0,
"maximum_major": 2,
"maximum_minor": 65535,
"maximum_patch": 65535
},
"wrapper": {
"assembly": "OpenTelemetry.AutoInstrumentation",
"type": "OpenTelemetry.AutoInstrumentation.Instrumentations.StackExchangeRedis.StackExchangeRedisIntegrationAsync",
"action": "CallTargetModification"
}
},
{
"caller": {},
"target": {
"assembly": "StackExchange.Redis",
"type": "StackExchange.Redis.ConnectionMultiplexer",
"method": "ConnectImplAsync",
"signature_types": [
"System.Threading.Tasks.Task`1[StackExchange.Redis.ConnectionMultiplexer]",
"StackExchange.Redis.ConfigurationOptions",
"System.IO.TextWriter"
],
"minimum_major": 2,
"minimum_minor": 0,
"minimum_patch": 0,
"maximum_major": 2,
"maximum_minor": 65535,
"maximum_patch": 65535
},
"wrapper": {
"assembly": "OpenTelemetry.AutoInstrumentation",
"type": "OpenTelemetry.AutoInstrumentation.Instrumentations.StackExchangeRedis.StackExchangeRedisIntegrationAsync",
"action": "CallTargetModification"
}
},
{
"caller": {},
"target": {
"assembly": "StackExchange.Redis",
"type": "StackExchange.Redis.ConnectionMultiplexer",
"method": "ConnectImplAsync",
"signature_types": [
"System.Threading.Tasks.Task`1[StackExchange.Redis.ConnectionMultiplexer]",
"StackExchange.Redis.ConfigurationOptions",
"System.IO.TextWriter",
"System.Nullable`1[StackExchange.Redis.ServerType]"
],
"minimum_major": 2,
"minimum_minor": 0,
"minimum_patch": 0,
"maximum_major": 2,
"maximum_minor": 65535,
"maximum_patch": 65535
},
"wrapper": {
"assembly": "OpenTelemetry.AutoInstrumentation",
"type": "OpenTelemetry.AutoInstrumentation.Instrumentations.StackExchangeRedis.StackExchangeRedisIntegrationAsync",
"action": "CallTargetModification"
}
}
]
}
]
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
#if NETCOREAPP3_1_OR_GREATER
using OpenTelemetry.AutoInstrumentation.Util;
#endif
using OpenTelemetry.Trace;

namespace OpenTelemetry.AutoInstrumentation.Configuration;
Expand All @@ -32,6 +34,7 @@ internal static class EnvironmentConfigurationTracerHelper
#if NETCOREAPP3_1_OR_GREATER
[TracerInstrumentation.MongoDB] = builder => builder.AddSource("MongoDB.Driver.Core.Extensions.DiagnosticSources"),
[TracerInstrumentation.MySqlData] = builder => builder.AddSource("OpenTelemetry.Instrumentation.MySqlData"),
[TracerInstrumentation.StackExchangeRedis] = builder => builder.AddSource("OpenTelemetry.Instrumentation.StackExchangeRedis"),
#endif
[TracerInstrumentation.Npgsql] = builder => builder.AddSource("Npgsql")
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ public enum TracerInstrumentation
/// <summary>
/// MySqlData instrumentation.
/// </summary>
MySqlData = 6
MySqlData = 6,

/// <summary>
/// StackExchangeRedis instrumentation.
/// </summary>
StackExchangeRedis = 7
#endif
}
4 changes: 4 additions & 0 deletions src/OpenTelemetry.AutoInstrumentation/Instrumentation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ public static bool ProfilerAttached
}
}

#if NETCOREAPP3_1_OR_GREATER
internal static ILifespanManager LifespanManager => LazyInstrumentationLoader;
#endif

internal static TracerSettings TracerSettings { get; } = TracerSettings.FromDefaultSources();

internal static MeterSettings MeterSettings { get; } = MeterSettings.FromDefaultSources();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public GraphQLExecuteAsyncAttribute()
{
IntegrationName = GraphQLCommon.IntegrationName;
MethodName = "ExecuteAsync";
ReturnTypeName = "System.Threading.Tasks.Task`1<GraphQL.ExecutionResult>";
ReturnTypeName = "System.Threading.Tasks.Task`1[GraphQL.ExecutionResult]";
ParameterTypeNames = new[] { "GraphQL.Execution.ExecutionContext" };
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// <copyright file="StackExchangeRedisConstants.cs" company="OpenTelemetry Authors">
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>

#if NETCOREAPP3_1_OR_GREATER

namespace OpenTelemetry.AutoInstrumentation.Instrumentations.StackExchangeRedis;

internal static class StackExchangeRedisConstants
{
public const string AssemblyName = "StackExchange.Redis";

public const string MinimumVersion = "2.0.0"; // this is AssemblyVersion, all 2.* versions are released with this value
public const string MaximumVersion = "2.65535.65535";
public const string IntegrationName = "StackExchangeRedis";

public const string ConnectionMultiplexerTypeName = "StackExchange.Redis.ConnectionMultiplexer";
public const string ConfigurationOptionsTypeName = "StackExchange.Redis.ConfigurationOptions";
public const string TextWriterTypeName = "System.IO.TextWriter";
public const string TaskConnectionMultiplexerTypeName = $"System.Threading.Tasks.Task`1[{ConnectionMultiplexerTypeName}]";
public const string NullableServerType = $"System.Nullable`1[{ServerTypeTypeName}]";

public const string ConnectImplMethodName = "ConnectImpl";
public const string ConnectImplAsyncMethodName = "ConnectImplAsync";

private const string ServerTypeTypeName = "StackExchange.Redis.ServerType";
}
#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// <copyright file="StackExchangeRedisInitializer.cs" company="OpenTelemetry Authors">
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>

#if NETCOREAPP3_1_OR_GREATER

using System;
using OpenTelemetry.AutoInstrumentation.Configuration;

namespace OpenTelemetry.AutoInstrumentation.Instrumentations.StackExchangeRedis;

internal static class StackExchangeRedisInitializer
{
public static void Initialize(object connection)
{
if (connection != null && Instrumentation.TracerSettings.EnabledInstrumentations.Contains(TracerInstrumentation.StackExchangeRedis))
{
var instrumentationType = Type.GetType("OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentation, OpenTelemetry.Instrumentation.StackExchangeRedis");
var optionsInstrumentationType = Type.GetType("OpenTelemetry.Instrumentation.StackExchangeRedis.StackExchangeRedisCallsInstrumentationOptions, OpenTelemetry.Instrumentation.StackExchangeRedis");

var options = Activator.CreateInstance(optionsInstrumentationType);
var instrumentation = Activator.CreateInstance(instrumentationType, connection, options);

Instrumentation.LifespanManager.Track(instrumentation);
}
}
}
#endif
Loading

0 comments on commit 076306d

Please sign in to comment.