Skip to content

Commit 5aed71e

Browse files
author
Liudmila Molkova
authored
Support Azure.Mesasging.ServiceBus (Track2) SDK (#2593)
* support ServiceBus Track2 SDK * changelog * fxcop
1 parent 51dc14a commit 5aed71e

File tree

3 files changed

+170
-13
lines changed

3 files changed

+170
-13
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
## VNext
44
- [LOGGING: Make TelemetryConfiguration configurable in ApplicationInsightsLoggingBuilderExtensions](https://github.com/microsoft/ApplicationInsights-dotnet/issues/1944)
5+
- [Added support for distributed tracing with Azure.Messaging.ServiceBus](https://github.com/microsoft/ApplicationInsights-dotnet/pull/2593)
56

67
## Version 2.21.0-beta1
78
- [Support IPv6 in request headers](https://github.com/microsoft/ApplicationInsights-dotnet/issues/2521)

WEB/Src/DependencyCollector/DependencyCollector.Tests/Implementation/AzureSdkDiagnosticListenerTest.cs

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1123,6 +1123,147 @@ public void AzureClientSpansAreCollectedForEventHubsException()
11231123
}
11241124
}
11251125

1126+
[DataRow("producer")]
1127+
[DataRow("client")]
1128+
[DataTestMethod]
1129+
public void AzureServiceBusSpansAreCollectedAsDependency(string kind)
1130+
{
1131+
using (var listener = new DiagnosticListener("Azure.SomeClient"))
1132+
using (var module = new DependencyTrackingTelemetryModule())
1133+
{
1134+
module.Initialize(this.configuration);
1135+
1136+
Activity sendActivity = new Activity("Azure.SomeClient.Method")
1137+
.AddTag("kind", kind)
1138+
.AddTag("az.namespace", "Microsoft.ServiceBus")
1139+
.AddTag("component", "servicebus")
1140+
.AddTag("peer.address", "amqps://my.servicebus.windows.net/")
1141+
.AddTag("message_bus.destination", "queueName");
1142+
1143+
listener.StartActivity(sendActivity, null);
1144+
listener.StopActivity(sendActivity, null);
1145+
1146+
var telemetry = this.sentItems.Last() as DependencyTelemetry;
1147+
1148+
Assert.IsNotNull(telemetry);
1149+
Assert.AreEqual("SomeClient.Method", telemetry.Name);
1150+
if (kind == "producer")
1151+
{
1152+
Assert.AreEqual("Queue Message | Azure Service Bus", telemetry.Type);
1153+
}
1154+
else
1155+
{
1156+
Assert.AreEqual("Azure Service Bus", telemetry.Type);
1157+
}
1158+
1159+
Assert.IsTrue(telemetry.Success.Value);
1160+
Assert.IsNull(telemetry.Context.Operation.ParentId);
1161+
Assert.AreEqual(sendActivity.StartTimeUtc, telemetry.Timestamp);
1162+
Assert.AreEqual(sendActivity.Duration, telemetry.Duration);
1163+
Assert.AreEqual(sendActivity.TraceId.ToHexString(), telemetry.Context.Operation.Id);
1164+
Assert.AreEqual(sendActivity.SpanId.ToHexString(), telemetry.Id);
1165+
Assert.AreEqual("amqps://my.servicebus.windows.net/queueName", telemetry.Target);
1166+
}
1167+
}
1168+
1169+
[DataRow("server")]
1170+
[DataRow("consumer")]
1171+
[DataTestMethod]
1172+
public void AzureServiceBusSpansAreCollectedAsRequest(string kind)
1173+
{
1174+
using (var listener = new DiagnosticListener("Azure.SomeClient"))
1175+
using (var module = new DependencyTrackingTelemetryModule())
1176+
{
1177+
module.Initialize(this.configuration);
1178+
1179+
Activity sendActivity = new Activity("Azure.SomeClient.Process")
1180+
.AddTag("kind", kind)
1181+
.AddTag("az.namespace", "Microsoft.ServiceBus")
1182+
.AddTag("component", "servicebus")
1183+
.AddTag("peer.address", "amqps://my.servicebus.windows.net")
1184+
.AddTag("message_bus.destination", "queueName");
1185+
1186+
listener.StartActivity(sendActivity, null);
1187+
listener.StopActivity(sendActivity, null);
1188+
1189+
var telemetry = this.sentItems.Last() as RequestTelemetry;
1190+
1191+
Assert.IsNotNull(telemetry);
1192+
Assert.AreEqual("SomeClient.Process", telemetry.Name);
1193+
Assert.AreEqual("amqps://my.servicebus.windows.net/queueName", telemetry.Source);
1194+
Assert.IsTrue(telemetry.Success.Value);
1195+
1196+
Assert.IsNull(telemetry.Context.Operation.ParentId);
1197+
Assert.AreEqual(sendActivity.StartTimeUtc, telemetry.Timestamp);
1198+
Assert.AreEqual(sendActivity.Duration, telemetry.Duration);
1199+
Assert.AreEqual(sendActivity.TraceId.ToHexString(), telemetry.Context.Operation.Id);
1200+
Assert.AreEqual(sendActivity.SpanId.ToHexString(), telemetry.Id);
1201+
Assert.IsFalse(telemetry.Metrics.Any());
1202+
}
1203+
}
1204+
1205+
[DataRow("producer")]
1206+
[DataRow("client")]
1207+
[DataRow("server")]
1208+
[DataRow("consumer")]
1209+
[DataTestMethod]
1210+
public void AzureServiceBusSpansAreCollectedError(string kind)
1211+
{
1212+
using (var listener = new DiagnosticListener("Azure.SomeClient"))
1213+
using (var module = new DependencyTrackingTelemetryModule())
1214+
{
1215+
module.Initialize(this.configuration);
1216+
1217+
var exception = new InvalidOperationException();
1218+
Activity sendActivity = new Activity("Azure.SomeClient.Method")
1219+
.AddTag("peer.address", "amqps://my.servicebus.windows.net")
1220+
.AddTag("message_bus.destination", "queueName")
1221+
.AddTag("kind", kind)
1222+
.AddTag("az.namespace", "Microsoft.ServiceBus");
1223+
1224+
listener.StartActivity(sendActivity, null);
1225+
listener.Write("Azure.SomeClient.Send.Exception", exception);
1226+
listener.StopActivity(sendActivity, null);
1227+
1228+
var telemetry = this.sentItems.Last();
1229+
1230+
Assert.IsNotNull(telemetry);
1231+
Assert.IsNull(telemetry.Context.Operation.ParentId);
1232+
Assert.AreEqual(sendActivity.TraceId.ToHexString(), telemetry.Context.Operation.Id);
1233+
1234+
OperationTelemetry operation = telemetry as OperationTelemetry;
1235+
Assert.IsFalse(operation.Success.Value);
1236+
Assert.AreEqual(exception.ToInvariantString(), operation.Properties["Error"]);
1237+
Assert.AreEqual(sendActivity.SpanId.ToHexString(), operation.Id);
1238+
Assert.AreEqual("SomeClient.Method", operation.Name);
1239+
1240+
if (kind == "producer" || kind == "client" || kind == "internal")
1241+
{
1242+
Assert.IsTrue(telemetry is DependencyTelemetry);
1243+
DependencyTelemetry dependency = telemetry as DependencyTelemetry;
1244+
Assert.AreEqual(string.Empty, dependency.Data);
1245+
Assert.AreEqual(string.Empty, dependency.ResultCode);
1246+
Assert.AreEqual("amqps://my.servicebus.windows.net/queueName", dependency.Target);
1247+
if (kind == "producer")
1248+
{
1249+
Assert.AreEqual("Queue Message | Azure Service Bus", dependency.Type);
1250+
}
1251+
else
1252+
{
1253+
Assert.AreEqual("Azure Service Bus", dependency.Type);
1254+
}
1255+
}
1256+
else
1257+
{
1258+
Assert.IsTrue(telemetry is RequestTelemetry);
1259+
RequestTelemetry request = telemetry as RequestTelemetry;
1260+
Assert.AreEqual(string.Empty, request.ResponseCode);
1261+
Assert.AreEqual("amqps://my.servicebus.windows.net/queueName", request.Source);
1262+
}
1263+
}
1264+
}
1265+
1266+
11261267
private T TrackOperation<T>(
11271268
DiagnosticListener listener,
11281269
string activityName,

WEB/Src/DependencyCollector/DependencyCollector/Implementation/AzureSdk/AzureSdkDiagnosticsEventHandler.cs

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,9 @@ public override void OnEvent(KeyValuePair<string, object> evnt, DiagnosticListen
6565
telemetry = new DependencyTelemetry { Type = type };
6666
}
6767

68-
if (type != null && type.EndsWith(RemoteDependencyConstants.AzureEventHubs, StringComparison.Ordinal))
68+
if (IsMessagingDependency(type))
6969
{
70-
SetEventHubsProperties(currentActivity, telemetry);
70+
SetMessagingProperties(currentActivity, telemetry);
7171
}
7272

7373
if (this.linksPropertyFetcher.Fetch(evnt.Value) is IEnumerable<Activity> activityLinks)
@@ -225,6 +225,13 @@ private static string GetType(Activity currentActivity)
225225
break;
226226

227227
case "component":
228+
// old tag populated for back-compat, if az.namespace is set - ignore it.
229+
if (component == null)
230+
{
231+
component = tag.Value;
232+
}
233+
234+
break;
228235
case "az.namespace":
229236
component = tag.Value;
230237
break;
@@ -233,9 +240,11 @@ private static string GetType(Activity currentActivity)
233240

234241
if (component == "eventhubs" || component == "Microsoft.EventHub")
235242
{
236-
return kind == null
237-
? RemoteDependencyConstants.AzureEventHubs
238-
: string.Concat(kind, " | ", RemoteDependencyConstants.AzureEventHubs);
243+
component = RemoteDependencyConstants.AzureEventHubs;
244+
}
245+
else if (component == "Microsoft.ServiceBus")
246+
{
247+
component = RemoteDependencyConstants.AzureServiceBus;
239248
}
240249

241250
if (component != null)
@@ -310,10 +319,16 @@ private static void SetHttpProperties(Activity activity, DependencyTelemetry dep
310319
}
311320
}
312321

313-
private static void SetEventHubsProperties(Activity activity, OperationTelemetry telemetry)
322+
private static bool IsMessagingDependency(string dependencyType)
323+
{
324+
return dependencyType != null && (dependencyType.EndsWith(RemoteDependencyConstants.AzureEventHubs, StringComparison.Ordinal) ||
325+
dependencyType.EndsWith(RemoteDependencyConstants.AzureServiceBus, StringComparison.Ordinal));
326+
}
327+
328+
private static void SetMessagingProperties(Activity activity, OperationTelemetry telemetry)
314329
{
315330
string endpoint = null;
316-
string queueName = null;
331+
string entityName = null;
317332

318333
foreach (var tag in activity.Tags)
319334
{
@@ -323,32 +338,32 @@ private static void SetEventHubsProperties(Activity activity, OperationTelemetry
323338
}
324339
else if (tag.Key == "message_bus.destination")
325340
{
326-
queueName = tag.Value;
341+
entityName = tag.Value;
327342
}
328343
}
329344

330-
if (endpoint == null || queueName == null)
345+
if (endpoint == null || entityName == null)
331346
{
332347
return;
333348
}
334349

335-
// Target uniquely identifies the resource, we use both: queueName and endpoint
350+
// Target uniquely identifies the resource, we use both: entityName and endpoint
336351
// with schema used for SQL-dependencies
337352
string separator = "/";
338353
if (endpoint.EndsWith(separator, StringComparison.Ordinal))
339354
{
340355
separator = string.Empty;
341356
}
342357

343-
string eventHubInfo = string.Concat(endpoint, separator, queueName);
358+
string brokerInfo = string.Concat(endpoint, separator, entityName);
344359

345360
if (telemetry is DependencyTelemetry dependency)
346361
{
347-
dependency.Target = eventHubInfo;
362+
dependency.Target = brokerInfo;
348363
}
349364
else if (telemetry is RequestTelemetry request)
350365
{
351-
request.Source = eventHubInfo;
366+
request.Source = brokerInfo;
352367
}
353368
}
354369

0 commit comments

Comments
 (0)