public void ValidateStatusForAzureMonitorTrace(string activityStatusCode, string activityStatusDescription)
        {
            using ActivitySource activitySource = new ActivitySource(ActivitySourceName);
            using var activity = activitySource.StartActivity(
                      ActivityName,
                      ActivityKind.Server,
                      parentContext: new ActivityContext(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.Recorded),
                      startTime: DateTime.UtcNow);

            activity.SetTag("otel.status_code", activityStatusCode);
            activity.SetTag("otel.status_description", activityStatusDescription);

            activity.SetTag(SemanticConventions.AttributeHttpUrl, "https://www.foo.bar/search");

            var monitorTags = TraceHelper.EnumerateActivityTags(activity);

            var requestData          = new RequestData(2, activity, ref monitorTags);
            var remoteDependencyData = new RemoteDependencyData(2, activity, ref monitorTags);

            Assert.Equal(activity.GetStatus().StatusCode != StatusCode.Error, requestData.Success);
            Assert.Equal(activity.GetStatus().StatusCode != StatusCode.Error, remoteDependencyData.Success);
        }
        // Applies the given sampler to NUM_SAMPLE_TRIES random traceId/spanId pairs.
        private static void AssertSamplerSamplesWithProbability(
            ISampler sampler, SpanContext parent, List <Link> links, double probability)
        {
            var count = 0; // Count of spans with sampling enabled

            for (var i = 0; i < NUM_SAMPLE_TRIES; i++)
            {
                if (sampler.ShouldSample(
                        parent,
                        ActivityTraceId.CreateRandom(),
                        ActivitySpanId.CreateRandom(),
                        SPAN_NAME,
                        links).IsSampled)
                {
                    count++;
                }
            }
            var proportionSampled = (double)count / NUM_SAMPLE_TRIES;

            // Allow for a large amount of slop (+/- 10%) in number of sampled traces, to avoid flakiness.
            Assert.True(proportionSampled <probability + 0.1 && proportionSampled> probability - 0.1);
        }
        public async Task SuccessfulTemplateControllerCallUsesParentContext()
        {
            var spanProcessor = new Mock <ActivityProcessor>();

            var expectedTraceId = ActivityTraceId.CreateRandom();
            var expectedSpanId  = ActivitySpanId.CreateRandom();

            // Arrange
            using (var testFactory = this.factory
                                     .WithWebHostBuilder(builder =>
                                                         builder.ConfigureTestServices(services =>
            {
                this.openTelemetrySdk = OpenTelemetrySdk.EnableOpenTelemetry((builder) => builder.AddRequestInstrumentation()
                                                                             .AddProcessorPipeline(p => p.AddProcessor(n => spanProcessor.Object)));
            })))
            {
                using var client = testFactory.CreateClient();
                var request = new HttpRequestMessage(HttpMethod.Get, "/api/values/2");
                request.Headers.Add("traceparent", $"00-{expectedTraceId}-{expectedSpanId}-01");

                // Act
                var response = await client.SendAsync(request);

                // Assert
                response.EnsureSuccessStatusCode(); // Status Code 200-299

                WaitForProcessorInvocations(spanProcessor, 2);
            }

            Assert.Equal(2, spanProcessor.Invocations.Count); // begin and end was called
            var span = (Activity)spanProcessor.Invocations[1].Arguments[0];

            Assert.Equal(ActivityKind.Server, span.Kind);
            Assert.Equal("api/Values/{id}", span.DisplayName);
            Assert.Equal("/api/values/2", span.Tags.FirstOrDefault(i => i.Key == SpanAttributeConstants.HttpPathKey).Value);

            Assert.Equal(expectedTraceId, span.Context.TraceId);
            Assert.Equal(expectedSpanId, span.ParentSpanId);
        }
Exemple #4
0
        public void DroppingLinksEnumerable()
        {
            var contextLink = new SpanContext(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(),
                                              ActivityTraceFlags.None);

            var maxNumberOfLinks = 8;
            var traceConfig      = new TracerConfiguration(Samplers.AlwaysSample, 32, 128, maxNumberOfLinks);
            var tracer           = TracerFactory.Create(b => b
                                                        .AddProcessorPipeline(p => p.AddProcessor(n => spanProcessor))
                                                        .SetTracerOptions(traceConfig))
                                   .GetTracer(null);

            var overflowedLinks = new List <Link>();
            var link            = new Link(contextLink);

            for (var i = 0; i < 2 * maxNumberOfLinks; i++)
            {
                overflowedLinks.Add(link);
            }

            var span = (Span)tracer.StartSpan(SpanName, SpanKind.Client, new SpanCreationOptions
            {
                Links = overflowedLinks,
            });

            Assert.Equal(maxNumberOfLinks, span.Links.Count());
            foreach (var actualLink in span.Links)
            {
                Assert.Equal(link, actualLink);
            }

            span.End();

            Assert.Equal(maxNumberOfLinks, span.Links.Count());
            foreach (var actualLink in span.Links)
            {
                Assert.Equal(link, actualLink);
            }
        }
Exemple #5
0
        public void StartRemoteSpan()
        {
            var spanContext =
                SpanContext.Create(
                    ActivityTraceId.CreateRandom(),
                    ActivitySpanId.CreateRandom(),
                    ActivityTraceFlags.None,
                    Tracestate.Builder.Set("k1", "v1").Build());

            var span = (Span) new SpanBuilder(SpanName, spanProcessor, alwaysSampleTraceConfig)
                       .SetSpanKind(SpanKind.Internal)
                       .SetParent(spanContext)
                       .SetRecordEvents(true)
                       .StartSpan();

            Assert.True(span.Context.IsValid);
            Assert.Equal(spanContext.TraceId, span.Context.TraceId);
            Assert.True((span.Context.TraceOptions & ActivityTraceFlags.Recorded) != 0);

            Assert.Equal(spanContext.SpanId, span.ParentSpanId);
            Assert.Equal("k1=v1", span.Context.Tracestate.ToString());
        }
        public void GeneratePartAEnvelope_Activity_WithParentSpanId()
        {
            using ActivitySource activitySource = new ActivitySource(ActivitySourceName);
            using var activity = activitySource.StartActivity(
                      ActivityName,
                      ActivityKind.Client,
                      parentContext: new ActivityContext(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.Recorded),
                      startTime: DateTime.UtcNow);
            var resource = CreateTestResource();

            var monitorTags = AzureMonitorConverter.EnumerateActivityTags(activity);

            var telemetryItem = TelemetryPartA.GetTelemetryItem(activity, ref monitorTags, resource, null);

            Assert.Equal("RemoteDependency", telemetryItem.Name);
            Assert.Equal(TelemetryPartA.FormatUtcTimestamp(activity.StartTimeUtc), telemetryItem.Time);
            Assert.StartsWith("unknown_service", telemetryItem.Tags[ContextTagKeys.AiCloudRole.ToString()]);
            Assert.Equal(Dns.GetHostName(), telemetryItem.Tags[ContextTagKeys.AiCloudRoleInstance.ToString()]);
            Assert.NotNull(telemetryItem.Tags[ContextTagKeys.AiOperationId.ToString()]);
            Assert.NotNull(telemetryItem.Tags[ContextTagKeys.AiInternalSdkVersion.ToString()]);
            Assert.Equal(activity.ParentSpanId.ToHexString(), telemetryItem.Tags[ContextTagKeys.AiOperationParentId.ToString()]);
        }
        public LinkTest()
        {
            this.spanContext = new SpanContext(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.None);

            this.attributesMap.Add("MyAttributeKey0", "MyStringAttribute");
            this.attributesMap.Add("MyAttributeKey1", 10L);
            this.attributesMap.Add("MyAttributeKey2", true);
            this.attributesMap.Add("MyAttributeKey3", 0.005);
            this.attributesMap.Add("MyAttributeKey4", new long[] { 1, 2 });
            this.attributesMap.Add("MyAttributeKey5", new string[] { "a", "b" });
            this.attributesMap.Add("MyAttributeKey6", new bool[] { true, false });
            this.attributesMap.Add("MyAttributeKey7", new double[] { 0.1, -0.1 });
            this.tags = new SpanAttributes();
            this.tags.Add("MyAttributeKey0", "MyStringAttribute");
            this.tags.Add("MyAttributeKey1", 10L);
            this.tags.Add("MyAttributeKey2", true);
            this.tags.Add("MyAttributeKey3", 0.005);
            this.tags.Add("MyAttributeKey4", new long[] { 1, 2 });
            this.tags.Add("MyAttributeKey5", new string[] { "a", "b" });
            this.tags.Add("MyAttributeKey6", new bool[] { true, false });
            this.tags.Add("MyAttributeKey7", new double[] { 0.1, -0.1 });
        }
Exemple #8
0
        public async Task TestTraceStateAndCorrelationContext()
        {
            try
            {
                using var eventRecords = new ActivitySourceRecorder();

                var parent = new Activity("w3c activity");
                parent.SetParentId(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom());
                parent.TraceStateString = "some=state";
                parent.AddBaggage("k", "v");
                parent.Start();

                // Send a random Http request to generate some events
                using (var client = new HttpClient())
                {
                    (await client.GetAsync(this.BuildRequestUrl())).Dispose();
                }

                parent.Stop();

                Assert.Equal(2, eventRecords.Records.Count());

                // Check to make sure: The first record must be a request, the next record must be a response.
                (Activity activity, HttpWebRequest startRequest) = AssertFirstEventWasStart(eventRecords);

                var traceparent        = startRequest.Headers["traceparent"];
                var tracestate         = startRequest.Headers["tracestate"];
                var correlationContext = startRequest.Headers["Correlation-Context"];
                Assert.NotNull(traceparent);
                Assert.Equal("some=state", tracestate);
                Assert.Equal("k=v", correlationContext);
                Assert.StartsWith($"00-{parent.TraceId.ToHexString()}-", traceparent);
                Assert.Matches("^[0-9a-f]{2}-[0-9a-f]{32}-[0-9a-f]{16}-[0-9a-f]{2}$", traceparent);
            }
            finally
            {
                this.CleanUpActivity();
            }
        }
        public void StartSpan_CurrentSpanParent()
        {
            var rootSpan = new SpanBuilder(SpanName, spanBuilderOptions)
                           .SetParent(
                SpanContext.Create(
                    ActivityTraceId.CreateRandom(),
                    ActivitySpanId.CreateRandom(),
                    ActivityTraceFlags.None,
                    Tracestate.Builder.Set("k1", "v1").Build()))
                           .StartSpan();

            using (tracer.WithSpan(rootSpan))
            {
                var childSpan = (Span) new SpanBuilder(SpanName, spanBuilderOptions)
                                .StartSpan();

                Assert.True(childSpan.Context.IsValid);
                Assert.Equal(rootSpan.Context.TraceId, childSpan.Context.TraceId);
                Assert.Equal(rootSpan.Context.SpanId, childSpan.ParentSpanId);
                Assert.Equal("k1=v1", childSpan.Context.Tracestate.ToString());
            }
        }
Exemple #10
0
        public void TestW3CHeadersTraceStateAndCorrelationContext()
        {
            RemoteExecutor.Invoke(async() =>
            {
                using (var eventRecords = new EventObserverAndRecorder())
                {
                    var parent = new Activity("w3c activity");
                    parent.SetParentId(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom());
                    parent.TraceStateString = "some=state";
                    parent.AddBaggage("k", "v");
                    parent.Start();

                    // Send a random Http request to generate some events
                    using (var client = new HttpClient())
                    {
                        (await client.GetAsync(Configuration.Http.RemoteEchoServer)).Dispose();
                    }

                    parent.Stop();

                    // Check to make sure: The first record must be a request, the next record must be a response.
                    Assert.True(eventRecords.Records.TryDequeue(out var evnt));
                    Assert.Equal("System.Net.Http.Desktop.HttpRequestOut.Start", evnt.Key);
                    HttpWebRequest startRequest = ReadPublicProperty <HttpWebRequest>(evnt.Value, "Request");
                    Assert.NotNull(startRequest);

                    var traceparent        = startRequest.Headers["traceparent"];
                    var tracestate         = startRequest.Headers["tracestate"];
                    var correlationContext = startRequest.Headers["Correlation-Context"];
                    Assert.NotNull(traceparent);
                    Assert.Equal("some=state", tracestate);
                    Assert.Equal("k=v", correlationContext);
                    Assert.StartsWith($"00-{parent.TraceId.ToHexString()}-", traceparent);
                    Assert.Matches("^[0-9a-f]{2}-[0-9a-f]{32}-[0-9a-f]{16}-[0-9a-f]{2}$", traceparent);
                    Assert.Null(startRequest.Headers["Request-Id"]);
                }
            }).Dispose();
        }
        public void TelemetryPartBPropertiesContainsMSLinksWhenActivityHasLinks(string telemetryType)
        {
            using ActivitySource activitySource = new ActivitySource(ActivitySourceName);
            ActivityLink activityLink = new ActivityLink(new ActivityContext(
                                                             ActivityTraceId.CreateRandom(),
                                                             ActivitySpanId.CreateRandom(),
                                                             ActivityTraceFlags.None), null);

            List <ActivityLink> links = new List <ActivityLink>();

            links.Add(activityLink);

            using var activity = activitySource.StartActivity(
                      ActivityName,
                      ActivityKind.Client,
                      parentContext: default,
                      null,
                      links,
                      startTime: DateTime.UtcNow);

            string expectedMSlinks = GetExpectedMSlinks(links);
            string actualMSlinks   = null;

            var monitorTags = TraceHelper.EnumerateActivityTags(activity);

            if (telemetryType == "RequestData")
            {
                var telemetryPartBRequestData = new RequestData(2, activity, ref monitorTags);
                Assert.True(telemetryPartBRequestData.Properties.TryGetValue(msLinks, out actualMSlinks));
            }
            if (telemetryType == "RemoteDependencyData")
            {
                var telemetryPartBRemoteDependencyData = new RemoteDependencyData(2, activity, ref monitorTags);
                Assert.True(telemetryPartBRemoteDependencyData.Properties.TryGetValue(msLinks, out actualMSlinks));
            }

            Assert.Equal(expectedMSlinks, actualMSlinks);
        }
        public void DoNotCrash()
        {
            IDictionary <string, object> attributes = new Dictionary <string, object>();

            attributes.Add(
                "MyStringAttributeKey", "MyStringAttributeValue");
            IDictionary <string, object> multipleAttributes = new Dictionary <string, object>();

            multipleAttributes.Add(
                "MyStringAttributeKey", "MyStringAttributeValue");
            multipleAttributes.Add("MyBooleanAttributeKey", true);
            multipleAttributes.Add("MyLongAttributeKey", 123);
            multipleAttributes.Add("MyDoubleAttributeKey", 0.005);
            // Tests only that all the methods are not crashing/throwing errors.
            BlankSpan.Instance.SetAttribute(
                "MyStringAttributeKey2", "MyStringAttributeValue2");
            foreach (var a in attributes)
            {
                BlankSpan.Instance.SetAttribute(a);
            }

            foreach (var a in multipleAttributes)
            {
                BlankSpan.Instance.SetAttribute(a);
            }

            BlankSpan.Instance.AddEvent("MyEvent");
            BlankSpan.Instance.AddEvent("MyEvent", attributes);
            BlankSpan.Instance.AddEvent("MyEvent", multipleAttributes);
            BlankSpan.Instance.AddEvent(new Event("MyEvent"));
            BlankSpan.Instance.AddLink(new Link(new SpanContext(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.None)));

            Assert.False(BlankSpan.Instance.Context.IsValid);
            Assert.False(BlankSpan.Instance.IsRecordingEvents);
            Assert.Equal(Status.Ok, BlankSpan.Instance.Status);
            BlankSpan.Instance.Status = Status.Ok;
            BlankSpan.Instance.End();
        }
        public void StartSpan_WithLinkFromSpanContext()
        {
            var linkContext =
                SpanContext.Create(
                    ActivityTraceId.CreateRandom(),
                    ActivitySpanId.CreateRandom(),
                    ActivityTraceFlags.None, Tracestate.Empty);

            var span = new SpanBuilder(SpanName, spanBuilderOptions)
                       .SetSpanKind(SpanKind.Internal)
                       .AddLink(linkContext)
                       .StartSpan();

            var spanData = ((Span)span).ToSpanData();
            var links    = spanData.Links.Links.ToArray();

            Assert.Single(links);

            Assert.Equal(linkContext.TraceId, links[0].Context.TraceId);
            Assert.Equal(linkContext.SpanId, links[0].Context.SpanId);
            Assert.Equal(linkContext.TraceOptions, links[0].Context.TraceOptions);
            Assert.Equal(linkContext.Tracestate, links[0].Context.Tracestate);
        }
        public void StartSpan_WithLink()
        {
            var link = new Link(
                new SpanContext(
                    ActivityTraceId.CreateRandom(),
                    ActivitySpanId.CreateRandom(),
                    ActivityTraceFlags.None));

            var span = (Span) new SpanBuilder(SpanName, spanProcessor, alwaysSampleTracerConfiguration, Resource.Empty)
                       .SetSpanKind(SpanKind.Internal)
                       .AddLink(link)
                       .StartSpan();

            var links = span.Links.ToArray();

            Assert.Single(links);

            Assert.Equal(link.Context.TraceId, links[0].Context.TraceId);
            Assert.Equal(link.Context.SpanId, links[0].Context.SpanId);
            Assert.Equal(link.Context.TraceOptions, links[0].Context.TraceOptions);
            Assert.Equal(link.Context.Tracestate, links[0].Context.Tracestate);
            Assert.Equal(0, links[0].Attributes.Count);
        }
Exemple #15
0
        public void ProactivelySampledInItemsAreNotGivenPriorityIfRatesAreNotSet()
        {
            var sentTelemetry = new List <ITelemetry>();
            TelemetryProcessorChain telemetryProcessorChainWithSampling = CreateTelemetryProcessorChainWithSampling(
                sentTelemetry,
                50);

            for (int i = 0; i < 1000; i++)
            {
                var item = new RequestTelemetry();
                item.Context.Operation.Id = ActivityTraceId.CreateRandom().ToHexString();

                // proactively sample in items with big score, so they should not be sampled in
                if (SamplingScoreGenerator.GetSamplingScore(item.Context.Operation.Id) > 50)
                {
                    item.ProactiveSamplingDecision = SamplingDecision.SampledIn;
                }

                telemetryProcessorChainWithSampling.Process(item);
            }

            Assert.AreEqual(0, sentTelemetry.Count(i => ((ISupportAdvancedSampling)i).ProactiveSamplingDecision == SamplingDecision.SampledIn));
        }
Exemple #16
0
        public void ProcessorDoesNotBlockOnExporter()
        {
            spanExporter = new TestExporter(async _ => await Task.Delay(500));
            tracer       = TracerFactory.Create(b => b
                                                .SetExporter(spanExporter)
                                                .SetProcessor(e => new SimpleSpanProcessor(e)))
                           .GetTracer(null);

            var context = new SpanContext(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.Recorded);
            var span    = (Span)tracer.StartSpan("foo", context);

            // does not block
            var sw = Stopwatch.StartNew();

            span.End();
            sw.Stop();

            Assert.InRange(sw.Elapsed, TimeSpan.Zero, TimeSpan.FromMilliseconds(100));

            var exported = WaitForSpans(spanExporter, 1, TimeSpan.FromMilliseconds(600));

            Assert.Single(exported);
        }
        public async Task ProcessEvents_SingleDispatch_SystemPropertiesAndApplicationProperties()
        {
            var partitionContext = EventHubTests.GetPartitionContext();
            var options          = new EventHubOptions {
                BatchCheckpointFrequency = 1
            };

            var checkpointer = new Mock <EventHubListener.ICheckpointer>();

            var loggerMock = new Mock <ILogger>();
            var executor   = new Mock <ITriggeredFunctionExecutor>(MockBehavior.Strict);

            executor.Setup(p => p.TryExecuteAsync(It.IsAny <TriggeredFunctionData>(), It.IsAny <CancellationToken>())).ReturnsAsync(new FunctionResult(true));
            var eventProcessor = new EventHubListener.EventProcessor(options, executor.Object, loggerMock.Object, true, checkpointer.Object);

            var diagnosticId = $"00-{ActivityTraceId.CreateRandom().ToHexString()}-{ActivitySpanId.CreateRandom().ToHexString()}-01";

            var eventData = new EventData(new byte[0])
            {
                SystemProperties = new EventData.SystemPropertiesCollection(-1, DateTime.Now, "0", "1")
                {
                    { "Diagnostic-Id", diagnosticId }
                },

                // will be ignored
                Properties = { ["Diagnostic-Id"] = $"00-{ActivityTraceId.CreateRandom().ToHexString()}-{ActivitySpanId.CreateRandom().ToHexString()}-01" }
            };

            await eventProcessor.ProcessEventsAsync(partitionContext, new[] { eventData });

            Func <Dictionary <string, object>, bool> checkLinksScope = (scope) => scope.TryGetValue("Links", out var links) &&
                                                                       links is IEnumerable <Activity> linksList &&
                                                                       linksList.Count() == 1 &&
                                                                       linksList.Single().ParentId == diagnosticId;

            loggerMock.Verify(l => l.BeginScope(It.Is <Dictionary <string, object> >(s => checkLinksScope(s))), Times.Once);
        }
        internal static bool ShouldSample(SpanContext parentContext, string name, ISampler sampler, out SpanContext context, out ActivitySpanId parentSpanId)
        {
            ActivityTraceId traceId    = default;
            var             tracestate = Tracestate.Empty;

            parentSpanId = default;
            var parentOptions = ActivityTraceFlags.None;

            if (parentContext.IsValid)
            {
                traceId       = parentContext.TraceId;
                parentSpanId  = parentContext.SpanId;
                parentOptions = parentContext.TraceOptions;
            }
            else
            {
                traceId = ActivityTraceId.CreateRandom();
            }

            var result       = (parentOptions & ActivityTraceFlags.Recorded) != 0;
            var spanId       = ActivitySpanId.CreateRandom();
            var traceOptions = ActivityTraceFlags.None;

            if (sampler != null)
            {
                traceOptions = parentContext.TraceOptions;
                result       = sampler.ShouldSample(parentContext, traceId, spanId, name, null);
                if (result)
                {
                    traceOptions |= ActivityTraceFlags.Recorded;
                }
            }

            context = SpanContext.Create(traceId, spanId, traceOptions, parentContext.Tracestate);

            return(result);
        }
        public void StartRemoteSpan()
        {
            var spanContext =
                new SpanContext(
                    ActivityTraceId.CreateRandom(),
                    ActivitySpanId.CreateRandom(),
                    ActivityTraceFlags.None,
                    new List <KeyValuePair <string, string> > {
                new KeyValuePair <string, string>("k1", "v1")
            });

            var span = (Span) new SpanBuilder(SpanName, spanProcessor, alwaysSampleTracerConfiguration, Resource.Empty)
                       .SetSpanKind(SpanKind.Internal)
                       .SetParent(spanContext)
                       .SetRecordEvents(true)
                       .StartSpan();

            Assert.True(span.Context.IsValid);
            Assert.Equal(spanContext.TraceId, span.Context.TraceId);
            Assert.True((span.Context.TraceOptions & ActivityTraceFlags.Recorded) != 0);

            Assert.Equal(spanContext.SpanId, span.ParentSpanId);
            Assert.Equal("k1=v1", TracestateUtils.GetString(span.Context.Tracestate));
        }
        public void StartSpan_CurrentSpanParent()
        {
            var rootSpan = new SpanBuilder(SpanName, spanProcessor, alwaysSampleTracerConfiguration, Resource.Empty)
                           .SetParent(
                new SpanContext(
                    ActivityTraceId.CreateRandom(),
                    ActivitySpanId.CreateRandom(),
                    ActivityTraceFlags.None,
                    new List <KeyValuePair <string, string> > {
                new KeyValuePair <string, string>("k1", "v1")
            }))
                           .StartSpan();

            using (tracer.WithSpan(rootSpan))
            {
                var childSpan = (Span) new SpanBuilder(SpanName, spanProcessor, alwaysSampleTracerConfiguration, Resource.Empty)
                                .StartSpan();

                Assert.True(childSpan.Context.IsValid);
                Assert.Equal(rootSpan.Context.TraceId, childSpan.Context.TraceId);
                Assert.Equal(rootSpan.Context.SpanId, childSpan.ParentSpanId);
                Assert.Equal("k1=v1", TracestateUtils.GetString(childSpan.Context.Tracestate));
            }
        }
Exemple #21
0
        public void StartStopRespectsUserProvidedIdsInScopeOfAnotherActivityExplicitOperationIdOnly()
        {
            var activity = new Activity("foo").Start();

            var customOperationId = ActivityTraceId.CreateRandom().ToHexString();

            using (var operation = this.telemetryClient.StartOperation <DependencyTelemetry>("name", customOperationId))
            {
                Assert.IsNotNull(Activity.Current);
                Assert.AreNotEqual(activity, Activity.Current.Parent);
                Assert.AreEqual(customOperationId, Activity.Current.TraceId.ToHexString());
                Assert.AreEqual(customOperationId, operation.Telemetry.Context.Operation.Id);
                Assert.IsNull(operation.Telemetry.Context.Operation.ParentId);
            }

            Assert.AreEqual(activity, Activity.Current);
            Assert.AreEqual(1, this.sendItems.Count);
            Assert.IsTrue(this.sendItems.Single() is DependencyTelemetry);

            var dependency = this.sendItems.Single() as DependencyTelemetry;

            Assert.AreEqual(customOperationId, dependency.Context.Operation.Id);
            Assert.IsNull(dependency.Context.Operation.ParentId);
        }
Exemple #22
0
        private static async Task RunAsync()
        {
            var endpoint = "/delay/5ms";

            using var listener = new HttpEventListener();

            source = new ActivitySource("http-client-test");

            var serviceCollection = new ServiceCollection();

            serviceCollection.AddHttpOptionsTelemetry(builder => builder.AddConsoleExporter());


            serviceCollection.AddHttpClientOptions(options =>
            {
                options.ServiceName           = "service";
                options.Handler.MaxConnection = 500;
                _server.ConfigureWireMockServer(options);
            });


            var services =
                serviceCollection.BuildServiceProvider();
            await Task.WhenAll(services.GetServices <IHostedService>()
                               .Select(e => e.StartAsync(CancellationToken.None)));

            var factory = services.GetRequiredService <IHttpClientFactory>();
            var client  = factory.CreateClient("service");

            var stopwatch = Stopwatch.StartNew();

            Console.WriteLine("oooo: ");

            do
            {
                try
                {
                    await client.GetAsync(endpoint).ConfigureAwait(false);
                }
                catch (Exception e)
                {
                }
            } while (Console.ReadKey().Key != ConsoleKey.Escape);


            do
            {
                try
                {
                    var activityLinks = new List <ActivityLink>();
                    var initialTags   = new ActivityTagsCollection();

                    initialTags["com.mycompany.product.mytag1"] = "tagValue1";
                    initialTags["com.mycompany.product.mytag2"] = "tagValue2";

                    var linkedContext1 = new ActivityContext(
                        ActivityTraceId.CreateRandom(),
                        ActivitySpanId.CreateRandom(),
                        ActivityTraceFlags.None);

                    var linkedContext2 = new ActivityContext(
                        ActivityTraceId.CreateRandom(),
                        ActivitySpanId.CreateRandom(),
                        ActivityTraceFlags.Recorded);

                    activityLinks.Add(new ActivityLink(linkedContext1));
                    activityLinks.Add(new ActivityLink(linkedContext2));


                    using var activity = source.StartActivity(
                              "ActivityWithLinks",
                              ActivityKind.Server,
                              default(ActivityContext),
                              initialTags,
                              activityLinks);
                    var latencyStats = await TrafficGenerator
                                       .GenerateTraffic(100, () => client.GetAsync(endpoint))
                                       .Latency()
                                       .TakeUntil(DateTimeOffset.Now.AddSeconds(20));

                    Console.WriteLine(latencyStats.Print());
                    await client.GetAsync(endpoint).ConfigureAwait(false);

                    System.Console.WriteLine("Press Enter key to continue.");
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                    throw;
                }
            } while (Console.ReadKey().Key != ConsoleKey.Escape);
        }
Exemple #23
0
        public void ActivityTraceFlagsTests()
        {
            Activity activity;

            // Set the 'Recorded' bit by using SetParentId with a -01 flags.
            activity = new Activity("activity1");
            activity.SetParentId("00-0123456789abcdef0123456789abcdef-0123456789abcdef-01");
            activity.Start();
            Assert.Equal(ActivityIdFormat.W3C, activity.IdFormat);
            Assert.Equal("0123456789abcdef0123456789abcdef", activity.TraceId.ToHexString());
            Assert.Equal("0123456789abcdef", activity.ParentSpanId.ToHexString());
            Assert.True(IdIsW3CFormat(activity.Id));
            Assert.Equal($"00-0123456789abcdef0123456789abcdef-{activity.SpanId.ToHexString()}-01", activity.Id);
            Assert.Equal(ActivityTraceFlags.Recorded, activity.ActivityTraceFlags);
            Assert.True(activity.Recorded);
            activity.Stop();

            // Set the 'Recorded' bit by using SetParentId by using the TraceId, SpanId, ActivityTraceFlags overload
            activity = new Activity("activity2");
            ActivityTraceId activityTraceId = ActivityTraceId.CreateRandom();

            activity.SetParentId(activityTraceId, ActivitySpanId.CreateRandom(), ActivityTraceFlags.Recorded);
            activity.Start();
            Assert.Equal(ActivityIdFormat.W3C, activity.IdFormat);
            Assert.Equal(activityTraceId.ToHexString(), activity.TraceId.ToHexString());
            Assert.True(IdIsW3CFormat(activity.Id));
            Assert.Equal($"00-{activity.TraceId.ToHexString()}-{activity.SpanId.ToHexString()}-01", activity.Id);
            Assert.Equal(ActivityTraceFlags.Recorded, activity.ActivityTraceFlags);
            Assert.True(activity.Recorded);
            activity.Stop();

            /****************************************************/
            // Set the 'Recorded' bit explicitly after the fact.
            activity = new Activity("activity3");
            activity.SetParentId("00-0123456789abcdef0123456789abcdef-0123456789abcdef-00");
            activity.Start();
            Assert.Equal(ActivityIdFormat.W3C, activity.IdFormat);
            Assert.Equal("0123456789abcdef0123456789abcdef", activity.TraceId.ToHexString());
            Assert.Equal("0123456789abcdef", activity.ParentSpanId.ToHexString());
            Assert.True(IdIsW3CFormat(activity.Id));
            Assert.Equal($"00-{activity.TraceId.ToHexString()}-{activity.SpanId.ToHexString()}-00", activity.Id);
            Assert.Equal(ActivityTraceFlags.None, activity.ActivityTraceFlags);
            Assert.False(activity.Recorded);

            activity.ActivityTraceFlags = ActivityTraceFlags.Recorded;
            Assert.Equal(ActivityTraceFlags.Recorded, activity.ActivityTraceFlags);
            Assert.True(activity.Recorded);
            activity.Stop();

            /****************************************************/
            // Confirm that that flags are propagated to children.
            activity = new Activity("activity4");
            activity.SetParentId("00-0123456789abcdef0123456789abcdef-0123456789abcdef-01");
            activity.Start();
            Assert.Equal(activity, Activity.Current);
            Assert.Equal(ActivityIdFormat.W3C, activity.IdFormat);
            Assert.Equal("0123456789abcdef0123456789abcdef", activity.TraceId.ToHexString());
            Assert.Equal("0123456789abcdef", activity.ParentSpanId.ToHexString());
            Assert.True(IdIsW3CFormat(activity.Id));
            Assert.Equal($"00-{activity.TraceId.ToHexString()}-{activity.SpanId.ToHexString()}-01", activity.Id);
            Assert.Equal(ActivityTraceFlags.Recorded, activity.ActivityTraceFlags);
            Assert.True(activity.Recorded);

            // create a child
            var childActivity = new Activity("activity4Child");

            childActivity.Start();
            Assert.Equal(childActivity, Activity.Current);

            Assert.Equal("0123456789abcdef0123456789abcdef", childActivity.TraceId.ToHexString());
            Assert.NotEqual(activity.SpanId.ToHexString(), childActivity.SpanId.ToHexString());
            Assert.True(IdIsW3CFormat(childActivity.Id));
            Assert.Equal($"00-{childActivity.TraceId.ToHexString()}-{childActivity.SpanId.ToHexString()}-01", childActivity.Id);
            Assert.Equal(ActivityTraceFlags.Recorded, childActivity.ActivityTraceFlags);
            Assert.True(childActivity.Recorded);

            childActivity.Stop();
            activity.Stop();
        }
Exemple #24
0
        public void IdFormatTests()
        {
            try
            {
                Activity activity;

                // Default format is the default (Hierarchical)
                activity = new Activity("activity1");
                activity.Start();
                Assert.Equal(ActivityIdFormat.Hierarchical, activity.IdFormat);
                activity.Stop();

                // Set the parent to something that is W3C by string
                activity = new Activity("activity2");
                activity.SetParentId("00-0123456789abcdef0123456789abcdef-0123456789abcdef-00");
                activity.Start();
                Assert.Equal(ActivityIdFormat.W3C, activity.IdFormat);
                Assert.Equal("0123456789abcdef0123456789abcdef", activity.TraceId.ToHexString());
                Assert.Equal("0123456789abcdef", activity.ParentSpanId.ToHexString());
                Assert.Equal(ActivityTraceFlags.None, activity.ActivityTraceFlags);
                Assert.False(activity.Recorded);
                Assert.True(IdIsW3CFormat(activity.Id));
                activity.Stop();

                // Set the parent to something that is W3C but using ActivityTraceId,ActivitySpanId version of SetParentId.
                activity = new Activity("activity3");
                ActivityTraceId activityTraceId = ActivityTraceId.CreateRandom();
                activity.SetParentId(activityTraceId, ActivitySpanId.CreateRandom());
                activity.Start();
                Assert.Equal(ActivityIdFormat.W3C, activity.IdFormat);
                Assert.Equal(activityTraceId.ToHexString(), activity.TraceId.ToHexString());
                Assert.Equal(ActivityTraceFlags.None, activity.ActivityTraceFlags);
                Assert.False(activity.Recorded);
                Assert.True(IdIsW3CFormat(activity.Id));
                activity.Stop();

                // Change DefaultIdFormat to W3C, confirm I get the new format.
                Activity.DefaultIdFormat = ActivityIdFormat.W3C;
                activity = new Activity("activity4");
                activity.Start();
                Assert.Equal(ActivityIdFormat.W3C, activity.IdFormat);
                Assert.True(IdIsW3CFormat(activity.Id));
                activity.Stop();

                // But I don't get the default format if parent is hierarchical
                activity = new Activity("activity5");
                string parentId = "|a000b421-5d183ab6.1";
                activity.SetParentId(parentId);
                activity.Start();
                Assert.Equal(ActivityIdFormat.Hierarchical, activity.IdFormat);
                Assert.True(activity.Id.StartsWith(parentId));

                // Heirarchical Ids return null ActivityTraceId and ActivitySpanIds
                Assert.Equal("00000000000000000000000000000000", activity.TraceId.ToHexString());
                Assert.Equal("0000000000000000", activity.SpanId.ToHexString());
                activity.Stop();

                // But if I set ForceDefaultFormat I get what I asked for (W3C format)
                Activity.ForceDefaultIdFormat = true;
                activity = new Activity("activity6");
                activity.SetParentId(parentId);
                activity.Start();
                Assert.Equal(ActivityIdFormat.W3C, activity.IdFormat);
                Assert.True(IdIsW3CFormat(activity.Id));
                Assert.NotEqual("00000000000000000000000000000000", activity.TraceId.ToHexString());
                Assert.NotEqual("0000000000000000", activity.SpanId.ToHexString());

                /* TraceStateString testing */
                // Test TraceStateString (that it inherits from parent)
                Activity parent     = new Activity("parent");
                string   testString = "MyTestString";
                parent.TraceStateString = testString;
                parent.Start();
                Assert.Equal(testString, parent.TraceStateString);

                activity = new Activity("activity7");
                activity.Start();
                Assert.Equal(ActivityIdFormat.W3C, activity.IdFormat);
                Assert.True(IdIsW3CFormat(activity.Id));
                Assert.Equal(testString, activity.TraceStateString);

                // Update child
                string childTestString = "ChildTestString";
                activity.TraceStateString = childTestString;

                // Confirm that child sees update, but parent does not
                Assert.Equal(childTestString, activity.TraceStateString);
                Assert.Equal(testString, parent.TraceStateString);

                // Update parent
                string parentTestString = "newTestString";
                parent.TraceStateString = parentTestString;

                // Confirm that parent sees update but child does not.
                Assert.Equal(childTestString, activity.TraceStateString);
                Assert.Equal(parentTestString, parent.TraceStateString);

                activity.Stop();
                parent.Stop();

                // Upper-case ids are not supported
                activity = new Activity("activity8");
                activity.SetParentId("00-0123456789ABCDEF0123456789ABCDEF-0123456789ABCDEF-01");
                activity.Start();
                Assert.Equal(ActivityIdFormat.W3C, activity.IdFormat);
                Assert.True(IdIsW3CFormat(activity.Id));
                activity.Stop();

                // non hex chars are not supported in traceId
                activity = new Activity("activity9");
                activity.SetParentId("00-xyz3456789abcdef0123456789abcdef-0123456789abcdef-01");
                activity.Start();
                Assert.Equal(ActivityIdFormat.W3C, activity.IdFormat);
                Assert.True(IdIsW3CFormat(activity.Id));
                activity.Stop();

                // non hex chars are not supported in parentSpanId
                activity = new Activity("activity10");
                activity.SetParentId("00-0123456789abcdef0123456789abcdef-x123456789abcdef-01");
                activity.Start();
                Assert.Equal(ActivityIdFormat.W3C, activity.IdFormat);
                Assert.True(IdIsW3CFormat(activity.Id));
                Assert.Equal("0000000000000000", activity.ParentSpanId.ToHexString());
                Assert.Equal("0123456789abcdef0123456789abcdef", activity.TraceId.ToHexString());
                activity.Stop();

                // ParentSpanId from parent Activity
                Activity.DefaultIdFormat      = ActivityIdFormat.W3C;
                Activity.ForceDefaultIdFormat = true;

                parent   = new Activity("parent").Start();
                activity = new Activity("parent").Start();
                Assert.Equal(parent.SpanId.ToHexString(), activity.ParentSpanId.ToHexString());

                activity.Stop();
                parent.Stop();
            }
            finally
            {
                // Set global settings back to the default, just to put the state back.
                Activity.ForceDefaultIdFormat = false;
                Activity.DefaultIdFormat      = ActivityIdFormat.Hierarchical;
                Activity.Current = null;
            }
        }
Exemple #25
0
        public void ActivityTraceIdTests()
        {
            Span <byte> idBytes1 = stackalloc byte[16];
            Span <byte> idBytes2 = stackalloc byte[16];

            // Empty Constructor
            string          zeros   = "00000000000000000000000000000000";
            ActivityTraceId emptyId = new ActivityTraceId();

            Assert.Equal(zeros, emptyId.ToHexString());
            emptyId.CopyTo(idBytes1);
            Assert.Equal(new byte[16], idBytes1.ToArray());

            Assert.True(emptyId == new ActivityTraceId());
            Assert.True(!(emptyId != new ActivityTraceId()));
            Assert.True(emptyId.Equals(new ActivityTraceId()));
            Assert.True(emptyId.Equals((object)new ActivityTraceId()));
            Assert.Equal(new ActivityTraceId().GetHashCode(), emptyId.GetHashCode());

            // NewActivityTraceId
            ActivityTraceId newId1 = ActivityTraceId.CreateRandom();

            Assert.True(IsLowerCaseHex(newId1.ToHexString()));
            Assert.Equal(32, newId1.ToHexString().Length);

            ActivityTraceId newId2 = ActivityTraceId.CreateRandom();

            Assert.Equal(32, newId1.ToHexString().Length);
            Assert.NotEqual(newId1.ToHexString(), newId2.ToHexString());

            // Test equality
            Assert.True(newId1 != newId2);
            Assert.True(!(newId1 == newId2));
            Assert.True(!(newId1.Equals(newId2)));
            Assert.True(!(newId1.Equals((object)newId2)));
            Assert.NotEqual(newId1.GetHashCode(), newId2.GetHashCode());

            ActivityTraceId newId3 = ActivityTraceId.CreateFromString("00000000000000000000000000000001".AsSpan());

            Assert.True(newId3 != emptyId);
            Assert.True(!(newId3 == emptyId));
            Assert.True(!(newId3.Equals(emptyId)));
            Assert.True(!(newId3.Equals((object)emptyId)));
            Assert.NotEqual(newId3.GetHashCode(), emptyId.GetHashCode());

            // Use in Dictionary (this does assume we have no collisions in IDs over 100 tries (very good).
            var dict = new Dictionary <ActivityTraceId, string>();

            for (int i = 0; i < 100; i++)
            {
                var newId7 = ActivityTraceId.CreateRandom();
                dict[newId7] = newId7.ToHexString();
            }
            int ctr = 0;

            foreach (string value in dict.Values)
            {
                string valueInDict;
                Assert.True(dict.TryGetValue(ActivityTraceId.CreateFromString(value.AsSpan()), out valueInDict));
                Assert.Equal(value, valueInDict);
                ctr++;
            }
            Assert.Equal(100, ctr);     // We got out what we put in.

            // AsBytes and Byte constructor.
            newId2.CopyTo(idBytes2);
            ActivityTraceId newId2Clone = ActivityTraceId.CreateFromBytes(idBytes2);

            Assert.Equal(newId2.ToHexString(), newId2Clone.ToHexString());
            newId2Clone.CopyTo(idBytes1);
            Assert.Equal(idBytes2.ToArray(), idBytes1.ToArray());

            Assert.True(newId2 == newId2Clone);
            Assert.True(newId2.Equals(newId2Clone));
            Assert.True(newId2.Equals((object)newId2Clone));
            Assert.Equal(newId2.GetHashCode(), newId2Clone.GetHashCode());

            // String constructor and ToHexString().
            string          idStr = "0123456789abcdef0123456789abcdef";
            ActivityTraceId id    = ActivityTraceId.CreateFromString(idStr.AsSpan());

            Assert.Equal(idStr, id.ToHexString());

            // Utf8 Constructor.
            byte[]          idUtf8 = Encoding.UTF8.GetBytes(idStr);
            ActivityTraceId id1    = ActivityTraceId.CreateFromUtf8String(idUtf8);

            Assert.Equal(idStr, id1.ToHexString());

            // ToString
            Assert.Equal(idStr, id.ToString());
        }
Exemple #26
0
        public void BuildSamplingParametersHandlesCurrentActivity()
        {
            using var activitySource = new ActivitySource(nameof(this.BuildSamplingParametersHandlesCurrentActivity));

            var testSampler = new TestSampler {
                DesiredSamplingResult = new SamplingResult(true)
            };

            using var listener = new ActivityListener
                  {
                      ShouldListenTo = _ => true,
                      GetRequestedDataUsingContext = (ref ActivityCreationOptions <ActivityContext> options) =>
                                                     Sdk.ComputeActivityDataRequest(options, testSampler),
                  };

            ActivitySource.AddActivityListener(listener);

            using (var root = activitySource.StartActivity("root"))
            {
                Assert.Equal(default(ActivitySpanId), root.ParentSpanId);

                // This enforces the current behavior that the traceId passed to the sampler for the
                // root span/activity is not the traceId actually used.
                Assert.NotEqual(root.TraceId, testSampler.LatestSamplingParameters.TraceId);
            }

            using (var parent = activitySource.StartActivity("parent", ActivityKind.Client))
            {
                // This enforces the current behavior that the traceId passed to the sampler for the
                // root span/activity is not the traceId actually used.
                Assert.NotEqual(parent.TraceId, testSampler.LatestSamplingParameters.TraceId);
                using (var child = activitySource.StartActivity("child"))
                {
                    Assert.Equal(parent.TraceId, testSampler.LatestSamplingParameters.TraceId);
                    Assert.Equal(parent.TraceId, child.TraceId);
                    Assert.Equal(parent.SpanId, child.ParentSpanId);
                }
            }

            var customContext = new ActivityContext(
                ActivityTraceId.CreateRandom(),
                ActivitySpanId.CreateRandom(),
                ActivityTraceFlags.None);

            using (var fromCustomContext =
                       activitySource.StartActivity("customContext", ActivityKind.Client, customContext))
            {
                Assert.Equal(customContext.TraceId, fromCustomContext.TraceId);
                Assert.Equal(customContext.SpanId, fromCustomContext.ParentSpanId);
                Assert.NotEqual(customContext.SpanId, fromCustomContext.SpanId);
            }

            // Preserve traceId in case span is propagated but not recorded (sampled per OpenTelemetry parlance) and
            // no data is requested for children spans.
            testSampler.DesiredSamplingResult = new SamplingResult(false);
            using (var root = activitySource.StartActivity("root"))
            {
                Assert.Equal(default(ActivitySpanId), root.ParentSpanId);

                using (var child = activitySource.StartActivity("child"))
                {
                    Assert.Null(child);
                    Assert.Equal(root.TraceId, testSampler.LatestSamplingParameters.TraceId);
                    Assert.Same(Activity.Current, root);
                }
            }
        }
        public void AllPropertiesShouldTranslate()
        {
            var startTs = DateTime.UtcNow;
            var endTs   = startTs.AddSeconds(60);
            var evtTs   = DateTime.UtcNow;

            var traceId  = ActivityTraceId.CreateRandom();
            var parentId = ActivitySpanId.CreateRandom();

            var traceIdInt  = traceId.ToLSTraceId();
            var parentIdInt = parentId.ToLSSpanId();

            var attrs = new Dictionary <string, object>
            {
                ["stringKey"] = "foo",
                ["longKey"]   = 1L,
                ["doubleKey"] = 1D,
                ["boolKey"]   = true,
            };

            var evts = new List <Event>
            {
                new Event(
                    "evt1",
                    evtTs,
                    new Dictionary <string, object> {
                    { "key", "value" },
                }
                    ),
                new Event(
                    "evt2",
                    evtTs,
                    new Dictionary <string, object> {
                    { "key", "value" },
                }
                    ),
            };

            var linkedSpanId = ActivitySpanId.CreateRandom();
            var link         = new Link(new Trace.SpanContext(
                                            traceId, linkedSpanId, ActivityTraceFlags.Recorded));

            var span = (Span)tracer
                       .StartSpan("Test", new Trace.SpanContext(traceId, parentId, ActivityTraceFlags.Recorded), SpanKind.Client,
                                  new SpanCreationOptions
            {
                StartTimestamp = startTs,
                Links          = new[] { link },
            });

            var spanIdInt = span.Context.SpanId.ToLSSpanId();

            foreach (var attribute in attrs)
            {
                span.SetAttribute(attribute.Key, attribute.Value);
            }

            foreach (var evnt in evts)
            {
                span.AddEvent(evnt);
            }


            span.End(endTs);
            span.Status = Status.Ok;

            var lsSpan = span.ToLightStepSpan();

            Assert.Equal("Test", lsSpan.OperationName);
            Assert.Equal(2, lsSpan.Logs.Count);
            Assert.Equal(4, lsSpan.Tags.Count);

            Assert.Equal(traceIdInt, lsSpan.SpanContext.TraceId);
            Assert.Equal(spanIdInt, lsSpan.SpanContext.SpanId);
            Assert.Equal(parentIdInt, lsSpan.References[0].SpanContext.SpanId);
        }
Exemple #28
0
        public async Task EventHub_MultipleDispatch_IndependentMessages()
        {
            // send individual messages via EventHub client, process batch by host
            await using var ehClient = new EventHubProducerClient(EventHubsTestEnvironment.Instance.EventHubsConnectionString, _eventHubScope.EventHubName);

            var messages      = new EventData[5];
            var expectedLinks = new TestLink[messages.Length];

            for (int i = 0; i < messages.Length; i++)
            {
                var operationId = ActivityTraceId.CreateRandom().ToHexString();
                var spanId      = ActivitySpanId.CreateRandom().ToHexString();
                expectedLinks[i] = new TestLink
                {
                    operation_Id = operationId,
                    id           = spanId
                };

                messages[i] = new EventData(Encoding.UTF8.GetBytes(i.ToString()))
                {
                    Properties = { ["Diagnostic-Id"] = $"00-{operationId}-{spanId}-01" }
                };
            }

            await ehClient.SendAsync(messages);

            var(jobHost, host) = BuildHost <EventHubTestMultipleDispatchJobs>();
            using (host)
            {
                bool result = _eventWait.WaitOne(Timeout);
                Assert.True(result);
            }

            List <RequestTelemetry> requests = _channel.Telemetries.OfType <RequestTelemetry>().ToList();

            var ehTriggerRequests = requests.Where(r => r.Context.Operation.Name == nameof(EventHubTestMultipleDispatchJobs.ProcessMultipleEvents));

            List <TestLink> actualLinks = new List <TestLink>();

            foreach (var ehTriggerRequest in ehTriggerRequests)
            {
                ValidateEventHubRequest(
                    ehTriggerRequest,
                    true,
                    EventHubsTestEnvironment.Instance.FullyQualifiedNamespace,
                    _eventHubScope.EventHubName,
                    nameof(EventHubTestMultipleDispatchJobs.ProcessMultipleEvents),
                    null,
                    null);

                Assert.NotNull(ehTriggerRequest.Context.Operation.Id);
                Assert.Null(ehTriggerRequest.Context.Operation.ParentId);
                Assert.True(ehTriggerRequest.Properties.TryGetValue("_MS.links", out var linksStr));
                actualLinks.AddRange(JsonConvert.DeserializeObject <TestLink[]>(linksStr, jsonSettingThrowOnError));
            }

            Assert.AreEqual(expectedLinks.Length, actualLinks.Count);
            foreach (var link in actualLinks)
            {
                Assert.True(expectedLinks.Any(l => l.operation_Id == link.operation_Id && l.id == link.id));
            }
        }
Exemple #29
0
        public async Task CustomPropagator()
        {
            var activityProcessor = new Mock <BaseProcessor <Activity> >();

            var expectedTraceId = ActivityTraceId.CreateRandom();
            var expectedSpanId  = ActivitySpanId.CreateRandom();

            var propagator = new Mock <TextMapPropagator>();

            propagator.Setup(m => m.Extract(It.IsAny <PropagationContext>(), It.IsAny <HttpRequest>(), It.IsAny <Func <HttpRequest, string, IEnumerable <string> > >())).Returns(
                new PropagationContext(
                    new ActivityContext(
                        expectedTraceId,
                        expectedSpanId,
                        ActivityTraceFlags.Recorded),
                    default));

            // Arrange
            using (var testFactory = this.factory
                                     .WithWebHostBuilder(builder =>
                                                         builder.ConfigureTestServices(services =>
            {
                Sdk.SetDefaultTextMapPropagator(propagator.Object);
                this.openTelemetrySdk = Sdk.CreateTracerProviderBuilder()
                                        .AddAspNetCoreInstrumentation()
                                        .AddProcessor(activityProcessor.Object)
                                        .Build();
            })))
            {
                using var client = testFactory.CreateClient();
                var response = await client.GetAsync("/api/values/2");

                response.EnsureSuccessStatusCode(); // Status Code 200-299

                WaitForProcessorInvocations(activityProcessor, 4);
            }

            // List of invocations on the processor
            // 1. SetParentProvider for TracerProviderSdk
            // 2. OnStart for the activity created by AspNetCore with the OperationName: Microsoft.AspNetCore.Hosting.HttpRequestIn
            // 3. OnStart for the sibling activity created by the instrumentation library with the OperationName: ActivityCreatedByHttpInListener
            // 4. OnEnd for the sibling activity created by the instrumentation library with the OperationName: ActivityCreatedByHttpInListener
            Assert.Equal(4, activityProcessor.Invocations.Count);

            var startedActivities = activityProcessor.Invocations.Where(invo => invo.Method.Name == "OnStart");
            var stoppedActivities = activityProcessor.Invocations.Where(invo => invo.Method.Name == "OnEnd");

            Assert.Equal(2, startedActivities.Count());
            Assert.Single(stoppedActivities);

            // The activity created by the framework and the sibling activity are both sent to Processor.OnStart
            Assert.Contains(startedActivities, item =>
            {
                var startedActivity = item.Arguments[0] as Activity;
                return(startedActivity.OperationName == HttpInListener.ActivityOperationName);
            });

            Assert.Contains(startedActivities, item =>
            {
                var startedActivity = item.Arguments[0] as Activity;
                return(startedActivity.OperationName == HttpInListener.ActivityNameByHttpInListener);
            });

            // Only the sibling activity is sent to Processor.OnEnd
            Assert.Contains(stoppedActivities, item =>
            {
                var stoppedActivity = item.Arguments[0] as Activity;
                return(stoppedActivity.OperationName == HttpInListener.ActivityNameByHttpInListener);
            });

            var activity = activityProcessor.Invocations.FirstOrDefault(invo => invo.Method.Name == "OnEnd").Arguments[0] as Activity;

            Assert.Equal(ActivityKind.Server, activity.Kind);
            Assert.True(activity.Duration != TimeSpan.Zero);
            Assert.Equal("api/Values/{id}", activity.DisplayName);
            Assert.Equal("/api/values/2", activity.GetTagValue(SpanAttributeConstants.HttpPathKey) as string);

            Assert.Equal(expectedTraceId, activity.Context.TraceId);
            Assert.Equal(expectedSpanId, activity.ParentSpanId);
            Sdk.SetDefaultTextMapPropagator(new CompositeTextMapPropagator(new TextMapPropagator[]
            {
                new TraceContextPropagator(),
                new BaggagePropagator(),
            }));
        }
Exemple #30
0
 public static string GenerateTraceId()
 {
     return(ActivityTraceId.CreateRandom().ToHexString());
 }