OperationTelemetry SetIdAndParentId(OperationTelemetry telemetry, string id, string parentId, DateTimeOffset timeStamp) { telemetry.Id = id; telemetry.Context.Operation.ParentId = parentId; telemetry.Timestamp = timeStamp; return(telemetry); }
/// <summary> /// Set the duration given a timestamp from a high-resolution <see cref="Stopwatch"/>. /// </summary> /// <param name="telemetry">Telemetry item object to update.</param> /// <param name="timestamp">The high resolution timestamp.</param> private static void StopImpl(OperationTelemetry telemetry, long timestamp) { long stopWatchTicksDiff = timestamp - telemetry.BeginTimeInTicks; double durationInTicks = stopWatchTicksDiff * StopwatchTicksToTimeSpanTicks; StopImpl(telemetry, TimeSpan.FromTicks((long)Math.Round(durationInTicks))); }
/// <summary> /// An extension to telemetry item that starts the timer for the the respective telemetry. /// </summary> /// <param name="telemetry">Telemetry item object that calls this extension method.</param> public static void Start(this OperationTelemetry telemetry) { var startTime = Clock.Instance.Time; telemetry.StartTime = startTime; telemetry.Timestamp = startTime; }
internal static void UpdateTelemetryHttpCorrelationProtocol(ITelemetry telemetry, HttpCorrelationProtocolTraceContext context) { OperationTelemetry opTelemetry = telemetry as OperationTelemetry; bool initializeFromCurrent = opTelemetry != null; if (initializeFromCurrent) { initializeFromCurrent &= !(opTelemetry is DependencyTelemetry dependency && dependency.Type == SqlRemoteDependencyType && dependency.Context.GetInternalContext().SdkVersion .StartsWith(RddDiagnosticSourcePrefix, StringComparison.Ordinal)); } if (initializeFromCurrent) { opTelemetry.Id = !string.IsNullOrEmpty(opTelemetry.Id) ? opTelemetry.Id : context.TelemetryId; telemetry.Context.Operation.ParentId = !string.IsNullOrEmpty(telemetry.Context.Operation.ParentId) ? telemetry.Context.Operation.ParentId : context.TelemetryContextOperationParentId; } else { telemetry.Context.Operation.Id = !string.IsNullOrEmpty(telemetry.Context.Operation.Id) ? telemetry.Context.Operation.Id : context.TelemetryContextOperationId; if (telemetry is ExceptionTelemetry) { telemetry.Context.Operation.ParentId = context.TelemetryId; } else { telemetry.Context.Operation.ParentId = !string.IsNullOrEmpty(telemetry.Context.Operation.ParentId) ? telemetry.Context.Operation.ParentId : context.TelemetryContextOperationParentId; } } }
static List <OperationTelemetry> GetCorrelationSortedList(OperationTelemetry parent, List <OperationTelemetry> current) { var result = new List <OperationTelemetry>(); if (current.Count != 0) { foreach (var some in current) { if (parent.Id == some.Context.Operation.ParentId) { Console.WriteLine("match"); } } IOrderedEnumerable <OperationTelemetry> nexts = current.Where(p => p.Context.Operation.ParentId == parent.Id).OrderBy(p => p.Timestamp.Ticks); foreach (OperationTelemetry next in nexts) { current.RemoveOperationTelemetry(next); result.Add(next); var childResult = GetCorrelationSortedList(next, current); result.AddRange(childResult); } } return(result); }
/// <summary> /// Generate random operation Id and set it to OperationContext. /// </summary> /// <param name="telemetry">Telemetry to initialize Operation id for.</param> public static void GenerateOperationId(this OperationTelemetry telemetry) { if (telemetry == null) { throw new ArgumentNullException(nameof(telemetry)); } telemetry.GenerateId(); }
public async Task <bool?> Handle(Update update, OperationTelemetry telemetry, CancellationToken cancellationToken = default) { var inlineQuery = update.InlineQuery; telemetry.Properties["uid"] = inlineQuery.From?.Id.ToString(); telemetry.Properties["username"] = inlineQuery.From?.Username; telemetry.Properties["query"] = inlineQuery.Query; return(await HandlerExtentions <bool?> .Handle(myInlineQueryHandlers, inlineQuery, new object(), cancellationToken).ConfigureAwait(false)); }
/// <summary> /// An extension to telemetry item that starts the timer for the the respective telemetry. /// </summary> /// <param name="telemetry">Telemetry item object that calls this extension method.</param> public static void Start(this OperationTelemetry telemetry) { telemetry.Timestamp = DateTimeOffset.UtcNow; // Begin time is used internally for calculating duration of operation at the end call, // and hence is stored using higher precision Clock. // Stopwatch.GetTimestamp() is used (instead of ElapsedTicks) as it is thread-safe. telemetry.BeginTimeInTicks = Stopwatch.GetTimestamp(); }
protected virtual void PopulateTags(Activity activity, OperationTelemetry telemetry) { foreach (var item in activity.Tags) { if (!telemetry.Properties.ContainsKey(item.Key)) { telemetry.Properties[item.Key] = item.Value; } } }
public async Task <bool?> Handle(Update update, OperationTelemetry telemetry, CancellationToken cancellationToken = default) { var chosenInlineResult = update.ChosenInlineResult; telemetry.Properties["uid"] = chosenInlineResult.From?.Id.ToString(); telemetry.Properties["username"] = chosenInlineResult.From?.Username; telemetry.Properties["query"] = chosenInlineResult.Query; telemetry.Properties["result"] = chosenInlineResult.ResultId; return(await HandlerExtentions <bool?> .Handle(myChosenInlineResultHandlers, chosenInlineResult, new object(), cancellationToken).ConfigureAwait(false)); }
/// <summary> /// An extension method to telemetry item that stops the timer and computes the duration of the request or dependency. /// </summary> /// <param name="telemetry">Telemetry item object that calls this extension method.</param> public static void Stop(this OperationTelemetry telemetry) { if (telemetry.BeginTimeInTicks != 0L) { StopImpl(telemetry, timestamp: Stopwatch.GetTimestamp()); } else { StopImpl(telemetry, duration: TimeSpan.Zero); } }
/// <summary> /// An extension method to telemetry item that stops the timer and computes the duration of the request or dependency. /// </summary> /// <param name="telemetry">Telemetry item object that calls this extension method.</param> /// <param name="timestamp">A high-resolution timestamp from <see cref="Stopwatch"/>.</param> public static void Stop(this OperationTelemetry telemetry, long timestamp) { if (telemetry.BeginTimeInTicks != 0L) { StopImpl(telemetry, timestamp); } else { StopImpl(telemetry, duration: TimeSpan.Zero); } }
/// <summary> /// Record the duration and, optionally, set the timestamp to the current time. /// </summary> /// <param name="telemetry">Telemetry item object to update.</param> /// <param name="duration">The duration of the operation.</param> private static void StopImpl(OperationTelemetry telemetry, TimeSpan duration) { telemetry.Duration = duration; if (telemetry.Timestamp == DateTimeOffset.MinValue) { telemetry.Timestamp = PreciseTimestamp.GetUtcNow(); } RichPayloadEventSource.Log.ProcessOperationStop(telemetry); }
static void UpsertTelemetryProperty(OperationTelemetry operationTelemetry, string propertyName, string propertyValue) { if (operationTelemetry.Properties.ContainsKey(propertyName)) { operationTelemetry.Properties[propertyName] = propertyValue; } else { operationTelemetry.Properties.Add(propertyName, propertyValue); } }
/// <summary> /// An extension to telemetry item that initializes the timer for the respective telemetry /// using a timestamp from a high-resolution <see cref="Stopwatch"/>. /// </summary> /// <param name="telemetry">Telemetry item object that calls this extension method.</param> /// <param name="timestamp">A high-resolution timestamp from <see cref="Stopwatch"/>.</param> public static void Start(this OperationTelemetry telemetry, long timestamp) { telemetry.Timestamp = PreciseTimestamp.GetUtcNow(); // Begin time is used internally for calculating duration of operation at the end call, // and hence is stored using higher precision Clock. // Stopwatch.GetTimestamp() is used (instead of ElapsedTicks) as it is thread-safe. telemetry.BeginTimeInTicks = timestamp; RichPayloadEventSource.Log.ProcessOperationStart(telemetry); }
/// <summary> /// An extension method to telemetry item that stops the timer and computes the duration of the request or dependency. /// </summary> /// <param name="telemetry">Telemetry item object that calls this extension method.</param> public static void Stop(this OperationTelemetry telemetry) { if (telemetry.Timestamp != DateTimeOffset.MinValue) { telemetry.Duration = DateTimeOffset.UtcNow - telemetry.Timestamp; } else { telemetry.Timestamp = DateTimeOffset.UtcNow; telemetry.Duration = TimeSpan.Zero; } }
private static void SetOperationContext(Span span, OperationTelemetry telemetry) { string traceId = BytesStringToHexString(span.TraceId); telemetry.Context.Operation.Id = BytesStringToHexString(span.TraceId); if (span.ParentSpanId != null && !span.ParentSpanId.IsEmpty) { telemetry.Context.Operation.ParentId = FormatId(traceId, BytesStringToHexString(span.ParentSpanId)); } telemetry.Id = FormatId(traceId, BytesStringToHexString(span.SpanId)); }
/// <summary> /// An extension method to telemetry item that stops the timer and computes the duration of the request or dependency. /// </summary> /// <param name="telemetry">Telemetry item object that calls this extension method.</param> public static void Stop(this OperationTelemetry telemetry) { if (telemetry.StartTime != DateTimeOffset.MinValue) { telemetry.Duration = Clock.Instance.Time - telemetry.StartTime; } else { telemetry.Timestamp = Clock.Instance.Time; telemetry.StartTime = telemetry.Timestamp; telemetry.Duration = TimeSpan.Zero; } }
/// <summary> /// Record the duration and, optionally, set the timestamp to the current time. /// </summary> /// <param name="telemetry">Telemetry item object to update.</param> /// <param name="duration">The duration of the operation.</param> private static void StopImpl(OperationTelemetry telemetry, TimeSpan duration) { telemetry.Duration = duration; if (telemetry.Timestamp == DateTimeOffset.MinValue) { telemetry.Timestamp = DateTimeOffset.UtcNow; } #if !CORE_PCL RichPayloadEventSource.Log.ProcessOperationStop(telemetry); #endif }
private void SetEventHubsProperties(SpanData span, OperationTelemetry telemetry) { string endpoint = null; string queueName = null; foreach (var attribute in span.Attributes) { if (attribute.Key == "peer.address" && attribute.Value is string) { endpoint = (string)attribute.Value; } else if (attribute.Key == "message_bus.destination") { queueName = (string)attribute.Value; } else { AddPropertyWithAdjustedName(telemetry.Properties, attribute.Key, attribute.Value.ToString()); } } string eventHubsInfo = null; // Target/source uniquely identifies the resource, we use both: queueName and endpoint if (endpoint != null && queueName != null) { eventHubsInfo = string.Concat(endpoint, "/", queueName); } if (telemetry is DependencyTelemetry dependency) { dependency.Type = dependency.Type == QueueMessageDependencyType?string.Concat(dependency.Type, " | ", EventHubsDependencyType) : EventHubsDependencyType; if (eventHubsInfo != null) { dependency.Target = eventHubsInfo; } } else if (telemetry is RequestTelemetry request) { if (eventHubsInfo != null) { request.Source = eventHubsInfo; } if (this.TryGetAverageTimeInQueueForBatch(span, out long enqueuedTime)) { request.Metrics["timeSinceEnqueued"] = enqueuedTime; } } }
private void ValidateRootTelemetry(OperationTelemetry operationTelemetry, string expectedOperationId, string expectedId, string expectedOperationParentId, bool isW3C) { Assert.AreEqual(expectedOperationParentId, operationTelemetry.Context.Operation.ParentId); Assert.IsNotNull(operationTelemetry.Context.Operation.Id); Assert.AreEqual(expectedOperationId, operationTelemetry.Context.Operation.Id); if (isW3C) { Assert.IsTrue(W3CUtilities.IsCompatibleW3CTraceId(operationTelemetry.Context.Operation.Id)); } Assert.IsNotNull(operationTelemetry.Id); Assert.AreEqual(expectedId, operationTelemetry.Id); }
/// <summary> /// An extension method to telemetry item that stops the timer and computes the duration of the request or dependency. /// </summary> /// <param name="telemetry">Telemetry item object that calls this extension method.</param> /// <param name="timestamp">A high-resolution timestamp from <see cref="Stopwatch"/>.</param> public static void Stop(this OperationTelemetry telemetry, long timestamp) { if (telemetry == null) { throw new ArgumentNullException(nameof(telemetry)); } if (telemetry.BeginTimeInTicks != 0L) { StopImpl(telemetry, timestamp); } else { StopImpl(telemetry, duration: TimeSpan.Zero); } }
internal static void UpdateTelemetryW3C(ITelemetry telemetry, W3CTraceContext context) { OperationTelemetry opTelemetry = telemetry as OperationTelemetry; bool initializeFromCurrent = opTelemetry != null; if (initializeFromCurrent) { initializeFromCurrent &= !(opTelemetry is DependencyTelemetry dependency && dependency.Type == SqlRemoteDependencyType && dependency.Context.GetInternalContext().SdkVersion .StartsWith(RddDiagnosticSourcePrefix, StringComparison.Ordinal)); } if (!string.IsNullOrEmpty(context.TraceState)) { opTelemetry.Properties["w3c_tracestate"] = context.TraceState; } TraceParent traceParent = context.TraceParent.ToTraceParent(); if (initializeFromCurrent) { if (string.IsNullOrEmpty(opTelemetry.Id)) { opTelemetry.Id = StringUtilities.FormatRequestId(telemetry.Context.Operation.Id, traceParent.SpanId); } if (string.IsNullOrEmpty(context.ParentSpanId)) { telemetry.Context.Operation.ParentId = StringUtilities.FormatRequestId(telemetry.Context.Operation.Id, context.ParentSpanId); } } else { if (telemetry.Context.Operation.Id == null) { telemetry.Context.Operation.Id = traceParent.TraceId; } if (telemetry.Context.Operation.ParentId == null) // TODO check if it works. { telemetry.Context.Operation.ParentId = StringUtilities.FormatRequestId(telemetry.Context.Operation.Id, traceParent.SpanId); } } }
/// <summary> /// An extension method to telemetry item that stops the timer and computes the duration of the request or dependency. /// </summary> /// <param name="telemetry">Telemetry item object that calls this extension method.</param> public static void Stop(this OperationTelemetry telemetry) { if (telemetry.BeginTimeInTicks != 0L) { long stopWatchTicksDiff = Stopwatch.GetTimestamp() - telemetry.BeginTimeInTicks; double durationInMillisecs = stopWatchTicksDiff * 1000 / (double)Stopwatch.Frequency; telemetry.Duration = TimeSpan.FromMilliseconds(durationInMillisecs); } else { telemetry.Duration = TimeSpan.Zero; } if (telemetry.Timestamp == DateTimeOffset.MinValue) { telemetry.Timestamp = DateTimeOffset.UtcNow; } }
private void ValidateRootTelemetry(OperationTelemetry operationTelemetry, string expectedOperationId = "", string expectedOperationParentId = null, bool isW3C = true) { Assert.AreEqual(expectedOperationParentId, operationTelemetry.Context.Operation.ParentId); Assert.IsNotNull(operationTelemetry.Context.Operation.Id); if (!string.IsNullOrEmpty(expectedOperationId)) { Assert.AreEqual(expectedOperationId, operationTelemetry.Context.Operation.Id); } if (isW3C) { Assert.IsTrue(W3CUtilities.IsCompatibleW3CTraceId(operationTelemetry.Context.Operation.Id)); } Assert.IsNotNull(operationTelemetry.Id); // ID is shaped like |TraceID.SpanID. Assert.IsTrue(operationTelemetry.Id.Contains(operationTelemetry.Context.Operation.Id)); }
private static void SetEventHubsProperties(Activity activity, OperationTelemetry telemetry) { string endpoint = null; string queueName = null; foreach (var tag in activity.Tags) { if (tag.Key == "peer.address") { endpoint = tag.Value; } else if (tag.Key == "message_bus.destination") { queueName = tag.Value; } } if (endpoint == null || queueName == null) { return; } // Target uniquely identifies the resource, we use both: queueName and endpoint // with schema used for SQL-dependencies string separator = "/"; if (endpoint.EndsWith(separator, StringComparison.Ordinal)) { separator = string.Empty; } string eventHubInfo = string.Concat(endpoint, separator, queueName); if (telemetry is DependencyTelemetry dependency) { dependency.Target = eventHubInfo; } else if (telemetry is RequestTelemetry request) { request.Source = eventHubInfo; } }
internal static void UpdateTelemetry(ITelemetry telemetry, Activity activity, bool forceUpdate) { if (activity == null) { return; } // Requests and dependnecies are initialized from the current Activity // (i.e. telemetry.Id = current.Id). Activity is created for such requests specifically // Traces, exceptions, events on the other side are children of current activity // There is one exception - SQL DiagnosticSource where current Activity is a parent // for dependency calls. OperationTelemetry opTelemetry = telemetry as OperationTelemetry; bool initializeFromCurrent = opTelemetry != null; if (initializeFromCurrent) { initializeFromCurrent &= !(opTelemetry is DependencyTelemetry dependency && dependency.Type == SqlRemoteDependencyType && dependency.Context.GetInternalContext().SdkVersion .StartsWith(RddDiagnosticSourcePrefix, StringComparison.Ordinal)); } if (telemetry is OperationTelemetry operation) { operation.Properties[TracestateTag] = activity.TraceStateString; } if (initializeFromCurrent) { opTelemetry.Id = activity.SpanId.ToHexString(); if (activity.ParentSpanId != null) { opTelemetry.Context.Operation.ParentId = activity.ParentSpanId.ToHexString(); } } else { telemetry.Context.Operation.ParentId = activity.SpanId.ToHexString(); } }
internal bool IsSuppressedTelemetry(ITelemetry telemetry) { OperationTelemetry opTelemetry = telemetry as OperationTelemetry; if (telemetry is DependencyTelemetry) { DependencyTelemetry dTelemetry = telemetry as DependencyTelemetry; if (!string.IsNullOrEmpty(dTelemetry.CommandName)) { var host = new Uri(dTelemetry.CommandName).Host; if (ExcludeComponentCorrelationHttpHeadersOnDomains.Contains(host)) { return(true); } } } return(false); }
private static void PopulateLinks(IEnumerable <Activity> links, OperationTelemetry telemetry) { if (links.Any()) { var linksJson = new StringBuilder(); linksJson.Append('['); foreach (var link in links) { var linkTraceId = link.TraceId.ToHexString(); // avoiding json serializers for now because of extra dependency. // serialization is trivial and looks like `links` property with json blob // [{"operation_Id":"5eca8b153632494ba00f619d6877b134","id":"d4c1279b6e7b7c47"}, // {"operation_Id":"ff28988d0776b44f9ca93352da126047","id":"bf4fa4855d161141"}] linksJson .Append('{') .Append("\"operation_Id\":") .Append('\"') .Append(linkTraceId) .Append('\"') .Append(','); linksJson .Append("\"id\":") .Append('\"') .Append(link.ParentSpanId.ToHexString()) .Append('\"'); // we explicitly ignore sampling flag, tracestate and attributes at this point. linksJson.Append("},"); } if (linksJson.Length > 0) { // trim trailing comma - json does not support it linksJson.Remove(linksJson.Length - 1, 1); } linksJson.Append(']'); telemetry.Properties["_MS.links"] = linksJson.ToString(); } }
private static void InitializeOperationTelemetry(OperationTelemetry telemetry, string spanName, string requestId, string parentRequestId, long spanStatusCode, string spanStatusMessage, DateTimeOffset?startTime, DateTimeOffset?endTime, string roleName, string roleInstance) { telemetry.Name = spanName; var now = DateTimeOffset.UtcNow; telemetry.Timestamp = startTime ?? now; var endTimeAdjusted = endTime ?? now; telemetry.Duration = endTimeAdjusted - telemetry.Timestamp; SetOperationContext(requestId, parentRequestId, telemetry); telemetry.Success = spanStatusCode == 0; if (!string.IsNullOrEmpty(spanStatusMessage)) { telemetry.Properties["statusDescription"] = spanStatusMessage; } SetPeerInfo(telemetry, roleName, roleInstance); }