コード例 #1
0
        public void NoEventsRecordedAfterEnd()
        {
            ISpan span =
                Span.StartSpan(
                    spanContext,
                    recordSpanOptions,
                    SPAN_NAME,
                    SpanKind.Internal,
                    parentSpanId,
                    TraceParams.Default,
                    startEndHandler,
                    timestampConverter);

            span.End();
            // Check that adding trace events after Span#End() does not throw any exception and are not
            // recorded.
            foreach (var attribute in attributes)
            {
                span.SetAttribute(attribute.Key, attribute.Value);
            }
            span.SetAttribute(
                "MySingleStringAttributeKey",
                AttributeValue.StringAttributeValue("MySingleStringAttributeValue"));
            span.AddEvent(Event.Create(EVENT_DESCRIPTION));
            span.AddEvent(EVENT_DESCRIPTION, attributes);
            span.AddLink(Link.FromSpanContext(spanContext));
            SpanData spanData = ((Span)span).ToSpanData();

            Assert.Equal(timestamp, spanData.StartTimestamp);
            Assert.Empty(spanData.Attributes.AttributeMap);
            Assert.Empty(spanData.Events.Events);
            Assert.Empty(spanData.Links.Links);
            Assert.Equal(Status.Ok, spanData.Status);
            Assert.Equal(timestamp, spanData.EndTimestamp);
        }
コード例 #2
0
        public void ToSpanData_ActiveSpan()
        {
            ISpan span =
                Span.StartSpan(
                    spanContext,
                    recordSpanOptions,
                    SPAN_NAME,
                    SpanKind.Internal,
                    parentSpanId,
                    TraceParams.Default,
                    startEndHandler,
                    timestampConverter);

            span.SetAttribute(
                "MySingleStringAttributeKey",
                AttributeValue.StringAttributeValue("MySingleStringAttributeValue"));
            foreach (var attribute in attributes)
            {
                span.SetAttribute(attribute.Key, attribute.Value);
            }

            interval = TimeSpan.FromMilliseconds(100);
            span.AddEvent(Event.Create(EVENT_DESCRIPTION));
            interval = TimeSpan.FromMilliseconds(200);
            span.AddEvent(EVENT_DESCRIPTION, attributes);
            interval = TimeSpan.FromMilliseconds(300);
            interval = TimeSpan.FromMilliseconds(400);
            ILink link = Link.FromSpanContext(spanContext);

            span.AddLink(link);
            SpanData spanData = ((Span)span).ToSpanData();

            Assert.Equal(spanContext, spanData.Context);
            Assert.Equal(SPAN_NAME, spanData.Name);
            Assert.Equal(parentSpanId, spanData.ParentSpanId);
            Assert.Equal(0, spanData.Attributes.DroppedAttributesCount);
            Assert.Equal(expectedAttributes, spanData.Attributes.AttributeMap);
            Assert.Equal(0, spanData.Events.DroppedEventsCount);
            Assert.Equal(2, spanData.Events.Events.Count());
            Assert.Equal(timestamp.AddDuration(Duration.Create(TimeSpan.FromMilliseconds(100))), spanData.Events.Events.ToList()[0].Timestamp);
            Assert.Equal(Event.Create(EVENT_DESCRIPTION), spanData.Events.Events.ToList()[0].Event);
            Assert.Equal(timestamp.AddDuration(Duration.Create(TimeSpan.FromMilliseconds(200))), spanData.Events.Events.ToList()[1].Timestamp);
            Assert.Equal(Event.Create(EVENT_DESCRIPTION, attributes), spanData.Events.Events.ToList()[1].Event);
            Assert.Equal(0, spanData.Links.DroppedLinksCount);
            Assert.Single(spanData.Links.Links);
            Assert.Equal(link, spanData.Links.Links.First());
            Assert.Equal(timestamp, spanData.StartTimestamp);
            Assert.Null(spanData.Status);
            Assert.Null(spanData.EndTimestamp);

            var startEndMock = Mock.Get <IStartEndHandler>(startEndHandler);
            var spanBase     = span as SpanBase;

            startEndMock.Verify(s => s.OnStart(spanBase), Times.Once);
        }
コード例 #3
0
        public void GoSpanData_EndedSpan()
        {
            ISpan span =
                Span.StartSpan(
                    spanContext,
                    recordSpanOptions,
                    SPAN_NAME,
                    parentSpanId,
                    false,
                    TraceParams.Default,
                    startEndHandler,
                    timestampConverter);

            span.SetAttribute(
                "MySingleStringAttributeKey",
                AttributeValue.StringAttributeValue("MySingleStringAttributeValue"));
            span.SetAttributes(attributes);
            interval = TimeSpan.FromMilliseconds(100);
            span.AddEvent(Event.Create(EVENT_DESCRIPTION));
            interval = TimeSpan.FromMilliseconds(200);
            span.AddEvent(EVENT_DESCRIPTION, attributes);
            interval = TimeSpan.FromMilliseconds(300);
            ILink link = Link.FromSpanContext(spanContext, LinkType.ChildLinkedSpan);

            span.AddLink(link);
            interval = TimeSpan.FromMilliseconds(400);
            span.End(EndSpanOptions.Builder().SetStatus(Status.Cancelled).Build());

            ISpanData spanData = ((Span)span).ToSpanData();

            Assert.Equal(spanContext, spanData.Context);
            Assert.Equal(SPAN_NAME, spanData.Name);
            Assert.Equal(parentSpanId, spanData.ParentSpanId);
            Assert.False(spanData.HasRemoteParent);
            Assert.Equal(0, spanData.Attributes.DroppedAttributesCount);
            Assert.Equal(expectedAttributes, spanData.Attributes.AttributeMap);
            Assert.Equal(0, spanData.Events.DroppedEventsCount);
            Assert.Equal(2, spanData.Events.Events.Count());
            Assert.Equal(timestamp.AddDuration(Duration.Create(TimeSpan.FromMilliseconds(100))), spanData.Events.Events.ToList()[0].Timestamp);
            Assert.Equal(Event.Create(EVENT_DESCRIPTION), spanData.Events.Events.ToList()[0].Event);
            Assert.Equal(timestamp.AddDuration(Duration.Create(TimeSpan.FromMilliseconds(200))), spanData.Events.Events.ToList()[1].Timestamp);
            Assert.Equal(Event.Create(EVENT_DESCRIPTION, attributes), spanData.Events.Events.ToList()[1].Event);
            Assert.Equal(0, spanData.Links.DroppedLinksCount);
            Assert.Single(spanData.Links.Links);
            Assert.Equal(link, spanData.Links.Links.First());
            Assert.Equal(timestamp, spanData.StartTimestamp);
            Assert.Equal(Status.Cancelled, spanData.Status);
            Assert.Equal(timestamp.AddDuration(Duration.Create(TimeSpan.FromMilliseconds(400))), spanData.EndTimestamp);

            var startEndMock = Mock.Get <IStartEndHandler>(startEndHandler);
            var spanBase     = span as SpanBase;

            startEndMock.Verify(s => s.OnStart(spanBase), Times.Once);
            startEndMock.Verify(s => s.OnEnd(spanBase), Times.Once);
        }
コード例 #4
0
        private static void DoWork(int i)
        {
            // 6. Get the global singleton Tracer object
            ITracer tracer = Tracing.Tracer;

            // 7. Start another span. If another span was already started, it'll use that span as the parent span.
            // In this example, the main method already started a span, so that'll be the parent span, and this will be
            // a child span.
            using (OpenTelemetry.Common.IScope scope = tracer.SpanBuilder("DoWork").StartScopedSpan())
            {
                // Simulate some work.
                ISpan span = tracer.CurrentSpan;

                try
                {
                    Console.WriteLine("Doing busy work");
                    Thread.Sleep(1000);
                }
                catch (ArgumentOutOfRangeException e)
                {
                    // 6. Set status upon error
                    span.Status = Status.Internal.WithDescription(e.ToString());
                }

                // 7. Annotate our span to capture metadata about our operation
                var attributes = new Dictionary <string, IAttributeValue>();
                attributes.Add("use", AttributeValue.StringAttributeValue("demo"));
                attributes.Add("hoge", AttributeValue.LongAttributeValue(256 * i));
                span.AddEvent("Invoking DoWork", attributes);
            }
        }
コード例 #5
0
        public void ToSpanData_NoRecordEvents()
        {
            ISpan span =
                Span.StartSpan(
                    spanContext,
                    noRecordSpanOptions,
                    SPAN_NAME,
                    parentSpanId,
                    false,
                    TraceParams.Default,
                    startEndHandler,
                    timestampConverter);

            // Check that adding trace events after Span#End() does not throw any exception.
            span.SetAttributes(attributes);
            span.AddEvent(Event.Create(EVENT_DESCRIPTION));
            span.AddEvent(EVENT_DESCRIPTION, attributes);
            span.AddLink(Link.FromSpanContext(spanContext, LinkType.ChildLinkedSpan));
            span.End();
            // exception.expect(IllegalStateException);
            Assert.Throws <InvalidOperationException>(() => ((Span)span).ToSpanData());
        }
コード例 #6
0
        public void DroppingEvents()
        {
            int         maxNumberOfEvents = 8;
            TraceParams traceParams       =
                TraceParams.Default.ToBuilder().SetMaxNumberOfEvents(maxNumberOfEvents).Build();
            ISpan span =
                Span.StartSpan(
                    spanContext,
                    recordSpanOptions,
                    SPAN_NAME,
                    SpanKind.Internal,
                    parentSpanId,
                    traceParams,
                    startEndHandler,
                    timestampConverter);
            IEvent testEvent = Event.Create(EVENT_DESCRIPTION);
            int    i         = 0;

            for (i = 0; i < 2 * maxNumberOfEvents; i++)
            {
                span.AddEvent(testEvent);
                interval += TimeSpan.FromMilliseconds(100);
            }
            SpanData spanData = ((Span)span).ToSpanData();

            Assert.Equal(maxNumberOfEvents, spanData.Events.DroppedEventsCount);
            Assert.Equal(maxNumberOfEvents, spanData.Events.Events.Count());
            i = 0;
            foreach (var te in spanData.Events.Events)
            {
                Assert.Equal(timestamp.AddDuration(Duration.Create(TimeSpan.FromMilliseconds(100 * (maxNumberOfEvents + i)))), te.Timestamp);
                Assert.Equal(testEvent, te.Event);
                i++;
            }
            span.End();
            spanData = ((Span)span).ToSpanData();
            Assert.Equal(maxNumberOfEvents, spanData.Events.DroppedEventsCount);
            Assert.Equal(maxNumberOfEvents, spanData.Events.Events.Count());
            i = 0;
            foreach (var te in spanData.Events.Events)
            {
                Assert.Equal(timestamp.AddDuration(Duration.Create(TimeSpan.FromMilliseconds(100 * (maxNumberOfEvents + i)))), te.Timestamp);
                Assert.Equal(testEvent, te.Event);
                i++;
            }
        }
        private async Task ProcessWebQueueMessageAsync(object sender, BasicDeliverEventArgs @event)
        {
            // ExtractActivity creates the Activity setting the parent based on the RabbitMQ "traceparent" header
            var activity = @event.ExtractActivity("Process single RabbitMQ message");

            ISpan span = null;
            IOperationHolder <DependencyTelemetry> operation = null;
            var    processingSucceeded = false;
            string source = string.Empty;

            IDisposable loggingScope = null;

            try
            {
                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("queue", Constants.WebQueueName);
                }

                using (operation = telemetryClient?.StartOperation <DependencyTelemetry>(activity))
                {
                    if (operation != null)
                    {
                        operation.Telemetry.Properties.Add("queue", Constants.WebQueueName);
                        operation.Telemetry.Type   = ApplicationInformation.Name;
                        operation.Telemetry.Target = this.rabbitMQHostName;
                    }

                    loggingScope = logger.BeginScope("Starting message processing");

                    // Get the payload
                    var message = JsonSerializer.Deserialize <EnqueuedMessage>(@event.Body, jsonSerializerOptions);
                    if (logger.IsEnabled(LogLevel.Information))
                    {
                        logger.LogInformation("Processing message from {source}: {message}", message.Source, Encoding.UTF8.GetString(@event.Body));
                    }

                    source = message.Source;

                    if ("error".Equals(message.EventName, StringComparison.OrdinalIgnoreCase))
                    {
                        throw new InvalidEventNameException("Invalid event name");
                    }

                    var apiFullUrl = $"{timeApiURL}/api/time/dbtime";
                    var time       = await httpClientFactory.CreateClient().GetStringAsync(apiFullUrl);

                    if (!string.IsNullOrEmpty(message.EventName))
                    {
                        span?.AddEvent(message.EventName);
                        telemetryClient?.TrackEvent(message.EventName);
                    }
                }
                processingSucceeded = true;
            }
            catch (Exception ex)
            {
                if (span != null)
                {
                    span.SetAttribute("error", true);
                    span.Status = Status.Internal.WithDescription(ex.ToString());
                }

                if (operation != null)
                {
                    operation.Telemetry.Success    = false;
                    operation.Telemetry.ResultCode = "500";

                    // Track exception, adding the connection to the current activity
                    var exOperation = new ExceptionTelemetry(ex);
                    exOperation.Context.Operation.Id       = operation.Telemetry.Context.Operation.Id;
                    exOperation.Context.Operation.ParentId = operation.Telemetry.Context.Operation.ParentId;
                    telemetryClient.TrackException(exOperation);
                }

                logger.LogError(ex, "Failed to process message from {source}", source);
            }
            finally
            {
                span?.End();
                metrics.TrackItemProcessed(1, source, processingSucceeded);
                loggingScope?.Dispose();
            }
        }
コード例 #8
0
        private async Task ProcessWebQueueMessageAsync(object sender, BasicDeliverEventArgs @event)
        {
            //var correlationId = @event.BasicProperties.CorrelationId;
            TraceParent traceParent = null;

            if (@event.BasicProperties.Headers.TryGetValue(TraceParent.HeaderKey, out var rawTraceParent) && rawTraceParent is byte[] binRawTraceParent)
            {
                traceParent = TraceParent.CreateFromString(Encoding.UTF8.GetString(binRawTraceParent));
            }

            ISpan span = null;
            IOperationHolder <RequestTelemetry> operation = null;

            try
            {
                if (traceParent == null)
                {
                    throw new Exception("Trace information not found in message");
                }

                if (tracer != null)
                {
                    var traceId       = ActivityTraceId.CreateFromString(traceParent.TraceId);
                    var parentId      = ActivitySpanId.CreateFromString(traceParent.SpanId);
                    var parentContext = new SpanContext(traceId, parentId, ActivityTraceFlags.Recorded, isRemote: true);
                    tracer.StartActiveSpan("Process single RabbitMQ message", parentContext, SpanKind.Consumer, out span);
                    span.SetAttribute("queue", Constants.WebQueueName);
                }

                using (operation = telemetryClient?.StartOperation <RequestTelemetry>("Process single RabbitMQ message", traceParent.TraceId, traceParent.SpanId))
                {
                    if (operation != null)
                    {
                        operation.Telemetry.Properties.Add("queue", Constants.WebQueueName);
                    }

                    using (logger.BeginScope("processing message {correlationId}", traceParent.TraceId))
                    {
                        var apiFullUrl = $"{apiUrl}/api/time/dbtime";
                        var time       = await httpClientFactory.CreateClient().GetStringAsync(apiFullUrl);

                        // Get the payload
                        var message = JsonSerializer.Deserialize <EnqueuedMessage>(@event.Body, jsonSerializerOptions);
                        if (!string.IsNullOrEmpty(message.EventName))
                        {
                            span?.AddEvent(message.EventName);
                            telemetryClient?.TrackEvent(message.EventName);
                        }

                        if (logger.IsEnabled(LogLevel.Debug))
                        {
                            logger.LogDebug("Processed message: {message}", Encoding.UTF8.GetString(@event.Body));
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                if (span != null)
                {
                    span.Status = Status.Internal.WithDescription(ex.ToString());
                }

                if (operation != null)
                {
                    operation.Telemetry.Success = false;
                    telemetryClient.TrackException(ex);
                }
            }
            finally
            {
                span?.End();
            }
        }