internal static RemoteDependencyData GetRemoteDependencyData(Activity activity, ref TagEnumerationState monitorTags) { AddActivityLinksToPartCTags(activity.Links, ref monitorTags.PartCTags); var dependency = new RemoteDependencyData(2, activity.DisplayName, activity.Duration.ToString("c", CultureInfo.InvariantCulture)) { Id = activity.Context.SpanId.ToHexString(), Success = activity.GetStatus().StatusCode != StatusCode.Error }; switch (monitorTags.activityType) { case PartBType.Http: dependency.Data = monitorTags.PartBTags.GetDependencyUrl(); dependency.Target = monitorTags.PartBTags.GetDependencyTarget(PartBType.Http); dependency.Type = "Http"; dependency.ResultCode = AzMonList.GetTagValue(ref monitorTags.PartBTags, SemanticConventions.AttributeHttpStatusCode)?.ToString() ?? "0"; break; case PartBType.Db: var depDataAndType = AzMonList.GetTagValues(ref monitorTags.PartBTags, SemanticConventions.AttributeDbStatement, SemanticConventions.AttributeDbSystem); dependency.Data = depDataAndType[0]?.ToString(); dependency.Target = monitorTags.PartBTags.GetDbDependencyTarget(); dependency.Type = SqlDbs.Contains(depDataAndType[1]?.ToString()) ? "SQL" : depDataAndType[1]?.ToString(); break; case PartBType.Rpc: var depInfo = AzMonList.GetTagValues(ref monitorTags.PartBTags, SemanticConventions.AttributeRpcService, SemanticConventions.AttributeRpcSystem, SemanticConventions.AttributeRpcStatus); dependency.Data = depInfo[0]?.ToString(); dependency.Type = depInfo[1]?.ToString(); dependency.ResultCode = depInfo[2]?.ToString(); break; case PartBType.Messaging: depDataAndType = AzMonList.GetTagValues(ref monitorTags.PartBTags, SemanticConventions.AttributeMessagingUrl, SemanticConventions.AttributeMessagingSystem); dependency.Data = depDataAndType[0]?.ToString(); dependency.Type = depDataAndType[1]?.ToString(); break; } if (activity.Kind == ActivityKind.Internal && activity.Parent != null) { dependency.Type = "InProc"; } AddPropertiesToTelemetry(dependency.Properties, ref monitorTags.PartCTags); return(dependency); }
internal static RemoteDependencyData GetRemoteDependencyData(Activity activity) { var monitorTags = EnumerateActivityTags(activity); var dependency = new RemoteDependencyData(2, activity.DisplayName, activity.Duration.ToString("c", CultureInfo.InvariantCulture)) { Id = activity.Context.SpanId.ToHexString(), Success = activity.GetStatus() != Status.Error }; switch (monitorTags.activityType) { case PartBType.Http: monitorTags.PartBTags.GenerateUrlAndAuthority(out var url, out var urlAuthority); dependency.Data = url; dependency.Target = urlAuthority; dependency.Type = "Http"; dependency.ResultCode = AzMonList.GetTagValue(ref monitorTags.PartBTags, SemanticConventions.AttributeHttpStatusCode)?.ToString() ?? "0"; break; case PartBType.Db: var depDataAndType = AzMonList.GetTagValues(ref monitorTags.PartBTags, SemanticConventions.AttributeDbStatement, SemanticConventions.AttributeDbSystem); dependency.Data = depDataAndType[0]?.ToString(); dependency.Type = depDataAndType[1]?.ToString(); break; case PartBType.Rpc: var depInfo = AzMonList.GetTagValues(ref monitorTags.PartBTags, SemanticConventions.AttributeRpcService, SemanticConventions.AttributeRpcSystem, SemanticConventions.AttributeRpcStatus); dependency.Data = depInfo[0]?.ToString(); dependency.Type = depInfo[1]?.ToString(); dependency.ResultCode = depInfo[2]?.ToString(); break; case PartBType.Messaging: depDataAndType = AzMonList.GetTagValues(ref monitorTags.PartBTags, SemanticConventions.AttributeMessagingUrl, SemanticConventions.AttributeMessagingSystem); dependency.Data = depDataAndType[0]?.ToString(); dependency.Type = depDataAndType[1]?.ToString(); break; } AddPropertiesToTelemetry(dependency.Properties, ref monitorTags.PartCTags); return(dependency); }
/// <summary> /// This method follows OpenTelemetry specification to retrieve http URL. /// Reference: https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/semantic_conventions/http.md#http-client. /// </summary> /// <param name="tagObjects">Activity Tags</param> /// <param name="url">URL</param> /// <param name="urlAuthority">Host name or IP address and the port number </param> internal static void GenerateUrlAndAuthority(this AzMonList tagObjects, out string url, out string urlAuthority) { urlAuthority = null; url = null; var httpurl = AzMonList.GetTagValue(ref tagObjects, SemanticConventions.AttributeHttpUrl); if (httpurl != null && Uri.TryCreate(httpurl.ToString(), UriKind.RelativeOrAbsolute, out var uri) && uri.IsAbsoluteUri) { url = uri.AbsoluteUri; urlAuthority = uri.Authority; return; } var httpScheme = AzMonList.GetTagValue(ref tagObjects, SemanticConventions.AttributeHttpScheme)?.ToString(); if (!string.IsNullOrWhiteSpace(httpScheme)) { var httpHost = AzMonList.GetTagValue(ref tagObjects, SemanticConventions.AttributeHttpHost)?.ToString(); if (!string.IsNullOrWhiteSpace(httpHost)) { var httpPortAndTarget = AzMonList.GetTagValues(ref tagObjects, SemanticConventions.AttributeHttpHostPort, SemanticConventions.AttributeHttpTarget); if (httpPortAndTarget[0] != null && httpPortAndTarget[0].ToString() != "80" && httpPortAndTarget[0].ToString() != "443") { var IsColon = (string.IsNullOrWhiteSpace(httpPortAndTarget[0].ToString()) ? null : Colon); url = $"{httpScheme}://{httpHost}{IsColon}{httpPortAndTarget[0]}{httpPortAndTarget[1]}"; urlAuthority = $"{httpHost}{IsColon}{httpPortAndTarget[0]}"; } else { url = $"{httpScheme}://{httpHost}{httpPortAndTarget[1]}"; urlAuthority = $"{httpHost}"; } return; } var netPeerName = AzMonList.GetTagValue(ref tagObjects, SemanticConventions.AttributeNetPeerName)?.ToString(); if (!string.IsNullOrWhiteSpace(netPeerName)) { var netPeerPortAndTarget = AzMonList.GetTagValues(ref tagObjects, SemanticConventions.AttributeNetPeerPort, SemanticConventions.AttributeHttpTarget); var IsColon = (string.IsNullOrWhiteSpace(netPeerPortAndTarget[0]?.ToString()) ? null : Colon); url = $"{httpScheme}{SchemePostfix}{netPeerName}{IsColon}{netPeerPortAndTarget[0]}{netPeerPortAndTarget[1]}"; urlAuthority = $"{netPeerName}{IsColon}{netPeerPortAndTarget[0]}"; return; } var netPeerIP = AzMonList.GetTagValue(ref tagObjects, SemanticConventions.AttributeNetPeerIp)?.ToString(); if (!string.IsNullOrWhiteSpace(netPeerIP)) { var netPeerPortAndTarget = AzMonList.GetTagValues(ref tagObjects, SemanticConventions.AttributeNetPeerPort, SemanticConventions.AttributeHttpTarget); var IsColon = (string.IsNullOrWhiteSpace(netPeerPortAndTarget[0]?.ToString()) ? null : Colon); url = $"{httpScheme}{SchemePostfix}{netPeerIP}{IsColon}{netPeerPortAndTarget[0]}{netPeerPortAndTarget[1]}"; urlAuthority = $"{netPeerIP}{IsColon}{netPeerPortAndTarget[0]}"; return; } } var host = AzMonList.GetTagValue(ref tagObjects, SemanticConventions.AttributeHttpHost)?.ToString(); if (!string.IsNullOrWhiteSpace(host)) { var httpPortAndTarget = AzMonList.GetTagValues(ref tagObjects, SemanticConventions.AttributeHttpHostPort, SemanticConventions.AttributeHttpTarget); var IsColon = (string.IsNullOrWhiteSpace(httpPortAndTarget[0]?.ToString()) ? null : Colon); url = $"{host}{IsColon}{httpPortAndTarget[0]}{httpPortAndTarget[1]}"; urlAuthority = $"{host}{IsColon}{httpPortAndTarget[0]}"; return; } url = string.IsNullOrWhiteSpace(url) ? null : url; }