예제 #1
0
        public static void ApplyContext(this TelemetrySpan span, ReadOnlySettings settings,
                                        IReadOnlyDictionary <string, string> contextHeaders)
        {
            var transportDefinition = settings.Get <TransportDefinition>();

            span.SetAttribute("messaging.system", transportDefinition.GetType().Name.Replace("Transport", null).ToLowerInvariant());
            span.SetAttribute("messaging.destination", settings.LogicalAddress().ToString());
            if (contextHeaders.TryGetValue(Headers.ConversationId, out var conversationId))
            {
                span.SetAttribute("messaging.conversation_id", conversationId);
            }

            if (contextHeaders.TryGetValue(Headers.MessageIntent, out var intent) &&
                Enum.TryParse <MessageIntentEnum>(intent, out var intentValue))
            {
                var routingPolicy = settings.Get <TransportInfrastructure>().OutboundRoutingPolicy;

                var kind = GetDestinationKind(intentValue, routingPolicy);

                if (kind != null)
                {
                    span.SetAttribute("messaging.destination_kind", kind);
                }
            }

            foreach (var header in contextHeaders.Where(header => header.Key.StartsWith("NServiceBus.")))
            {
                span.SetAttribute($"messaging.{header.Key.ToLowerInvariant()}", header.Value);
            }
        }
        private static void SetSpanAttributes(Activity activity, IOutgoingPhysicalMessageContext context, TelemetrySpan span)
        {
            span.SetAttribute("messaging.message_id", context.MessageId);
            span.SetAttribute("messaging.message_payload_size_bytes", context.Body.Length);

            span.ApplyContext(context.Builder.Build <ReadOnlySettings>(), context.Headers);

            foreach (var tag in activity.Tags)
            {
                span.SetAttribute($"messaging.nservicebus.{tag.Key.ToLowerInvariant()}", tag.Value);
            }
        }
        /// <summary>
        /// Helper method that populates span properties from host and port
        /// to https://github.com/open-telemetry/opentelemetry-specification/blob/2316771e7e0ca3bfe9b2286d13e3a41ded6b8858/specification/data-http.md.
        /// </summary>
        /// <param name="span">Span to fill out.</param>
        /// <param name="hostName">Hostr name.</param>
        /// <param name="port">Port number.</param>
        /// <returns>Span with populated host properties.</returns>
        public static TelemetrySpan PutHttpHostAttribute(this TelemetrySpan span, string hostName, int port)
        {
            if (port == 80 || port == 443)
            {
                span.SetAttribute(SpanAttributeConstants.HttpHostKey, hostName);
            }
            else
            {
                span.SetAttribute(SpanAttributeConstants.HttpHostKey, hostName + ":" + port);
            }

            return(span);
        }
예제 #4
0
        private void RabbitMqConsumer_Received(object sender, BasicDeliverEventArgs e)
        {
            // ExtractActivity creates the Activity setting the parent based on the RabbitMQ "traceparent" header
            var           activity = e.ExtractActivity("Process single RabbitMQ message");
            TelemetrySpan span     = null;

            if (tracer != null)
            {
                // OpenTelemetry seems to require the Activity to have started, unlike AI SDK
                activity.Start();
                tracer.StartActiveSpanFromActivity(activity.OperationName, activity, SpanKind.Consumer, out span);

                span.SetAttribute(Telemetry.Constants.RoutingKeyTagName, e.RoutingKey);
            }

            try
            {
                string message = DeserializeMessage(e.Body, e.RoutingKey);

                string fullTypeName = e.BasicProperties.GetCustomProperty <string>(TypeNameHeader);

                OnMessagedReceived(new MessageReceivedEventArgs(message, fullTypeName));
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "Unable to proccess message. Routing key: {RoutingKey}", e.RoutingKey);
            }
            finally
            {
                span?.End();
            }
        }
예제 #5
0
 private static void PutHeadersAttribute(TelemetrySpan span, string key, List <KeyValuePair <string, IEnumerable <string> > > headers)
 {
     foreach (var header in headers)
     {
         span.SetAttribute(key + header.Key, string.Join(",", header.Value));
     }
 }
        /// <inheritdoc/>
        public ISpan Start()
        {
            TelemetrySpan span = null;

            SpanCreationOptions options = null;

            if (this.explicitStartTime != null || this.links != null)
            {
                options = new SpanCreationOptions
                {
                    StartTimestamp = this.explicitStartTime ?? default,
                    Links          = this.links,
                };
            }

            // If specified, this takes precedence.
            if (this.ignoreActiveSpan)
            {
                span = this.tracer.StartRootSpan(this.spanName, this.spanKind, options);
            }
            else if (this.parentSpan != null)
            {
                span = this.tracer.StartSpan(this.spanName, this.parentSpan, this.spanKind, options);
            }
            else if (this.parentSpanContext.IsValid)
            {
                span = this.tracer.StartSpan(this.spanName, this.parentSpanContext, this.spanKind, options);
            }
            else if (this.parentSpan == null && !this.parentSpanContext.IsValid && (this.tracer.CurrentSpan == null || !this.tracer.CurrentSpan.Context.IsValid))
            {
                // We need to know if we should inherit an existing Activity-based context or start a new one.
                if (System.Diagnostics.Activity.Current != null && System.Diagnostics.Activity.Current.IdFormat == System.Diagnostics.ActivityIdFormat.W3C)
                {
                    var currentActivity = System.Diagnostics.Activity.Current;
                    if (this.rootOperationNamesForActivityBasedAutoAdapters.Contains(currentActivity.OperationName))
                    {
                        this.tracer.StartSpanFromActivity(this.spanName, currentActivity, this.spanKind, this.links);
                        span = this.tracer.CurrentSpan;
                    }
                }
            }

            if (span == null)
            {
                span = this.tracer.StartSpan(this.spanName, null, this.spanKind, options);
            }

            foreach (var kvp in this.attributes)
            {
                span.SetAttribute(kvp.Key, kvp.Value);
            }

            if (this.error)
            {
                span.Status = Trace.Status.Unknown;
            }

            return(new SpanShim(span));
        }
예제 #7
0
 private static void PutHeadersAttribute(TelemetrySpan span, string key, NameValueCollection headers)
 {
     foreach (var header in headers.AllKeys)
     {
         var val = string.Join(",", headers.GetValues(header));
         span.SetAttribute(key + header, val);
     }
 }
        /// <summary>
        /// Helper method that populates span properties from route
        /// to https://github.com/open-telemetry/opentelemetry-specification/blob/2316771e7e0ca3bfe9b2286d13e3a41ded6b8858/specification/data-http.md.
        /// </summary>
        /// <param name="span">Span to fill out.</param>
        /// <param name="route">Route used to resolve url to controller.</param>
        /// <returns>Span with populated route properties.</returns>
        public static TelemetrySpan PutHttpRouteAttribute(this TelemetrySpan span, string route)
        {
            if (!string.IsNullOrEmpty(route))
            {
                span.SetAttribute(SpanAttributeConstants.HttpRouteKey, route);
            }

            return(span);
        }
        /// <summary>
        /// Helper method that populates span properties from host and port
        /// to https://github.com/open-telemetry/opentelemetry-specification/blob/2316771e7e0ca3bfe9b2286d13e3a41ded6b8858/specification/data-http.md.
        /// </summary>
        /// <param name="span">Span to fill out.</param>
        /// <param name="rawUrl">Raw url.</param>
        /// <returns>Span with populated url properties.</returns>
        public static TelemetrySpan PutHttpRawUrlAttribute(this TelemetrySpan span, string rawUrl)
        {
            if (!string.IsNullOrEmpty(rawUrl))
            {
                span.SetAttribute(SpanAttributeConstants.HttpUrlKey, rawUrl);
            }

            return(span);
        }
예제 #10
0
        /// <summary>
        /// Helper method that populates span properties from http user agent according
        /// to https://github.com/open-telemetry/opentelemetry-specification/blob/2316771e7e0ca3bfe9b2286d13e3a41ded6b8858/specification/data-http.md.
        /// </summary>
        /// <param name="span">Span to fill out.</param>
        /// <param name="userAgent">Http status code.</param>
        /// <returns>Span with populated user agent code properties.</returns>
        public static TelemetrySpan PutHttpUserAgentAttribute(this TelemetrySpan span, string userAgent)
        {
            if (!string.IsNullOrWhiteSpace(userAgent))
            {
                span.SetAttribute(SpanAttributeConstants.HttpUserAgentKey, userAgent);
            }

            return(span);
        }
예제 #11
0
        /// <summary>
        /// Helper method that populates span properties from host and port
        /// to https://github.com/open-telemetry/opentelemetry-specification/blob/2316771e7e0ca3bfe9b2286d13e3a41ded6b8858/specification/data-http.md.
        /// </summary>
        /// <param name="span">Span to fill out.</param>
        /// <param name="hostAndPort">Host and port value.</param>
        /// <returns>Span with populated host properties.</returns>
        public static TelemetrySpan PutHttpHostAttribute(this TelemetrySpan span, string hostAndPort)
        {
            if (!string.IsNullOrEmpty(hostAndPort))
            {
                span.SetAttribute(SpanAttributeConstants.HttpHostKey, hostAndPort);
            }

            return(span);
        }
        /// <inheritdoc/>
        public ISpan Start()
        {
            TelemetrySpan span = null;

            // If specified, this takes precedence.
            if (this.ignoreActiveSpan)
            {
                span = this.tracer.StartSpan(this.spanName, this.spanKind, default(SpanContext), null, this.links, this.explicitStartTime ?? default);
            }
            else if (this.parentSpan != null)
            {
                span = this.tracer.StartSpan(this.spanName, this.spanKind, this.parentSpan, null, this.links, this.explicitStartTime ?? default);
            }
            else if (this.parentSpanContext.IsValid)
            {
                span = this.tracer.StartSpan(this.spanName, this.spanKind, this.parentSpanContext, null, this.links, this.explicitStartTime ?? default);
            }
            else if (this.parentSpan == null && !this.parentSpanContext.IsValid && (this.tracer.CurrentSpan == null || !this.tracer.CurrentSpan.Context.IsValid))
            {
                // TODO: We need to know if we should inherit an existing Activity-based context or start a new one.

                /*
                 * if (System.Diagnostics.Activity.Current != null && System.Diagnostics.Activity.Current.IdFormat == System.Diagnostics.ActivityIdFormat.W3C)
                 * {
                 *  var currentActivity = System.Diagnostics.Activity.Current;
                 *  if (this.rootOperationNamesForActivityBasedAutoInstrumentations.Contains(currentActivity.OperationName))
                 *  {
                 *      this.tracer.StartSpanFromActivity(this.spanName, currentActivity, this.spanKind, this.links);
                 *      span = this.tracer.CurrentSpan;
                 *  }
                 * }*/
            }

            if (span == null)
            {
                span = this.tracer.StartSpan(this.spanName, this.spanKind, default(SpanContext), null, null, this.explicitStartTime ?? default);
            }

            foreach (var kvp in this.attributes)
            {
                span.SetAttribute(kvp.Key, kvp.Value.ToString());
            }

            if (this.error)
            {
                span.Status = Trace.Status.Unknown;
            }

            return(new SpanShim(span));
        }
예제 #13
0
 /// <summary>
 /// Helper method that populates span properties from component
 /// to https://github.com/open-telemetry/opentelemetry-specification/blob/2316771e7e0ca3bfe9b2286d13e3a41ded6b8858/specification/data-span-general.md.
 /// </summary>
 /// <param name="span">Span to fill out.</param>
 /// <param name="peerService">Peer service.</param>
 /// <returns>Span with populated http method properties.</returns>
 public static TelemetrySpan PutPeerServiceAttribute(this TelemetrySpan span, string peerService)
 {
     span.SetAttribute(SpanAttributeConstants.PeerServiceKey, peerService);
     return(span);
 }
예제 #14
0
 /// <summary>
 /// Helper method that populates span properties from component
 /// to https://github.com/open-telemetry/opentelemetry-specification/blob/2316771e7e0ca3bfe9b2286d13e3a41ded6b8858/specification/data-http.md.
 /// </summary>
 /// <param name="span">Span to fill out.</param>
 /// <param name="component">Http method.</param>
 /// <returns>Span with populated http method properties.</returns>
 public static TelemetrySpan PutComponentAttribute(this TelemetrySpan span, string component)
 {
     span.SetAttribute(SpanAttributeConstants.ComponentKey, component);
     return(span);
 }
예제 #15
0
 /// <summary>
 /// Helper method that populates database statement
 /// to https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/data-database.md.
 /// </summary>
 /// <param name="span">Span to fill out.</param>
 /// <param name="statement">Database statement.</param>
 /// <returns>Span with populated properties.</returns>
 public static TelemetrySpan PutDatabaseStatementAttribute(this TelemetrySpan span, string statement)
 {
     span.SetAttribute(SpanAttributeConstants.DatabaseStatementKey, statement);
     return(span);
 }
예제 #16
0
 /// <summary>
 /// Helper method that populates database instance
 /// to https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/data-database.md.
 /// </summary>
 /// <param name="span">Span to fill out.</param>
 /// <param name="instance">Database instance.</param>
 /// <returns>Span with populated properties.</returns>
 public static TelemetrySpan PutDatabaseInstanceAttribute(this TelemetrySpan span, string instance)
 {
     span.SetAttribute(SpanAttributeConstants.DatabaseInstanceKey, instance);
     return(span);
 }
예제 #17
0
 /// <summary>
 /// Helper method that populates database type
 /// to https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/data-database.md.
 /// </summary>
 /// <param name="span">Span to fill out.</param>
 /// <param name="type">Database type.</param>
 /// <returns>Span with populated properties.</returns>
 public static TelemetrySpan PutDatabaseTypeAttribute(this TelemetrySpan span, string type)
 {
     span.SetAttribute(SpanAttributeConstants.DatabaseTypeKey, type);
     return(span);
 }
예제 #18
0
 /// <summary>
 /// Helper method that populates span properties from request version according
 /// to https://github.com/open-telemetry/opentelemetry-specification/blob/2316771e7e0ca3bfe9b2286d13e3a41ded6b8858/specification/data-http.md.
 /// </summary>
 /// <param name="span">Span to fill out.</param>
 /// <param name="flavor">HTTP version.</param>
 /// <returns>Span with populated properties.</returns>
 public static TelemetrySpan PutHttpFlavorAttribute(this TelemetrySpan span, string flavor)
 {
     span.SetAttribute(SpanAttributeConstants.HttpFlavorKey, flavor);
     return(span);
 }
예제 #19
0
 public static TelemetrySpan PutMvcControllerAction(this TelemetrySpan span, string actionName)
 {
     span.SetAttribute(SpanAttributeConstants.MvcControllerMethod, actionName);
     return(span);
 }
예제 #20
0
 public static TelemetrySpan PutErrorAttribute(this TelemetrySpan span, string errorMessage)
 {
     span.SetAttribute(SpanAttributeConstants.ErrorKey, errorMessage);
     return(span);
 }
예제 #21
0
 /// <summary>
 /// Helper method that populates database system
 /// to https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/semantic_conventions/database.md.
 /// </summary>
 /// <param name="span">Span to fill out.</param>
 /// <param name="system">Database system.</param>
 /// <returns>Span with populated properties.</returns>
 public static TelemetrySpan PutDatabaseSystemAttribute(this TelemetrySpan span, string system)
 {
     span.SetAttribute(SpanAttributeConstants.DatabaseSystemKey, system);
     return(span);
 }
예제 #22
0
 public static TelemetrySpan PutErrorStackTraceAttribute(this TelemetrySpan span, string errorStackTrace)
 {
     span.SetAttribute(SpanAttributeConstants.ErrorStackTrace, errorStackTrace);
     return(span);
 }
예제 #23
0
 public static TelemetrySpan PutMvcViewExecutingFilePath(this TelemetrySpan span, string actionName)
 {
     span.SetAttribute(SpanAttributeConstants.MvcViewFilePath, actionName);
     return(span);
 }
예제 #24
0
 /// <summary>
 /// Helper method that populates span properties from http method according
 /// to https://github.com/open-telemetry/opentelemetry-specification/blob/2316771e7e0ca3bfe9b2286d13e3a41ded6b8858/specification/data-http.md.
 /// </summary>
 /// <param name="span">Span to fill out.</param>
 /// <param name="method">Http method.</param>
 /// <returns>Span with populated http method properties.</returns>
 public static TelemetrySpan PutHttpMethodAttribute(this TelemetrySpan span, string method)
 {
     span.SetAttribute(SpanAttributeConstants.HttpMethodKey, method);
     return(span);
 }
예제 #25
0
 /// <summary>
 /// Helper method that populates span properties from url path according
 /// to https://github.com/open-telemetry/opentelemetry-specification/blob/2316771e7e0ca3bfe9b2286d13e3a41ded6b8858/specification/data-http.md.
 /// </summary>
 /// <param name="span">Span to fill out.</param>
 /// <param name="path">Url path.</param>
 /// <returns>Span with populated path properties.</returns>
 public static TelemetrySpan PutHttpPathAttribute(this TelemetrySpan span, string path)
 {
     span.SetAttribute(SpanAttributeConstants.HttpPathKey, path);
     return(span);
 }
예제 #26
0
 /// <summary>
 /// Helper method that populates span properties from http status code according
 /// to https://github.com/open-telemetry/opentelemetry-specification/blob/2316771e7e0ca3bfe9b2286d13e3a41ded6b8858/specification/data-http.md.
 /// </summary>
 /// <param name="span">Span to fill out.</param>
 /// <param name="statusCode">Http status code.</param>
 /// <returns>Span with populated status code properties.</returns>
 public static TelemetrySpan PutHttpStatusCodeAttribute(this TelemetrySpan span, int statusCode)
 {
     span.SetAttribute(SpanAttributeConstants.HttpStatusCodeKey, statusCode);
     return(span);
 }
예제 #27
0
 public static TelemetrySpan PutMvcControllerClass(this TelemetrySpan span, string className)
 {
     span.SetAttribute(SpanAttributeConstants.MvcControllerClass, className);
     return(span);
 }
예제 #28
0
 public IInternalSpan SetAttribute(string key, string value)
 {
     _span.SetAttribute(key, value);
     return(this);
 }
예제 #29
0
 public static TelemetrySpan PutHttpRequestSizeAttribute(this TelemetrySpan span, long size)
 {
     span.SetAttribute(SpanAttributeConstants.HttpRequestSizeKey, size);
     return(span);
 }