/// <summary> /// Initializes a new instance of the <see cref="DependencyTelemetry"/> class by cloning an existing instance. /// </summary> /// <param name="source">Source instance of <see cref="DependencyTelemetry"/> to clone from.</param> private DependencyTelemetry(DependencyTelemetry source) { this.InternalData = source.InternalData.DeepClone(); this.context = source.context.DeepClone(this.InternalData.properties); this.Sequence = source.Sequence; this.Timestamp = source.Timestamp; this.samplingPercentage = source.samplingPercentage; this.successFieldSet = source.successFieldSet; }
/// <summary> /// Initializes a new instance of the <see cref="DependencyTelemetry"/> class. /// </summary> public DependencyTelemetry() { this.Data = new RemoteDependencyData() { kind = DataPointType.Aggregation }; this.context = new TelemetryContext(this.Data.properties, new Dictionary <string, string>()); this.Data.dependencyKind = BondDependencyKind.Other; }
/// <summary> /// Initializes a new instance of the <see cref="DependencyTelemetry"/> class. /// </summary> public DependencyTelemetry() { this.Data = new RemoteDependencyData() { kind = DataPointType.Aggregation }; this.context = new TelemetryContext(this.Data.properties, new Dictionary <string, string>()); this.Data.dependencyKind = BondDependencyKind.Other; this.Id = Convert.ToBase64String(BitConverter.GetBytes(WeakConcurrentRandom.Instance.Next())); }
public void LinksAreTruncatedWhenCannotFitInMaxLength(string telemetryType) { using ActivitySource activitySource = new ActivitySource(ActivitySourceName); List <ActivityLink> links = new List <ActivityLink>(); // Arbitrary number > 100 int numberOfLinks = 150; for (int i = 0; i < numberOfLinks; i++) { ActivityLink activityLink = new ActivityLink(new ActivityContext( ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.None), null); links.Add(activityLink); } string expectedMSlinks = GetExpectedMSlinks(links.GetRange(0, MaxLinksAllowed)); string actualMSlinks = null; using var activity = activitySource.StartActivity( ActivityName, ActivityKind.Client, parentContext: default, null, links, startTime: DateTime.UtcNow); var monitorTags = TraceHelper.EnumerateActivityTags(activity); if (telemetryType == "RequestData") { var requestData = new RequestData(2, activity, ref monitorTags); Assert.True(requestData.Properties.TryGetValue(msLinks, out actualMSlinks)); } if (telemetryType == "RemoteDependencyData") { var remoteDependencyData = new RemoteDependencyData(2, activity, ref monitorTags); Assert.True(remoteDependencyData.Properties.TryGetValue(msLinks, out actualMSlinks)); } // Check for valid JSON string try { JsonDocument document = JsonDocument.Parse(actualMSlinks); } catch (Exception) { Assert.True(false, "_MSlinks should be a JSON formatted string"); } Assert.True(actualMSlinks.Length <= MaxLength); Assert.Equal(actualMSlinks, expectedMSlinks); }
private static MonitorBase GenerateTelemetryData(Activity activity) { var telemetryType = activity.GetTelemetryType(); var activityType = activity.TagObjects.ToAzureMonitorTags(out var partBTags, out var PartCTags); MonitorBase telemetry = new MonitorBase { BaseType = Telemetry_Base_Type_Mapping[telemetryType] }; if (telemetryType == TelemetryType.Request) { var url = activity.Kind == ActivityKind.Server ? HttpHelper.GetUrl(partBTags) : GetMessagingUrl(partBTags); var statusCode = HttpHelper.GetHttpStatusCode(partBTags); var success = HttpHelper.GetSuccessFromHttpStatusCode(statusCode); var request = new RequestData(2, activity.Context.SpanId.ToHexString(), activity.Duration.ToString("c", CultureInfo.InvariantCulture), success, statusCode) { Name = activity.DisplayName, Url = url, // TODO: Handle request.source. }; // TODO: Handle activity.TagObjects, extract well-known tags AddPropertiesToTelemetry(request.Properties, PartCTags); telemetry.BaseData = request; } else if (telemetryType == TelemetryType.Dependency) { var dependency = new RemoteDependencyData(2, activity.DisplayName, activity.Duration.ToString("c", CultureInfo.InvariantCulture)) { Id = activity.Context.SpanId.ToHexString() }; // TODO: Handle activity.TagObjects // ExtractPropertiesFromTags(dependency.Properties, activity.Tags); if (activityType == PartBType.Http) { dependency.Data = HttpHelper.GetUrl(partBTags); dependency.Type = "HTTP"; // TODO: Parse for storage / SB. var statusCode = HttpHelper.GetHttpStatusCode(partBTags); dependency.ResultCode = statusCode; dependency.Success = HttpHelper.GetSuccessFromHttpStatusCode(statusCode); } // TODO: Handle dependency.target. AddPropertiesToTelemetry(dependency.Properties, PartCTags); telemetry.BaseData = dependency; } return(telemetry); }
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); }
/// <summary> /// Initializes a new instance of the <see cref="DependencyTelemetry"/> class by cloning an existing instance. /// </summary> /// <param name="source">Source instance of <see cref="DependencyTelemetry"/> to clone from.</param> private DependencyTelemetry(DependencyTelemetry source) { this.InternalData = source.InternalData.DeepClone(); this.context = source.context.DeepClone(this.InternalData.properties); this.Sequence = source.Sequence; this.Timestamp = source.Timestamp; this.samplingPercentage = source.samplingPercentage; this.successFieldSet = source.successFieldSet; // Only clone the details if the source has had details initialized if (source.operationDetails != null) { this.operationDetails = new ConcurrentDictionary <string, object>(source.operationDetails); } }
private MonitorBase GenerateTelemetryData(Activity activity) { MonitorBase telemetry = new MonitorBase(); var telemetryType = activity.GetTelemetryType(); telemetry.BaseType = Telemetry_Base_Type_Mapping[telemetryType]; string url = GetHttpUrl(activity.Tags); if (telemetryType == TelemetryType.Request) { var request = new RequestData(2, activity.Context.SpanId.ToHexString(), activity.Duration.ToString("c", CultureInfo.InvariantCulture), activity.GetStatus().IsOk, activity.GetStatusCode()) { Name = activity.DisplayName, Url = url, // TODO: Handle request.source. }; // TODO: Handle activity.TagObjects ExtractPropertiesFromTags(request.Properties, activity.Tags); telemetry.BaseData = request; } else if (telemetryType == TelemetryType.Dependency) { var dependency = new RemoteDependencyData(2, activity.DisplayName, activity.Duration) { Id = activity.Context.SpanId.ToHexString(), Success = activity.GetStatus().IsOk }; // TODO: Handle activity.TagObjects ExtractPropertiesFromTags(dependency.Properties, activity.Tags); if (url != null) { dependency.Data = url; dependency.Type = "HTTP"; // TODO: Parse for storage / SB. dependency.ResultCode = activity.GetStatusCode(); } // TODO: Handle dependency.target. telemetry.BaseData = dependency; } return(telemetry); }
public void ValidateDBDependencyType(string dbSystem) { using ActivitySource activitySource = new ActivitySource(ActivitySourceName); using var activity = activitySource.StartActivity( ActivityName, ActivityKind.Server, parentContext: new ActivityContext(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.Recorded), startTime: DateTime.UtcNow); activity.SetTag(SemanticConventions.AttributeDbSystem, dbSystem); var monitorTags = TraceHelper.EnumerateActivityTags(activity); var remoteDependencyDataType = new RemoteDependencyData(2, activity, ref monitorTags).Type; var expectedType = RemoteDependencyData.s_sqlDbs.Contains(dbSystem) ? "SQL" : dbSystem; Assert.Equal(expectedType, remoteDependencyDataType); }
public void DependencyTypeisSetToInProcForInternalSpanWithParent() { using ActivitySource activitySource = new ActivitySource(ActivitySourceName); using var parentActivity = activitySource.StartActivity("ParentActivity", ActivityKind.Internal); using var childActivity = activitySource.StartActivity("ChildActivity", ActivityKind.Internal); var monitorTagsParent = TraceHelper.EnumerateActivityTags(parentActivity); var remoteDependencyDataTypeForParent = new RemoteDependencyData(2, parentActivity, ref monitorTagsParent).Type; Assert.Null(remoteDependencyDataTypeForParent); var monitorTagsChild = TraceHelper.EnumerateActivityTags(childActivity); var remoteDependencyDataTypeForChild = new RemoteDependencyData(2, childActivity, ref monitorTagsChild).Type; Assert.Equal("InProc", remoteDependencyDataTypeForChild); }
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); }
public void HttpDependencyNameIsActivityDisplayNameByDefault() { using ActivitySource activitySource = new ActivitySource(ActivitySourceName); using var activity = activitySource.StartActivity( ActivityName, ActivityKind.Client, parentContext: new ActivityContext(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.Recorded), startTime: DateTime.UtcNow); activity.SetTag(SemanticConventions.AttributeHttpMethod, "GET"); activity.DisplayName = "HTTP GET"; var monitorTags = TraceHelper.EnumerateActivityTags(activity); var remoteDependencyDataName = new RemoteDependencyData(2, activity, ref monitorTags).Name; Assert.Equal(activity.DisplayName, remoteDependencyDataName); }
public void TelemetryPartBPropertiesDoesNotContainMSLinksWhenActivityHasNoLinks(string telemetryType) { using ActivitySource activitySource = new ActivitySource(ActivitySourceName); using var activity = activitySource.StartActivity( ActivityName, ActivityKind.Client, parentContext: default, startTime: DateTime.UtcNow); var monitorTags = TraceHelper.EnumerateActivityTags(activity); if (telemetryType == "RequestData") { var telemetryPartBRequestData = new RequestData(2, activity, ref monitorTags); Assert.False(telemetryPartBRequestData.Properties.TryGetValue(msLinks, out var mslinks)); } if (telemetryType == "RemoteDependencyData") { var telemetryPartBRemoteDependencyData = new RemoteDependencyData(2, activity, ref monitorTags); Assert.False(telemetryPartBRemoteDependencyData.Properties.TryGetValue(msLinks, out var mslinks)); } }
public void ValidateStatusForAzureMonitorTrace(string activityStatusCode, string activityStatusDescription) { using ActivitySource activitySource = new ActivitySource(ActivitySourceName); using var activity = activitySource.StartActivity( ActivityName, ActivityKind.Server, parentContext: new ActivityContext(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.Recorded), startTime: DateTime.UtcNow); activity.SetTag("otel.status_code", activityStatusCode); activity.SetTag("otel.status_description", activityStatusDescription); activity.SetTag(SemanticConventions.AttributeHttpUrl, "https://www.foo.bar/search"); var monitorTags = TraceHelper.EnumerateActivityTags(activity); var requestData = new RequestData(2, activity, ref monitorTags); var remoteDependencyData = new RemoteDependencyData(2, activity, ref monitorTags); Assert.Equal(activity.GetStatus().StatusCode != StatusCode.Error, requestData.Success); Assert.Equal(activity.GetStatus().StatusCode != StatusCode.Error, remoteDependencyData.Success); }
public void TelemetryPartBPropertiesContainsMSLinksWhenActivityHasLinks(string telemetryType) { using ActivitySource activitySource = new ActivitySource(ActivitySourceName); ActivityLink activityLink = new ActivityLink(new ActivityContext( ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.None), null); List <ActivityLink> links = new List <ActivityLink>(); links.Add(activityLink); using var activity = activitySource.StartActivity( ActivityName, ActivityKind.Client, parentContext: default, null, links, startTime: DateTime.UtcNow); string expectedMSlinks = GetExpectedMSlinks(links); string actualMSlinks = null; var monitorTags = TraceHelper.EnumerateActivityTags(activity); if (telemetryType == "RequestData") { var telemetryPartBRequestData = new RequestData(2, activity, ref monitorTags); Assert.True(telemetryPartBRequestData.Properties.TryGetValue(msLinks, out actualMSlinks)); } if (telemetryType == "RemoteDependencyData") { var telemetryPartBRemoteDependencyData = new RemoteDependencyData(2, activity, ref monitorTags); Assert.True(telemetryPartBRemoteDependencyData.Properties.TryGetValue(msLinks, out actualMSlinks)); } Assert.Equal(expectedMSlinks, actualMSlinks); }
private static MonitorBase GenerateTelemetryData(Activity activity) { var telemetryType = activity.GetTelemetryType(); var monitorTags = new TagEnumerationState { PartBTags = AzMonList.Initialize(), PartCTags = AzMonList.Initialize() }; activity.EnumerateTags(ref monitorTags); MonitorBase telemetry = new MonitorBase { BaseType = Telemetry_Base_Type_Mapping[telemetryType] }; if (telemetryType == TelemetryType.Request) { monitorTags.PartBTags.GenerateUrlAndAuthority(out var url, out var urlAuthority); var statusCode = AzMonList.GetTagValue(ref monitorTags.PartBTags, SemanticConventions.AttributeHttpStatusCode)?.ToString() ?? "0"; var success = activity.GetStatus() != Status.Error; var request = new RequestData(2, activity.Context.SpanId.ToHexString(), activity.Duration.ToString("c", CultureInfo.InvariantCulture), success, statusCode) { Name = activity.DisplayName, Url = url, Source = urlAuthority }; // TODO: Handle activity.TagObjects, extract well-known tags AddPropertiesToTelemetry(request.Properties, monitorTags.PartCTags); telemetry.BaseData = request; } else if (telemetryType == TelemetryType.Dependency) { 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, monitorTags.PartCTags); telemetry.BaseData = dependency; } return(telemetry); }
/// <summary> /// Create handler for dependency telemetry. /// </summary> private Action <ITelemetry> CreateHandlerForDependencyTelemetry(EventSource eventSource, MethodInfo writeGenericMethod, Type eventSourceOptionsType, PropertyInfo eventSourceOptionsKeywordsProperty) { var eventSourceOptions = Activator.CreateInstance(eventSourceOptionsType); var keywords = Keywords.Dependencies; eventSourceOptionsKeywordsProperty.SetValue(eventSourceOptions, keywords); var dummyDependencyData = new RemoteDependencyData(); var writeMethod = writeGenericMethod.MakeGenericMethod(new { PartA_iKey = this.dummyPartAiKeyValue, PartA_Tags = this.dummyPartATagsValue, PartB_RemoteDependencyData = new { // The properties and layout should be the same as RemoteDependencyData_types.cs dummyDependencyData.ver, dummyDependencyData.name, dummyDependencyData.id, dummyDependencyData.resultCode, dummyDependencyData.duration, dummyDependencyData.success, dummyDependencyData.data, dummyDependencyData.target, dummyDependencyData.type, dummyDependencyData.properties, dummyDependencyData.measurements, }, PartA_flags = this.dummyPartAFlagsValue, }.GetType()); return((item) => { if (this.EventSourceInternal.IsEnabled(EventLevel.Verbose, keywords)) { var telemetryItem = item as DependencyTelemetry; if (item.Context.GlobalPropertiesValue != null) { Utils.CopyDictionary(item.Context.GlobalProperties, telemetryItem.Properties); } item.Sanitize(); var data = telemetryItem.InternalData; var extendedData = new { // The properties and layout should be the same as the anonymous type in the above MakeGenericMethod PartA_iKey = telemetryItem.Context.InstrumentationKey, PartA_Tags = telemetryItem.Context.SanitizedTags, PartB_RemoteDependencyData = new { data.ver, data.name, data.id, data.resultCode, data.duration, data.success, data.data, data.target, data.type, data.properties, data.measurements, }, PartA_flags = telemetryItem.Context.Flags, }; writeMethod.Invoke(eventSource, new object[] { DependencyTelemetry.TelemetryName, eventSourceOptions, extendedData }); } }); }
/// <summary> /// Initializes a new instance of the <see cref="DependencyTelemetry"/> class. /// </summary> public DependencyTelemetry() { this.InternalData = new RemoteDependencyData(); this.context = new TelemetryContext(this.InternalData.properties); this.GenerateId(); }
/// <summary> /// Initializes a new instance of the <see cref="DependencyTelemetry"/> class. /// </summary> public DependencyTelemetry() { this.InternalData = new RemoteDependencyData(); this.context = new TelemetryContext(this.InternalData.properties); this.Id = Convert.ToBase64String(BitConverter.GetBytes(WeakConcurrentRandom.Instance.Next())); }
/// <summary> /// Initializes a new instance of the <see cref="DependencyTelemetry"/> class. /// </summary> public DependencyTelemetry() { this.Data = new RemoteDependencyData() { kind = DataPointType.Aggregation }; this.context = new TelemetryContext(this.Data.properties, new Dictionary<string, string>()); this.Data.dependencyKind = BondDependencyKind.Other; }