public void TagObjects_DoubleArray() { var monitorTags = new TagEnumerationState { PartBTags = AzMonList.Initialize(), PartCTags = AzMonList.Initialize() }; IEnumerable <KeyValuePair <string, object> > tagObjects = new Dictionary <string, object> { ["doubleArray"] = new double[] { 1.1, 2.2, 3.3 }, }; using var activity = CreateTestActivity(tagObjects); activity.EnumerateTags(ref monitorTags); Assert.Equal(PartBType.Unknown, monitorTags.activityType); Assert.Empty(monitorTags.PartBTags); Assert.Single(monitorTags.PartCTags); Assert.Equal("1.1,2.2,3.3", AzMonList.GetTagValue(ref monitorTags.PartCTags, "doubleArray")); }
public void TagObjects_BooleanArray() { var monitorTags = new TagEnumerationState { MappedTags = AzMonList.Initialize(), UnMappedTags = AzMonList.Initialize() }; IEnumerable <KeyValuePair <string, object> > tagObjects = new Dictionary <string, object> { ["boolArray"] = new bool[] { true, false, true }, }; using var activity = CreateTestActivity(tagObjects); monitorTags.ForEach(activity.TagObjects); Assert.Equal(OperationType.Unknown, monitorTags.activityType); Assert.Empty(monitorTags.MappedTags); Assert.Single(monitorTags.UnMappedTags); Assert.Equal("True,False,True", AzMonList.GetTagValue(ref monitorTags.UnMappedTags, "boolArray")); }
public void TagObjects_StringArray() { var monitorTags = new TagEnumerationState { MappedTags = AzMonList.Initialize(), UnMappedTags = AzMonList.Initialize() }; IEnumerable <KeyValuePair <string, object> > tagObjects = new Dictionary <string, object> { ["strArray"] = new string[] { "test1", "test2", "test3" }, }; using var activity = CreateTestActivity(tagObjects); monitorTags.ForEach(activity.TagObjects); Assert.Equal(OperationType.Unknown, monitorTags.activityType); Assert.Empty(monitorTags.MappedTags); Assert.Single(monitorTags.UnMappedTags); Assert.Equal("test1,test2,test3", AzMonList.GetTagValue(ref monitorTags.UnMappedTags, "strArray")); }
public static JaegerSpan ToJaegerSpan(this Activity activity) { var jaegerTags = new TagEnumerationState { Tags = PooledList <JaegerTag> .Create(), }; activity.EnumerateTags(ref jaegerTags); string peerServiceName = null; if (activity.Kind == ActivityKind.Client || activity.Kind == ActivityKind.Producer) { // If priority = 0 that means peer.service may have already been included in tags var addPeerServiceTag = jaegerTags.PeerServicePriority > 0; var hostNameOrIpAddress = jaegerTags.HostName ?? jaegerTags.IpAddress; // peer.service has not already been included, but net.peer.name/ip and optionally net.peer.port are present if ((jaegerTags.PeerService == null || addPeerServiceTag) && hostNameOrIpAddress != null) { peerServiceName = jaegerTags.Port == default ? hostNameOrIpAddress : $"{hostNameOrIpAddress}:{jaegerTags.Port}"; // Add the peer.service tag addPeerServiceTag = true; } if (peerServiceName == null && jaegerTags.PeerService != null) { peerServiceName = jaegerTags.PeerService; } if (peerServiceName != null && addPeerServiceTag) { PooledList <JaegerTag> .Add(ref jaegerTags.Tags, new JaegerTag(SemanticConventions.AttributePeerService, JaegerTagType.STRING, vStr : peerServiceName)); } } // The Span.Kind must translate into a tag. // See https://opentracing.io/specification/conventions/ if (activity.Kind != ActivityKind.Internal) { string spanKind = null; if (activity.Kind == ActivityKind.Server) { spanKind = "server"; } else if (activity.Kind == ActivityKind.Client) { spanKind = "client"; } else if (activity.Kind == ActivityKind.Consumer) { spanKind = "consumer"; } else if (activity.Kind == ActivityKind.Producer) { spanKind = "producer"; } if (spanKind != null) { PooledList <JaegerTag> .Add(ref jaegerTags.Tags, new JaegerTag("span.kind", JaegerTagType.STRING, vStr : spanKind)); } } var activitySource = activity.Source; if (!string.IsNullOrEmpty(activitySource.Name)) { PooledList <JaegerTag> .Add(ref jaegerTags.Tags, new JaegerTag("library.name", JaegerTagType.STRING, vStr : activitySource.Name)); if (!string.IsNullOrEmpty(activitySource.Version)) { PooledList <JaegerTag> .Add(ref jaegerTags.Tags, new JaegerTag("library.version", JaegerTagType.STRING, vStr : activitySource.Version)); } } var traceId = Int128.Empty; var spanId = Int128.Empty; var parentSpanId = Int128.Empty; if (activity.IdFormat == ActivityIdFormat.W3C) { // TODO: The check above should be enforced by the usage of the exporter. Perhaps enforce at higher-level. traceId = new Int128(activity.TraceId); spanId = new Int128(activity.SpanId); parentSpanId = new Int128(activity.ParentSpanId); } return(new JaegerSpan( peerServiceName: peerServiceName, traceIdLow: traceId.Low, traceIdHigh: traceId.High, spanId: spanId.Low, parentSpanId: parentSpanId.Low, operationName: activity.DisplayName, flags: (activity.Context.TraceFlags & ActivityTraceFlags.Recorded) > 0 ? 0x1 : 0, startTime: ToEpochMicroseconds(activity.StartTimeUtc), duration: (long)activity.Duration.TotalMilliseconds * 1000, references: activity.ToJaegerSpanRefs(), tags: jaegerTags.Tags, logs: activity.ToJaegerLogs())); }
private const long UnixEpochMicroseconds = UnixEpochTicks / TicksPerMicrosecond; // 62,135,596,800,000,000 public static JaegerSpan ToJaegerSpan(this Activity activity) { var jaegerTags = new TagEnumerationState { Tags = PooledList <JaegerTag> .Create(), }; activity.EnumerateTags(ref jaegerTags); string peerServiceName = null; if (activity.Kind == ActivityKind.Client || activity.Kind == ActivityKind.Producer) { PeerServiceResolver.Resolve(ref jaegerTags, out peerServiceName, out bool addAsTag); if (peerServiceName != null && addAsTag) { PooledList <JaegerTag> .Add(ref jaegerTags.Tags, new JaegerTag(SemanticConventions.AttributePeerService, JaegerTagType.STRING, vStr : peerServiceName)); } } // The Span.Kind must translate into a tag. // See https://opentracing.io/specification/conventions/ if (activity.Kind != ActivityKind.Internal) { string spanKind = null; if (activity.Kind == ActivityKind.Server) { spanKind = "server"; } else if (activity.Kind == ActivityKind.Client) { spanKind = "client"; } else if (activity.Kind == ActivityKind.Consumer) { spanKind = "consumer"; } else if (activity.Kind == ActivityKind.Producer) { spanKind = "producer"; } if (spanKind != null) { PooledList <JaegerTag> .Add(ref jaegerTags.Tags, new JaegerTag("span.kind", JaegerTagType.STRING, vStr : spanKind)); } } var activitySource = activity.Source; if (!string.IsNullOrEmpty(activitySource.Name)) { PooledList <JaegerTag> .Add(ref jaegerTags.Tags, new JaegerTag("library.name", JaegerTagType.STRING, vStr : activitySource.Name)); if (!string.IsNullOrEmpty(activitySource.Version)) { PooledList <JaegerTag> .Add(ref jaegerTags.Tags, new JaegerTag("library.version", JaegerTagType.STRING, vStr : activitySource.Version)); } } var traceId = Int128.Empty; var spanId = Int128.Empty; var parentSpanId = Int128.Empty; if (activity.IdFormat == ActivityIdFormat.W3C) { // TODO: The check above should be enforced by the usage of the exporter. Perhaps enforce at higher-level. traceId = new Int128(activity.TraceId); spanId = new Int128(activity.SpanId); parentSpanId = new Int128(activity.ParentSpanId); } return(new JaegerSpan( peerServiceName: peerServiceName, traceIdLow: traceId.Low, traceIdHigh: traceId.High, spanId: spanId.Low, parentSpanId: parentSpanId.Low, operationName: activity.DisplayName, flags: (activity.Context.TraceFlags & ActivityTraceFlags.Recorded) > 0 ? 0x1 : 0, startTime: ToEpochMicroseconds(activity.StartTimeUtc), duration: (long)activity.Duration.TotalMilliseconds * 1000, references: activity.ToJaegerSpanRefs(), tags: jaegerTags.Tags, logs: activity.ToJaegerLogs())); }
public RemoteDependencyData(int version, Activity activity, ref TagEnumerationState monitorTags) : base(version) { string httpUrl = null; string dependencyName; if (monitorTags.activityType == PartBType.Http) { httpUrl = monitorTags.PartBTags.GetDependencyUrl(); dependencyName = monitorTags.PartBTags.GetHttpDependencyName(httpUrl) ?? activity.DisplayName; } else { dependencyName = activity.DisplayName; } Name = dependencyName; Id = activity.Context.SpanId.ToHexString(); Duration = activity.Duration.ToString("c", CultureInfo.InvariantCulture); Success = activity.GetStatus().StatusCode != StatusCode.Error; switch (monitorTags.activityType) { case PartBType.Http: Data = httpUrl; Target = monitorTags.PartBTags.GetDependencyTarget(PartBType.Http); Type = "Http"; 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); Data = depDataAndType[0]?.ToString(); Target = monitorTags.PartBTags.GetDbDependencyTarget(); 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); Data = depInfo[0]?.ToString(); Type = depInfo[1]?.ToString(); ResultCode = depInfo[2]?.ToString(); break; case PartBType.Messaging: depDataAndType = AzMonList.GetTagValues(ref monitorTags.PartBTags, SemanticConventions.AttributeMessagingUrl, SemanticConventions.AttributeMessagingSystem); Data = depDataAndType[0]?.ToString(); Type = depDataAndType[1]?.ToString(); break; } if (activity.Kind == ActivityKind.Internal && activity.Parent != null) { Type = "InProc"; } Properties = new ChangeTrackingDictionary <string, string>(); Measurements = new ChangeTrackingDictionary <string, double>(); TraceHelper.AddActivityLinksToPartCTags(activity.Links, ref monitorTags.PartCTags); TraceHelper.AddPropertiesToTelemetry(Properties, ref monitorTags.PartCTags); }
private const long UnixEpochMicroseconds = UnixEpochTicks / TicksPerMicrosecond; // 62,135,596,800,000,000 public static JaegerSpan ToJaegerSpan(this Activity activity) { var jaegerTags = new TagEnumerationState { Tags = PooledList <JaegerTag> .Create(), }; activity.EnumerateTags(ref jaegerTags); if (activity.Status != ActivityStatusCode.Unset) { if (activity.Status == ActivityStatusCode.Ok) { PooledList <JaegerTag> .Add( ref jaegerTags.Tags, new JaegerTag(SpanAttributeConstants.StatusCodeKey, JaegerTagType.STRING, vStr : "OK")); } else { PooledList <JaegerTag> .Add( ref jaegerTags.Tags, new JaegerTag(SpanAttributeConstants.StatusCodeKey, JaegerTagType.STRING, vStr : "ERROR")); PooledList <JaegerTag> .Add( ref jaegerTags.Tags, new JaegerTag(JaegerErrorFlagTagName, JaegerTagType.BOOL, vBool : true)); PooledList <JaegerTag> .Add( ref jaegerTags.Tags, new JaegerTag(SpanAttributeConstants.StatusDescriptionKey, JaegerTagType.STRING, vStr : activity.StatusDescription ?? string.Empty)); } } else if (jaegerTags.StatusCode.HasValue && jaegerTags.StatusCode != StatusCode.Unset) { PooledList <JaegerTag> .Add( ref jaegerTags.Tags, new JaegerTag( SpanAttributeConstants.StatusCodeKey, JaegerTagType.STRING, vStr : StatusHelper.GetTagValueForStatusCode(jaegerTags.StatusCode.Value))); if (jaegerTags.StatusCode == StatusCode.Error) { PooledList <JaegerTag> .Add( ref jaegerTags.Tags, new JaegerTag(JaegerErrorFlagTagName, JaegerTagType.BOOL, vBool : true)); PooledList <JaegerTag> .Add( ref jaegerTags.Tags, new JaegerTag(SpanAttributeConstants.StatusDescriptionKey, JaegerTagType.STRING, vStr : jaegerTags.StatusDescription ?? string.Empty)); } } string peerServiceName = null; if (activity.Kind == ActivityKind.Client || activity.Kind == ActivityKind.Producer) { PeerServiceResolver.Resolve(ref jaegerTags, out peerServiceName, out bool addAsTag); if (peerServiceName != null && addAsTag) { PooledList <JaegerTag> .Add(ref jaegerTags.Tags, new JaegerTag(SemanticConventions.AttributePeerService, JaegerTagType.STRING, vStr : peerServiceName)); } } // The Span.Kind must translate into a tag. // See https://opentracing.io/specification/conventions/ if (activity.Kind != ActivityKind.Internal) { string spanKind = null; if (activity.Kind == ActivityKind.Server) { spanKind = "server"; } else if (activity.Kind == ActivityKind.Client) { spanKind = "client"; } else if (activity.Kind == ActivityKind.Consumer) { spanKind = "consumer"; } else if (activity.Kind == ActivityKind.Producer) { spanKind = "producer"; } if (spanKind != null) { PooledList <JaegerTag> .Add(ref jaegerTags.Tags, new JaegerTag("span.kind", JaegerTagType.STRING, vStr : spanKind)); } } var activitySource = activity.Source; if (!string.IsNullOrEmpty(activitySource.Name)) { PooledList <JaegerTag> .Add(ref jaegerTags.Tags, new JaegerTag("otel.library.name", JaegerTagType.STRING, vStr : activitySource.Name)); if (!string.IsNullOrEmpty(activitySource.Version)) { PooledList <JaegerTag> .Add(ref jaegerTags.Tags, new JaegerTag("otel.library.version", JaegerTagType.STRING, vStr : activitySource.Version)); } } var traceId = Int128.Empty; var spanId = Int128.Empty; var parentSpanId = Int128.Empty; if (activity.IdFormat == ActivityIdFormat.W3C) { // TODO: The check above should be enforced by the usage of the exporter. Perhaps enforce at higher-level. traceId = new Int128(activity.TraceId); spanId = new Int128(activity.SpanId); if (activity.ParentSpanId != default) { parentSpanId = new Int128(activity.ParentSpanId); } } return(new JaegerSpan( peerServiceName: peerServiceName, traceIdLow: traceId.Low, traceIdHigh: traceId.High, spanId: spanId.Low, parentSpanId: parentSpanId.Low, operationName: activity.DisplayName, flags: (activity.Context.TraceFlags & ActivityTraceFlags.Recorded) > 0 ? 0x1 : 0, startTime: ToEpochMicroseconds(activity.StartTimeUtc), duration: activity.Duration.Ticks / TicksPerMicrosecond, references: activity.ToJaegerSpanRefs(), tags: jaegerTags.Tags, logs: activity.ToJaegerLogs())); }