Skip to content

Commit 92de09d

Browse files
authored
Merge pull request #18 from digma-ai/better_proxy
Better proxy
2 parents b473a8a + 69b5d06 commit 92de09d

File tree

10 files changed

+242
-80
lines changed

10 files changed

+242
-80
lines changed

src/Digma.MassTransit.Integration/MasstransitDiagnosticObserver.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ async Task IConsumeObserver.PreConsume<T>(ConsumeContext<T> context)
2121
var methodInfo = _consumerMethodInfoMap.GetOrAdd(context.Message.GetType(), type => _configuration.GetConsumerMethodInfo(type));
2222
if (methodInfo is null) return;
2323

24-
SpanUtils.AddCommonTags(methodInfo,Activity.Current);
24+
SpanUtils.AddCommonTags(methodInfo.DeclaringType, methodInfo,Activity.Current);
2525

2626
await Task.CompletedTask;
2727
}

src/OpenTelemetry.Instrumentation.Digma.Tests/OpenTelemetry.Instrumentation.Digma.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
</PropertyGroup>
88

99
<ItemGroup>
10+
<PackageReference Include="Humanizer" Version="2.14.1" />
1011
<PackageReference Include="MSTest" Version="2.2.10" />
1112
</ItemGroup>
1213

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Diagnostics;
4+
using System.Linq;
5+
using Microsoft.VisualStudio.TestTools.UnitTesting;
6+
7+
namespace OpenTelemetry.Instrumentation.Digma.Tests.Stubs;
8+
9+
public static class AssertActivity
10+
{
11+
public static void SpanNameIs(string name, Activity activity)
12+
{
13+
Assert.AreEqual(name, activity.OperationName);
14+
}
15+
16+
public static void InstrumentationScopeIs(string name, Activity activity)
17+
{
18+
Assert.AreEqual(name, activity.Source.Name);
19+
}
20+
21+
public static void DurationIs(TimeSpan value, TimeSpan delta, Activity activity)
22+
{
23+
Assert.AreEqual(value.TotalMilliseconds, activity.Duration.TotalMilliseconds, delta.TotalMilliseconds);
24+
}
25+
26+
public static void HasTag(string key, string value, Activity activity)
27+
{
28+
CollectionAssert.Contains(activity.Tags.ToArray(), new KeyValuePair<string, string>(key, value));
29+
}
30+
}

src/OpenTelemetry.Instrumentation.Digma.Tests/Stubs/DecoratedService.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ public interface IDecoratedService
1212

1313
public Task AsyncMethodExplicitlyMarkedForTracing(Action stateValidation);
1414

15+
public Task AsyncVoid();
16+
17+
public Task<int> AsyncValue();
18+
19+
public Task AsyncError();
20+
1521
public void MethodNotExplicitlyMarkedForTracing(Action stateValidation);
1622

1723
public void MethodWithStrangeParams1(Action stateValidation,
@@ -39,6 +45,24 @@ public async Task AsyncMethodExplicitlyMarkedForTracing(Action stateValidation)
3945
stateValidation();
4046
}
4147

48+
49+
public async Task AsyncVoid()
50+
{
51+
await Task.Delay(100);
52+
}
53+
54+
public async Task<int> AsyncValue()
55+
{
56+
await Task.Delay(100);
57+
return 123;
58+
}
59+
60+
public async Task AsyncError()
61+
{
62+
await Task.Delay(100);
63+
throw new Exception("Bla");
64+
}
65+
4266
public void MethodNotExplicitlyMarkedForTracing(Action stateValidation)
4367
{
4468
stateValidation();
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using System.Collections.Generic;
2+
using System.Diagnostics;
3+
4+
namespace OpenTelemetry.Instrumentation.Digma.Tests.Stubs;
5+
6+
public class MockProcessor : BaseProcessor<Activity>
7+
{
8+
private readonly List<Activity> _activities = new();
9+
10+
public override void OnEnd(Activity data)
11+
{
12+
_activities.Add(data);
13+
base.OnEnd(data);
14+
}
15+
16+
public IReadOnlyList<Activity> Activities => _activities.AsReadOnly();
17+
18+
public void Reset() => _activities.Clear();
19+
}

src/OpenTelemetry.Instrumentation.Digma.Tests/TestTracingDecorator.cs

Lines changed: 123 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
using System;
12
using System.Collections.Generic;
23
using System.Diagnostics;
34
using System.Linq;
45
using System.Threading.Tasks;
6+
using Humanizer;
57
using Microsoft.VisualStudio.TestTools.UnitTesting;
68
using OpenTelemetry.Instrumentation.Digma.Helpers;
79
using OpenTelemetry.Instrumentation.Digma.Tests.Stubs;
@@ -16,82 +18,148 @@ public class TestTracingDecorator
1618
private static readonly string ServiceInterfaceFqn =
1719
"OpenTelemetry.Instrumentation.Digma.Tests.Stubs.IDecoratedService";
1820

19-
[TestMethod]
20-
public void Activity_Created_For_Attribute_Marked_Method()
21-
{
22-
DecoratedService service = new DecoratedService();
23-
IDecoratedService tracingDecorator = TraceDecorator<IDecoratedService>.Create(service);
24-
tracingDecorator.MethodExplicitlyMarkedForTracing(() =>
25-
{
26-
Assert.IsNotNull(Activity.Current);
27-
AssertHasCommonTags(Activity.Current, ServiceInterfaceFqn,
28-
"MethodExplicitlyMarkedForTracing", "Action");
29-
});
30-
}
21+
private MockProcessor _mockProcessor = new ();
22+
23+
// [TestMethod]
24+
// public void Activity_Created_For_Attribute_Marked_Method()
25+
// {
26+
// DecoratedService service = new DecoratedService();
27+
// IDecoratedService tracingDecorator = TraceDecorator<IDecoratedService>.Create(service);
28+
// tracingDecorator.MethodExplicitlyMarkedForTracing(() =>
29+
// {
30+
// Assert.IsNotNull(Activity.Current);
31+
// AssertHasCommonTags(Activity.Current, ServiceInterfaceFqn,
32+
// "MethodExplicitlyMarkedForTracing", "Action");
33+
// });
34+
// }
3135

3236
[TestInitialize]
3337
public void SetupOtel()
3438
{
39+
_mockProcessor.Reset();
3540
Sdk.CreateTracerProviderBuilder()
3641
.AddSource("*")
3742
.SetResourceBuilder(
3843
ResourceBuilder.CreateDefault()
3944
.AddService(serviceName: "test", serviceVersion: "2.2"))
45+
.AddProcessor(_mockProcessor)
4046
.Build();
4147
}
4248

43-
[TestMethod]
44-
public async Task Activity_Created_For_Async_Attribute_Marked_Method()
45-
{
46-
DecoratedService service = new DecoratedService();
47-
IDecoratedService tracingDecorator = TraceDecorator<IDecoratedService>.Create(service);
48-
await tracingDecorator.AsyncMethodExplicitlyMarkedForTracing(() =>
49-
{
50-
Assert.IsNotNull(Activity.Current);
51-
AssertHasCommonTags(Activity.Current, ServiceInterfaceFqn,
52-
"AsyncMethodExplicitlyMarkedForTracing", "Action");
53-
});
54-
}
49+
// [TestMethod]
50+
// public async Task Activity_Created_For_Async_Attribute_Marked_Method()
51+
// {
52+
// DecoratedService service = new DecoratedService();
53+
// IDecoratedService tracingDecorator = TraceDecorator<IDecoratedService>.Create(service);
54+
// await tracingDecorator.AsyncMethodExplicitlyMarkedForTracing(() =>
55+
// {
56+
// Assert.IsNotNull(Activity.Current);
57+
// AssertHasCommonTags(Activity.Current, ServiceInterfaceFqn,
58+
// "AsyncMethodExplicitlyMarkedForTracing", "Action");
59+
// });
60+
// }
61+
//
62+
// [TestMethod]
63+
// public void Activity_Created_MethodWithStrangeParams1()
64+
// {
65+
// DecoratedService service = new DecoratedService();
66+
// IDecoratedService tracingDecorator = TraceDecorator<IDecoratedService>.Create(service);
67+
// int intVal = 5;
68+
// tracingDecorator.MethodWithStrangeParams1(() =>
69+
// {
70+
// Assert.IsNotNull(Activity.Current);
71+
// AssertHasCommonTags(Activity.Current, ServiceInterfaceFqn, "MethodWithStrangeParams1",
72+
// "Action|IList`1[]|ISet`1|IDictionary`2|Int32&");
73+
// },
74+
// new List<string>[] { }, new HashSet<int[]>(), new Dictionary<int, ICollection<string>>(), ref intVal
75+
// );
76+
// }
77+
//
78+
// [TestMethod]
79+
// public void Activity_Created_MethodJaggedAndMultiDimArraysParams()
80+
// {
81+
// DecoratedService service = new DecoratedService();
82+
// IDecoratedService tracingDecorator = TraceDecorator<IDecoratedService>.Create(service);
83+
// string strVal;
84+
// tracingDecorator.MethodJaggedAndMultiDimArraysParams(() =>
85+
// {
86+
// Assert.IsNotNull(Activity.Current);
87+
// AssertHasCommonTags(Activity.Current, ServiceInterfaceFqn, "MethodJaggedAndMultiDimArraysParams",
88+
// "Action|String&|Boolean[][][]|Int16[,,][,][,,,]|Int64[][,][][,,]");
89+
// },
90+
// out strVal, new bool[][][] { }, new short[,,,][,][,,] { }, new long[,,][][,][] { }
91+
// );
92+
// }
93+
//
94+
// [TestMethod]
95+
// public void Activity_Not_Created_For_Non_Attribute_Marked_Method_If_All_Methods_False()
96+
// {
97+
// DecoratedService service = new DecoratedService();
98+
// IDecoratedService tracingDecorator =
99+
// TraceDecorator<IDecoratedService>.Create(service, decorateAllMethods: false);
100+
// tracingDecorator.MethodNotExplicitlyMarkedForTracing(() => { Assert.IsNull(Activity.Current); });
101+
// }
55102

56103
[TestMethod]
57-
public void Activity_Created_MethodWithStrangeParams1()
104+
public async Task Activity_Async_Void()
58105
{
59-
DecoratedService service = new DecoratedService();
60-
IDecoratedService tracingDecorator = TraceDecorator<IDecoratedService>.Create(service);
61-
int intVal = 5;
62-
tracingDecorator.MethodWithStrangeParams1(() =>
63-
{
64-
Assert.IsNotNull(Activity.Current);
65-
AssertHasCommonTags(Activity.Current, ServiceInterfaceFqn, "MethodWithStrangeParams1",
66-
"Action|IList`1[]|ISet`1|IDictionary`2|Int32&");
67-
},
68-
new List<string>[] { }, new HashSet<int[]>(), new Dictionary<int, ICollection<string>>(), ref intVal
69-
);
106+
// Arrange
107+
var service = new DecoratedService();
108+
var decoratedService = TraceDecorator<IDecoratedService>.Create(service, decorateAllMethods: true);
109+
110+
// Act #1
111+
await decoratedService.AsyncVoid();
112+
var activity = _mockProcessor.Activities.Single();
113+
AssertActivity.SpanNameIs("AsyncVoid", activity);
114+
AssertActivity.InstrumentationScopeIs("OpenTelemetry.Instrumentation.Digma.Tests.Stubs.DecoratedService", activity);
115+
AssertActivity.DurationIs(100.Milliseconds(), 30.Milliseconds(), activity);
116+
AssertActivity.HasTag("code.namespace", "OpenTelemetry.Instrumentation.Digma.Tests.Stubs.DecoratedService", activity);
117+
AssertActivity.HasTag("code.function", "AsyncVoid", activity);
70118
}
71-
119+
72120
[TestMethod]
73-
public void Activity_Created_MethodJaggedAndMultiDimArraysParams()
121+
public async Task Activity_Async_Value()
74122
{
75-
DecoratedService service = new DecoratedService();
76-
IDecoratedService tracingDecorator = TraceDecorator<IDecoratedService>.Create(service);
77-
string strVal;
78-
tracingDecorator.MethodJaggedAndMultiDimArraysParams(() =>
79-
{
80-
Assert.IsNotNull(Activity.Current);
81-
AssertHasCommonTags(Activity.Current, ServiceInterfaceFqn, "MethodJaggedAndMultiDimArraysParams",
82-
"Action|String&|Boolean[][][]|Int16[,,][,][,,,]|Int64[][,][][,,]");
83-
},
84-
out strVal, new bool[][][] { }, new short[,,,][,][,,] { }, new long[,,][][,][] { }
85-
);
123+
// Arrange
124+
var service = new DecoratedService();
125+
var decoratedService = TraceDecorator<IDecoratedService>.Create(service, decorateAllMethods: true);
126+
127+
// Act #1
128+
var result = await decoratedService.AsyncValue();
129+
Assert.AreEqual(123, result);
130+
131+
var activity = _mockProcessor.Activities.Single();
132+
AssertActivity.SpanNameIs("AsyncValue", activity);
133+
AssertActivity.InstrumentationScopeIs("OpenTelemetry.Instrumentation.Digma.Tests.Stubs.DecoratedService", activity);
134+
AssertActivity.DurationIs(100.Milliseconds(), 30.Milliseconds(), activity);
135+
AssertActivity.HasTag("code.namespace", "OpenTelemetry.Instrumentation.Digma.Tests.Stubs.DecoratedService", activity);
136+
AssertActivity.HasTag("code.function", "AsyncValue", activity);
86137
}
87-
138+
88139
[TestMethod]
89-
public void Activity_Not_Created_For_Non_Attribute_Marked_Method_If_All_Methods_False()
140+
public async Task Activity_Async_Error()
90141
{
91-
DecoratedService service = new DecoratedService();
92-
IDecoratedService tracingDecorator =
93-
TraceDecorator<IDecoratedService>.Create(service, decorateAllMethods: false);
94-
tracingDecorator.MethodNotExplicitlyMarkedForTracing(() => { Assert.IsNull(Activity.Current); });
142+
// Arrange
143+
var service = new DecoratedService();
144+
var decoratedService = TraceDecorator<IDecoratedService>.Create(service, decorateAllMethods: true);
145+
146+
// Act #1
147+
try
148+
{
149+
await decoratedService.AsyncError();
150+
Assert.Fail();
151+
}
152+
catch (Exception e)
153+
{
154+
Assert.AreEqual(e.Message, "Bla");
155+
156+
var activity = _mockProcessor.Activities.Single();
157+
AssertActivity.SpanNameIs("AsyncError", activity);
158+
AssertActivity.InstrumentationScopeIs("OpenTelemetry.Instrumentation.Digma.Tests.Stubs.DecoratedService", activity);
159+
AssertActivity.DurationIs(100.Milliseconds(), 30.Milliseconds(), activity);
160+
AssertActivity.HasTag("code.namespace", "OpenTelemetry.Instrumentation.Digma.Tests.Stubs.DecoratedService", activity);
161+
AssertActivity.HasTag("code.function", "AsyncError", activity);
162+
}
95163
}
96164

97165
private void AssertHasCommonTags(Activity? activity,

src/OpenTelemetry.Instrumentation.Digma/Diagnostic/HttpEndpointDiagnosticObserver.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public void OnNext(KeyValuePair<string, object?> pair)
3535
var descriptor = endpoint?.Metadata.GetMetadata<ControllerActionDescriptor>();
3636
if (descriptor == null)
3737
return;
38-
SpanUtils.AddCommonTags(descriptor.MethodInfo, Activity.Current);
38+
SpanUtils.AddCommonTags(descriptor.ControllerTypeInfo, descriptor.MethodInfo, Activity.Current);
3939
}
4040

4141
public bool CanHandle(string diagnosticListener)

src/OpenTelemetry.Instrumentation.Digma/Helpers/SpanNamingSchema.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@ public interface IActivityNamingSchema
77
public string GetSpanName(Type classType, MethodInfo method);
88
}
99

10+
public class MethodNameSchema : IActivityNamingSchema
11+
{
12+
public string GetSpanName(Type classType, MethodInfo method)
13+
{
14+
return method.Name;
15+
}
16+
}
17+
1018
public class MethodFullNameSchema : IActivityNamingSchema
1119
{
1220
public string GetSpanName(Type classType, MethodInfo method)

0 commit comments

Comments
 (0)