private void OnSendStart(KeyValuePair <string, object> kv) { var currentSegment = ApmAgent.GetCurrentExecutionSegment(); if (currentSegment is null) { Logger.Trace()?.Log("No current transaction or span - exiting"); return; } if (!(kv.Value is Activity activity)) { Logger.Trace()?.Log("Value is not an activity - exiting"); return; } string queueName = null; string destinationAddress = null; var urlTag = activity.Tags.FirstOrDefault(t => t.Key == "url").Value; if (!string.IsNullOrEmpty(urlTag)) { var queueUrl = new QueueUrl(urlTag); queueName = queueUrl.QueueName; destinationAddress = queueUrl.FullyQualifiedNamespace; } if (MatchesIgnoreMessageQueues(queueName)) { return; } var spanName = queueName is null ? $"{AzureQueueStorage.SpanName} SEND" : $"{AzureQueueStorage.SpanName} SEND to {queueName}"; var span = currentSegment.StartSpan(spanName, ApiConstants.TypeMessaging, AzureQueueStorage.SubType, "send"); span.Context.Destination = new Destination { Address = destinationAddress, Service = new Destination.DestinationService { Name = AzureQueueStorage.SubType, Resource = queueName is null ? AzureQueueStorage.SubType : $"{AzureQueueStorage.SubType}/{queueName}", Type = ApiConstants.TypeMessaging } }; if (!_processingSegments.TryAdd(activity.Id, span)) { Logger.Trace() ?.Log( "Could not add {Action} span {SpanId} for activity {ActivityId} to tracked spans", "SEND", span.Id, activity.Id); } }
private void OnSendStart(KeyValuePair <string, object> kv, string action, PropertyFetcherCollection cachedProperties) { var currentSegment = ApmAgent.GetCurrentExecutionSegment(); if (currentSegment is null) { Logger.Trace()?.Log("No current transaction or span - exiting"); return; } if (kv.Value is null) { Logger.Trace()?.Log("Value is null - exiting"); return; } var activity = Activity.Current; var queueName = cachedProperties.Fetch(kv.Value, "Entity") as string; var destinationAddress = cachedProperties.Fetch(kv.Value, "Endpoint") as Uri; if (MatchesIgnoreMessageQueues(queueName)) { return; } var spanName = queueName is null ? $"{ServiceBus.SegmentName} {action}" : $"{ServiceBus.SegmentName} {action} to {queueName}"; var span = currentSegment.StartSpan(spanName, ApiConstants.TypeMessaging, ServiceBus.SubType, action.ToLowerInvariant()); span.Context.Destination = new Destination { Address = destinationAddress?.AbsoluteUri, Service = new Destination.DestinationService { Resource = queueName is null ? ServiceBus.SubType : $"{ServiceBus.SubType}/{queueName}" } }; if (queueName != null) { span.Context.Message = new Message { Queue = new Queue { Name = queueName } } } ; if (!_processingSegments.TryAdd(activity.Id, span)) { Logger.Trace() ?.Log( "Could not add {Action} span {SpanId} for activity {ActivityId} to tracked segments", action, span.Id, activity.Id); } }
internal bool TryStartElasticsearchSpan(string name, out Span span, Uri instanceUri = null) { span = null; var transaction = ApmAgent.Tracer.CurrentTransaction; if (transaction is null) { return(false); } span = (Span)ApmAgent.GetCurrentExecutionSegment() .StartSpan( name, ApiConstants.TypeDb, ApiConstants.SubtypeElasticsearch); span.InstrumentationFlag = InstrumentationFlag.Elasticsearch; span.Action = name; SetDbContext(span, instanceUri); SetDestination(span, instanceUri); var id = Activity.Current.Id; if (Spans.TryAdd(id, span)) { return(true); } Logger.Error()?.Log("Failed to register start of span in ConcurrentDictionary {SpanDetails}", span.ToString()); span = null; return(false); }
private void OnSendStart(KeyValuePair <string, object> kv) { var currentSegment = ApmAgent.GetCurrentExecutionSegment(); if (currentSegment is null) { Logger.Trace()?.Log("No current transaction or span - exiting"); return; } if (!(kv.Value is Activity activity)) { Logger.Trace()?.Log("Value is not an activity - exiting"); return; } string queueName = null; string destinationAddress = null; var urlTag = activity.Tags.FirstOrDefault(t => t.Key == "url").Value; if (QueueUrl.TryCreate(urlTag, out var queueUrl)) { queueName = queueUrl.QueueName; destinationAddress = queueUrl.FullyQualifiedNamespace; } if (MatchesIgnoreMessageQueues(queueName)) { return; } var spanName = queueName is null ? $"{AzureQueueStorage.SpanName} SEND" : $"{AzureQueueStorage.SpanName} SEND to {queueName}"; var span = currentSegment.StartSpan(spanName, ApiConstants.TypeMessaging, AzureQueueStorage.SubType, "send", true); if (span is Span realSpan) { realSpan.InstrumentationFlag = InstrumentationFlag.Azure; } if (queueUrl != null) { SetDestination(span, destinationAddress, queueName); } if (!_processingSegments.TryAdd(activity.Id, span)) { Logger.Trace() ?.Log( "Could not add {Action} span {SpanId} for activity {ActivityId} to tracked spans", "SEND", span.Id, activity.Id); } }
private void OnStart(KeyValuePair <string, object> kv, string action) { var currentSegment = ApmAgent.GetCurrentExecutionSegment(); if (currentSegment is null) { Logger.Trace()?.Log("No current transaction or span - exiting"); return; } if (!(kv.Value is Activity activity)) { Logger.Trace()?.Log("Value is not an activity - exiting"); return; } var urlTag = activity.Tags.FirstOrDefault(t => t.Key == "url").Value; var blobUrl = new BlobUrl(urlTag); var spanName = $"{AzureBlobStorage.SpanName} {action} {blobUrl.ResourceName}"; var span = currentSegment.StartSpan(spanName, ApiConstants.TypeStorage, AzureBlobStorage.SubType, action); if (span is Span realSpan) { realSpan.InstrumentationFlag = InstrumentationFlag.Azure; } span.Context.Destination = new Destination { Address = blobUrl.FullyQualifiedNamespace, Service = new Destination.DestinationService { Name = AzureBlobStorage.SubType, Resource = $"{AzureBlobStorage.SubType}/{blobUrl.StorageAccountName}", Type = ApiConstants.TypeStorage } }; if (!_processingSegments.TryAdd(activity.Id, span)) { Logger.Trace() ?.Log( "Could not add {Action} span {SpanId} for activity {ActivityId} to tracked spans", action, span.Id, activity.Id); } }
private void HandleCommandStartEvent(CommandStartedEvent @event) { try { Logger.Trace()?.Log(nameof(HandleCommandStartEvent)); var currentExecutionSegment = ApmAgent.GetCurrentExecutionSegment(); var span = currentExecutionSegment.StartSpan( @event.CommandName, ApiConstants.TypeDb, "mongo", isExitSpan: true); if (!_processingQueries.TryAdd(@event.RequestId, span)) { Logger.Trace()?.Log("Failed adding item to _processingQueries with RequestId: {RequestId}", @event.RequestId); return; } span.Action = ApiConstants.ActionQuery; span.Context.Db = new Database { Statement = @event.Command.ToString(), Instance = @event.DatabaseNamespace.DatabaseName, Type = "mongo" }; if (@event.ConnectionId?.ServerId?.EndPoint != null) { span.Context.Destination = @event.ConnectionId.ServerId.EndPoint switch { IPEndPoint ipEndPoint => new Destination { Address = ipEndPoint.Address.ToString(), Port = ipEndPoint.Port }, DnsEndPoint dnsEndPoint => new Destination { Address = dnsEndPoint.Host, Port = dnsEndPoint.Port }, _ => null }; } } catch (Exception ex) { //ignore Logger.Log(LogLevel.Error, "Exception was thrown while handling 'command started event'", ex, null); } }
private void OnReceiveStart(KeyValuePair <string, object> kv, string action, PropertyFetcherCollection cachedProperties) { if (kv.Value is null) { Logger.Trace()?.Log("Value is null - exiting"); return; } var queueName = cachedProperties.Fetch(kv.Value, "Entity") as string; if (MatchesIgnoreMessageQueues(queueName)) { return; } var transactionName = queueName is null ? $"{ServiceBus.SegmentName} {action}" : $"{ServiceBus.SegmentName} {action} from {queueName}"; IExecutionSegment segment; if (ApmAgent.Tracer.CurrentTransaction is null) { var transaction = ApmAgent.Tracer.StartTransaction(transactionName, ApiConstants.TypeMessaging); transaction.Context.Service = new Service(null, null) { Framework = _framework }; segment = transaction; } else { var span = ApmAgent.GetCurrentExecutionSegment().StartSpan(transactionName, ApiConstants.TypeMessaging, ServiceBus.SubType, action); segment = span; } // transaction creation will create an activity, so use this as the key. var activityId = Activity.Current.Id; if (!_processingSegments.TryAdd(activityId, segment)) { Logger.Trace()?.Log( "Could not add {Action} {SegmentName} {TransactionId} for activity {ActivityId} to tracked segments", action, segment is ITransaction ? "transaction" : "span", segment.Id, activityId); } }
private void OnMessageStart(KeyValuePair <string, object> kv, string action) { var currentSegment = ApmAgent.GetCurrentExecutionSegment(); if (currentSegment is null) { return; } if (!(kv.Value is Activity activity)) { Logger.Trace()?.Log("Value is not an activity - exiting"); return; } string queueName = null; foreach (var tag in activity.Tags) { switch (tag.Key) { case "message_bus.destination": queueName = tag.Value; break; default: continue; } } if (MatchesIgnoreMessageQueues(queueName)) { return; } var name = $"{ServiceBus.SegmentName} {action} message"; _onMessageCurrent = currentSegment switch { Span span => span.StartSpanInternal(name, ApiConstants.TypeMessaging, ServiceBus.SubType, action.ToLowerInvariant(), id: activity.SpanId.ToString()), Transaction transaction => transaction.StartSpanInternal(name, ApiConstants.TypeMessaging, ServiceBus.SubType, action.ToLowerInvariant(), id: activity.SpanId.ToString()), _ => _onMessageCurrent }; }
private void OnStart(KeyValuePair <string, object> kv, string action) { var currentSegment = ApmAgent.GetCurrentExecutionSegment(); if (currentSegment is null) { Logger.Trace()?.Log("No current transaction or span - exiting"); return; } if (!(kv.Value is Activity activity)) { Logger.Trace()?.Log("Value is not an activity - exiting"); return; } var urlTag = activity.Tags.FirstOrDefault(t => t.Key == "url").Value; var spanName = BlobUrl.TryCreate(urlTag, out var blobUrl) ? $"{AzureBlobStorage.SpanName} {action} {blobUrl.ResourceName}" : $"{AzureBlobStorage.SpanName} {action}"; var span = currentSegment.StartSpan(spanName, ApiConstants.TypeStorage, AzureBlobStorage.SubType, action, true); if (span is Span realSpan) { realSpan.InstrumentationFlag = InstrumentationFlag.Azure; } if (blobUrl != null) { SetDestination(span, blobUrl); } if (!_processingSegments.TryAdd(activity.Id, span)) { Logger.Trace() ?.Log( "Could not add {Action} span {SpanId} for activity {ActivityId} to tracked spans", action, span.Id, activity.Id); } }
internal static ISpan CreateSpan(ApmAgent agent, IDbCommand command) { if (agent.Tracer.CurrentTransaction is null) { return(null); } // if the current execution segment is // 1. already for this instrumentation or instrumentation is AdoNet (System.Data.Common.DbCommand) and the type is "db" // and // 2. for the same command text // skip creating another db span for it, to prevent instrumenting delegated methods. if (agent.GetCurrentExecutionSegment() is Span span && (span.InstrumentationFlag.HasFlag(_instrumentationFlag) || span.Type == ApiConstants.TypeDb && (_instrumentationFlag == InstrumentationFlag.AdoNet || span.InstrumentationFlag == InstrumentationFlag.AdoNet)) && span.Name == DbSpanCommon.GetDbSpanName(command)) { return(null); } return(agent.TracerInternal.DbSpanCommon.StartSpan(agent, command, _instrumentationFlag)); }
private void OnSendStart(KeyValuePair <string, object> kv, string action) { var currentSegment = ApmAgent.GetCurrentExecutionSegment(); if (currentSegment is null) { Logger.Trace()?.Log("No current transaction or span - exiting"); return; } if (!(kv.Value is Activity activity)) { Logger.Trace()?.Log("Value is not an activity - exiting"); return; } string queueName = null; string destinationAddress = null; foreach (var tag in activity.Tags) { switch (tag.Key) { case "message_bus.destination": queueName = tag.Value; break; case "peer.address": destinationAddress = tag.Value; break; default: continue; } } if (MatchesIgnoreMessageQueues(queueName)) { return; } var spanName = queueName is null ? $"{ServiceBus.SegmentName} {action}" : $"{ServiceBus.SegmentName} {action} to {queueName}"; var span = currentSegment.StartSpan(spanName, ApiConstants.TypeMessaging, ServiceBus.SubType, action.ToLowerInvariant()); span.Context.Destination = new Destination { Address = destinationAddress, Service = new Destination.DestinationService { Name = ServiceBus.SubType, Resource = queueName is null ? ServiceBus.SubType : $"{ServiceBus.SubType}/{queueName}", Type = ApiConstants.TypeMessaging } }; if (!_processingSegments.TryAdd(activity.Id, span)) { Logger.Trace()?.Log( "Could not add {Action} span {SpanId} for activity {ActivityId} to tracked spans", action, span.Id, activity.Id); } }
private void OnReceiveStart(KeyValuePair <string, object> kv, string action) { if (!(kv.Value is Activity activity)) { Logger.Trace()?.Log("Value is not an activity - exiting"); return; } string queueName = null; foreach (var tag in activity.Tags) { switch (tag.Key) { case "message_bus.destination": queueName = tag.Value; break; default: continue; } } if (MatchesIgnoreMessageQueues(queueName)) { return; } var transactionName = queueName is null ? $"{ServiceBus.SegmentName} {action}" : $"{ServiceBus.SegmentName} {action} from {queueName}"; IExecutionSegment segment; if (ApmAgent.Tracer.CurrentTransaction is null) { var transaction = ApmAgent.Tracer.StartTransaction(transactionName, ApiConstants.TypeMessaging); transaction.Context.Service = new Service(null, null) { Framework = _framework }; segment = transaction; } else { var span = ApmAgent.GetCurrentExecutionSegment().StartSpan(transactionName, ApiConstants.TypeMessaging, ServiceBus.SubType, action); segment = span; } // transaction creation will create an activity, so use this as the key. var activityId = Activity.Current.Id; if (!_processingSegments.TryAdd(activityId, segment)) { Logger.Trace()?.Log( "Could not add {Action} {SegmentName} {TransactionId} for activity {ActivityId} to tracked segments", action, segment is ITransaction ? "transaction" : "span", segment.Id, activityId); } }