Exemplo n.º 1
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();
            }
        }
Exemplo n.º 2
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);
            }
        }
        protected internal void InjectTraceContext(HttpWebRequest message, TelemetrySpan parentSpan)
        {
            // Expects the currentspan to be the span to inject into
            var headers = message.Headers;

            TextFormat.Inject(Tracer.CurrentSpan.Context, headers, (c, k, v) =>
            {
                if (k == B3Constants.XB3TraceId && v.Length > 16 && Options.UseShortTraceIds)
                {
                    v = v.Substring(v.Length - 16, 16);
                }

                if (c.Get(k) != null)
                {
                    c.Remove(k);
                }

                c.Add(k, v);
            });

            if (parentSpan != null)
            {
                headers.Add(B3Constants.XB3ParentSpanId, parentSpan.Context.SpanId.ToHexString());
            }
        }
 public LoggingScope(TelemetrySpan span, bool endSpan = true)
 {
     this.span        = span;
     this.endSpan     = endSpan;
     this.origContext = CurrentSpanUtils.asyncLocalContext.Value;
     CurrentSpanUtils.asyncLocalContext.Value = span;
 }
Exemplo n.º 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));
     }
 }
 public static void DrainSession(Tracer tracer, TelemetrySpan parentSpan, IEnumerable <IProfiledCommand> sessionCommands)
 {
     foreach (var command in sessionCommands)
     {
         ProfilerCommandToSpan(tracer, parentSpan, command);
     }
 }
Exemplo n.º 7
0
 /// <inheritdoc />
 public override TelemetrySpan StartSpan(string operationName, TelemetrySpan parent, SpanKind kind,
                                         SpanCreationOptions options)
 {
     Logger.Log(
         $"{prefix}.StartSpan({operationName}, {parent.GetType().Name}, {kind}, {options.StartTimestamp:o}, {options.LinksFactory}, {options.Links})");
     return(new LoggingSpan(operationName, kind));
 }
Exemplo n.º 8
0
 public LoggingScope(TelemetrySpan span, bool endSpan = true)
 {
     this.span               = span;
     this.endSpan            = endSpan;
     origContext             = AsyncLocalContext.Value;
     AsyncLocalContext.Value = span;
 }
        /// <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));
        }
        public void ParentIds()
        {
            using var parentActivity = new Activity("parentOperation");
            parentActivity.Start(); // can't generate the Id until the operation is started
            using var parentSpan = new TelemetrySpan(parentActivity);

            // ParentId should be unset
            Assert.Equal(default, parentSpan.ParentSpanId);
Exemplo n.º 11
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);
     }
 }
        /// <inheritdoc/>
        public ISpan Start()
        {
            TelemetrySpan span = null;

            // If specified, this takes precedence.
            if (this.ignoreActiveSpan)
            {
                span = this.tracer.StartRootSpan(this.spanName, this.spanKind, default, this.links, this.explicitStartTime ?? default);
Exemplo n.º 13
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>
        /// <param name="reasonPhrase">Http reason phrase.</param>
        /// <returns>Span with populated properties.</returns>
        public static TelemetrySpan PutHttpStatusCode(this TelemetrySpan span, int statusCode, string reasonPhrase)
        {
            span.PutHttpStatusCodeAttribute(statusCode);

            span.Status = SpanHelper.ResolveSpanStatusForHttpStatusCode(statusCode).WithDescription(reasonPhrase);

            return(span);
        }
Exemplo n.º 14
0
        /// <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);
        }
Exemplo n.º 15
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="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);
        }
Exemplo n.º 16
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);
        }
Exemplo n.º 17
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);
        }
        public void CheckRecordExceptionEmpty()
        {
            using Activity activity           = new Activity("exception-test");
            using TelemetrySpan telemetrySpan = new TelemetrySpan(activity);
            telemetrySpan.RecordException(string.Empty, string.Empty, string.Empty);
            Assert.Empty(activity.Events);

            telemetrySpan.RecordException(null);
            Assert.Empty(activity.Events);
        }
        /// <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>
        /// <param name="reasonPhrase">Http reason phrase.</param>
        /// <returns>Span with populated properties.</returns>
        public static TelemetrySpan PutHttpStatusCode(this TelemetrySpan span, int statusCode, string reasonPhrase)
        {
            span.PutHttpStatusCodeAttribute(statusCode);

            var newStatus = Status.Ok;

            if ((int)statusCode < 200)
            {
                newStatus = Status.Unknown;
            }
            else if ((int)statusCode >= 200 && (int)statusCode <= 399)
            {
                newStatus = Status.Ok;
            }
            else if ((int)statusCode == 400)
            {
                newStatus = Status.InvalidArgument;
            }
            else if ((int)statusCode == 401)
            {
                newStatus = Status.Unauthenticated;
            }
            else if ((int)statusCode == 403)
            {
                newStatus = Status.PermissionDenied;
            }
            else if ((int)statusCode == 404)
            {
                newStatus = Status.NotFound;
            }
            else if ((int)statusCode == 429)
            {
                newStatus = Status.ResourceExhausted;
            }
            else if ((int)statusCode == 501)
            {
                newStatus = Status.Unimplemented;
            }
            else if ((int)statusCode == 503)
            {
                newStatus = Status.Unavailable;
            }
            else if ((int)statusCode == 504)
            {
                newStatus = Status.DeadlineExceeded;
            }
            else
            {
                newStatus = Status.Unknown;
            }

            span.Status = newStatus.WithDescription(reasonPhrase);

            return(span);
        }
Exemplo n.º 20
0
        public SpanShim(TelemetrySpan span)
        {
            this.Span = span ?? throw new ArgumentNullException(nameof(span), "Parameter cannot be null");

            if (!this.Span.Context.IsValid)
            {
                throw new ArgumentException("Passed span's context is not valid", nameof(this.Span.Context));
            }

            this.spanContextShim = new SpanContextShim(this.Span.Context);
        }
Exemplo n.º 21
0
        public SpanShim(TelemetrySpan span)
        {
            Guard.Null(span, nameof(span));
            if (!span.Context.IsValid)
            {
                throw new ArgumentException($"Invalid '{nameof(SpanContext)}'", nameof(span.Context));
            }

            this.Span            = span;
            this.spanContextShim = new SpanContextShim(this.Span.Context);
        }
Exemplo n.º 22
0
        public SpanShim(TelemetrySpan span)
        {
            this.Span = span ?? throw new ArgumentNullException(nameof(span));

            if (!this.Span.Context.IsValid)
            {
                throw new ArgumentException(nameof(this.Span.Context));
            }

            this.spanContextShim = new SpanContextShim(this.Span.Context);
        }
Exemplo n.º 23
0
        internal static object Run()
        {
            var zpagesOptions = new ZPagesExporterOptions()
            {
                Url = "http://localhost:7284/rpcz/"
            };
            var zpagesExporter = new ZPagesExporter(zpagesOptions);
            var spanProcessor  = new ZPagesSpanProcessor(zpagesExporter);

            ZPagesSpans.RetentionTime = 3600000;
            var httpServer = new ZPagesExporterStatsHttpServer(zpagesExporter, spanProcessor);

            // Start the server
            httpServer.Start();

            // Configure exporter
            using (var tracerFactory = TracerFactory.Create(builder => builder
                                                            .AddProcessorPipeline(b => b
                                                                                  .SetExporter(zpagesExporter)
                                                                                  .SetExportingProcessor(e => spanProcessor))))
            {
                var tracer = tracerFactory.GetTracer("zpages-test");

                while (true)
                {
                    // Create a scoped span.
                    TelemetrySpan telemetrySpan = tracer.StartSpan("Main");
                    telemetrySpan.Status = Status.Unavailable;

                    using (tracer.WithSpan(telemetrySpan))
                    {
                        Console.WriteLine("Starting Span");
                    }

                    Thread.Sleep(3000);

                    telemetrySpan.End();

                    // Create a scoped span.
                    TelemetrySpan telemetrySpan2 = tracer.StartSpan("TestSpan");
                    telemetrySpan2.Status = Status.Ok;

                    using (tracer.WithSpan(telemetrySpan2))
                    {
                        Console.WriteLine("Starting Span2");
                    }

                    Thread.Sleep(5000);

                    telemetrySpan2.End();
                }
            }
        }
Exemplo n.º 24
0
        /// <inheritdoc />
        public IKafkaMessage <TKey, TValue> Consume(CancellationToken cancellationToken = default)
        {
            TelemetrySpan span = null;
            Activity      consumingActivity = null;

            try
            {
                var consumeResult = _consumer.Consume(cancellationToken);
                consumingActivity = new Activity(Constants.ConsumeActivityName);
                consumingActivity.Start();
                var kafkaMessage = (KafkaMessage <TKey, TValue>)consumeResult;

                if (kafkaMessage.Headers?.Any() ?? false)
                {
                    kafkaMessage.Headers.TryGetValue(AbstractionConstants.CorrelationIdHeaderName, out var parentActivityId);

                    if (!string.IsNullOrEmpty(parentActivityId))
                    {
                        consumingActivity.SetParentId(parentActivityId);
                    }

                    foreach (var baggageItem in kafkaMessage.Headers)
                    {
                        if (baggageItem.Key != AbstractionConstants.CorrelationIdHeaderName)
                        {
                            consumingActivity.AddBaggage(baggageItem.Key, baggageItem.Value);
                        }
                    }
                }

                span = _tracer?.StartSpanFromActivity(Constants.SpanConsumeOperationNamePrefix, consumingActivity, SpanKind.Consumer);

                _logger.LogDebug("Consumed message 'key {key} ' at: '{partitionOffset}'.", consumeResult.Key, consumeResult.TopicPartitionOffset);

                return(kafkaMessage);
            }
            catch (ConsumeException e)
            {
                _logger.LogError(e, "ConsumeException occurred: {reason}", e.Error.Reason);
                throw;
            }
            catch (KafkaException e)
            {
                _logger.LogError(e, "KafkaException occurred: {reason}", e.Error.Reason);
                throw;
            }
            finally
            {
                consumingActivity?.Stop();
                span?.End();
            }
        }
Exemplo n.º 25
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="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);
        }
        public void CheckRecordExceptionData()
        {
            string message = "message";

            using Activity activity           = new Activity("exception-test");
            using TelemetrySpan telemetrySpan = new TelemetrySpan(activity);
            telemetrySpan.RecordException(new ArgumentNullException(message, new Exception("new-exception")));
            Assert.Single(activity.Events);

            var @event = telemetrySpan.Activity.Events.FirstOrDefault(q => q.Name == SemanticConventions.AttributeExceptionEventName);

            Assert.Equal(message, @event.Tags.FirstOrDefault(t => t.Key == SemanticConventions.AttributeExceptionMessage).Value);
            Assert.Equal(typeof(ArgumentNullException).Name, @event.Tags.FirstOrDefault(t => t.Key == SemanticConventions.AttributeExceptionType).Value);
        }
        /// <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));
        }
Exemplo n.º 28
0
        /// <inheritdoc/>
        public ISpanBuilder AsChildOf(ISpan parent)
        {
            if (parent == null)
            {
                return(this);
            }

            if (!this.ParentSet)
            {
                this.parentSpan = GetOpenTelemetrySpan(parent);
                return(this);
            }

            return(this.AsChildOf(parent.Context));
        }
Exemplo n.º 29
0
        public async Task Map(string supplier, Tracer tracer, TelemetrySpan parentSpan, CancellationToken cancellationToken)
        {
            using var localityMappingSpan =
                      tracer.StartActiveSpan("Map Localities", SpanKind.Internal, parentSpan);

            _logger.LogMappingLocalitiesStart(supplier);

            var countries = await _locationMapperDataRetrieveService.GetCountries(cancellationToken);

            foreach (var country in countries)
            {
                await MapCountryLocalities(supplier, country.Id, country.Code, country.Name, localityMappingSpan, cancellationToken);
            }

            _logger.LogMappingLocalitiesFinish(supplier);
        }
        public void CheckRecordExceptionData2()
        {
            string type    = "ArgumentNullException";
            string message = "message";
            string stack   = "stack";

            using Activity activity           = new Activity("exception-test");
            using TelemetrySpan telemetrySpan = new TelemetrySpan(activity);
            telemetrySpan.RecordException(type, message, stack);
            Assert.Single(activity.Events);

            var @event = telemetrySpan.Activity.Events.FirstOrDefault(q => q.Name == SemanticConventions.AttributeExceptionEventName);

            Assert.Equal(message, @event.Tags.FirstOrDefault(t => t.Key == SemanticConventions.AttributeExceptionMessage).Value);
            Assert.Equal(type, @event.Tags.FirstOrDefault(t => t.Key == SemanticConventions.AttributeExceptionType).Value);
            Assert.Equal(stack, @event.Tags.FirstOrDefault(t => t.Key == SemanticConventions.AttributeExceptionStacktrace).Value);
        }