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);
            }
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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);
            }
        }
Beispiel #5
0
        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);
            }
        }
Beispiel #6
0
        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);
            }
        }
Beispiel #7
0
        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
            };
        }
Beispiel #9
0
        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);
            }
        }