Skip to content

Commit 54f52e5

Browse files
committed
Fix NoCode instrumentation for generic classes and methods
1 parent 31a7277 commit 54f52e5

File tree

7 files changed

+113
-1
lines changed

7 files changed

+113
-1
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ This component adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.h
3636

3737
### Fixed
3838

39+
- Fixed configuration based instrumentation for generic classes and methods.
40+
3941
## [1.13.0](https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/releases/tag/v1.13.0)
4042

4143
This release include all changes from [1.13.0-beta.1](https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/releases/tag/v1.13.0-beta.1)

docs/nocode-instrumentation.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,68 @@ instrumentation/development:
393393
kind: internal
394394
```
395395
396+
### Generic Class Instrumentation
397+
398+
Instrument methods in generic classes with class-level type parameters:
399+
400+
```csharp
401+
public class GenericNoCodeTestingClass<TFooClass, TBarClass>
402+
{
403+
public TFooMethod GenericTestMethod<TFooMethod, TBarMethod>(
404+
TFooMethod fooMethod,
405+
TBarMethod barMethod,
406+
TFooClass fooClass,
407+
TBarClass barClass)
408+
{
409+
return fooMethod;
410+
}
411+
}
412+
```
413+
414+
For generic classes, use the backtick notation with the number of class-level
415+
type parameters:
416+
417+
Generic Type Parameter Notation:
418+
419+
- Class-level type parameters: Use `!!0`, `!!1`, etc. (where `!!0` is the first
420+
class type parameter)
421+
- Method-level type parameters: Use `!0`, `!1`, etc. (where `!0` is the first
422+
method type parameter)
423+
- In the type name, use backtick notation: `ClassName\`N` where N is the number
424+
of generic parameters
425+
426+
Configuration:
427+
428+
```yaml
429+
instrumentation/development:
430+
dotnet:
431+
no_code:
432+
targets:
433+
- target:
434+
assembly:
435+
name: TestApplication.NoCode
436+
type: TestApplication.NoCode.GenericNoCodeTestingClass`2
437+
method: GenericTestMethod
438+
signature:
439+
return_type: '!0'
440+
parameter_types:
441+
- '!0'
442+
- '!1'
443+
- '!!0'
444+
- '!!1'
445+
span:
446+
name: Span-GenericTestMethodWithParameters
447+
kind: internal
448+
```
449+
450+
In this example:
451+
452+
- `GenericNoCodeTestingClass\`2` indicates a class with 2 generic type parameters
453+
- `'!0'` represents the first method type parameter (`TFooMethod`)
454+
- `'!1'` represents the second method type parameter (`TBarMethod`)
455+
- `'!!0'` represents the first class type parameter (`TFooClass`)
456+
- `'!!1'` represents the second class type parameter (`TBarClass`)
457+
396458
### Methods with Return Values
397459

398460
Instrument methods that return values:

src/OpenTelemetry.AutoInstrumentation/Instrumentations/NoCode/NoCodeIntegrationHelper.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,12 +128,28 @@ private static bool CheckParameters(string[] targetSignatureTypes, ParameterInfo
128128

129129
for (var i = 0; i < parameters.Length; i++)
130130
{
131-
if (targetSignatureTypes[i + 1] != parameters[i].ParameterType.FullName)
131+
var parameterTypeNameDefinition = GetParameterTypeNameDefinition(parameters[i]);
132+
if (targetSignatureTypes[i + 1] != parameterTypeNameDefinition)
132133
{
133134
return false;
134135
}
135136
}
136137

137138
return true;
138139
}
140+
141+
private static string GetParameterTypeNameDefinition(ParameterInfo parameterInfo)
142+
{
143+
if (parameterInfo.ParameterType.IsGenericParameter)
144+
{
145+
var definedOnMethod = parameterInfo.ParameterType.DeclaringMethod != null;
146+
var genericParameterPosition = parameterInfo.ParameterType.GenericParameterPosition;
147+
148+
return definedOnMethod
149+
? $"!!{genericParameterPosition}"
150+
: $"!{genericParameterPosition}";
151+
}
152+
153+
return parameterInfo.ParameterType.FullName!;
154+
}
139155
}

test/IntegrationTests/NoCodeTests.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ public void SubmitsTraces()
101101

102102
collector.ExpectNoCode("Span-GenericTestMethod");
103103
collector.ExpectAsyncNoCode("Span-GenericTestMethodAsync");
104+
collector.ExpectNoCode("Span-GenericTestMethodWithParameters");
104105

105106
RunTestApplication();
106107

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright The OpenTelemetry Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
using System.Runtime.CompilerServices;
5+
6+
namespace TestApplication.NoCode;
7+
8+
internal class GenericNoCodeTestingClass<TFooClass, TBarClass>
9+
{
10+
[MethodImpl(MethodImplOptions.NoInlining)]
11+
public TFooMethod GenericTestMethod<TFooMethod, TBarMethod>(TFooMethod fooMethod, TBarMethod barMethod, TFooClass fooClass, TBarClass barClass)
12+
{
13+
return fooMethod;
14+
}
15+
}

test/test-applications/integrations/TestApplication.NoCode/Program.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ public static async Task Main(string[] args)
1212
ConsoleHelper.WriteSplashScreen(args);
1313

1414
var noCodeTestingClass = new NoCodeTestingClass();
15+
var genericNoCodeTestingClass = new GenericNoCodeTestingClass<int, long>();
1516

1617
noCodeTestingClass.TestMethod();
1718
noCodeTestingClass.TestMethodA();
@@ -67,5 +68,6 @@ public static async Task Main(string[] args)
6768

6869
_ = noCodeTestingClass.GenericTestMethod<int>();
6970
_ = await noCodeTestingClass.GenericTestMethodAsync<int>();
71+
_ = genericNoCodeTestingClass.GenericTestMethod(string.Empty, new object(), 123, 456L);
7072
}
7173
}

test/test-applications/integrations/TestApplication.NoCode/config.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -650,3 +650,17 @@ instrumentation/development:
650650
parameter_types:
651651
span:
652652
name: Span-GenericTestMethodAsync
653+
- target:
654+
assembly:
655+
name: TestApplication.NoCode
656+
type: TestApplication.NoCode.GenericNoCodeTestingClass`2
657+
method: GenericTestMethod
658+
signature:
659+
return_type: '!!0'
660+
parameter_types:
661+
- '!!0'
662+
- '!!1'
663+
- '!0'
664+
- '!1'
665+
span:
666+
name: Span-GenericTestMethodWithParameters

0 commit comments

Comments
 (0)