public void CustomHeadersBecomeParentWhenThereAreNoW3CHeaders()
        {
            this.aspNetDiagnosticsSource.FakeContext =
                HttpModuleHelper.GetFakeHttpContext(new Dictionary <string, string>
            {
                ["rootHeaderName"]   = "root",
                ["parentHeaderName"] = "parent"
            });
            this.module = this.CreateModule("rootHeaderName", "parentHeaderName");

            var activity = new Activity(FakeAspNetDiagnosticSource.IncomingRequestEventName);

            activity.Extract(HttpContext.Current.Request.Headers);

            Assert.IsTrue(this.aspNetDiagnosticsSource.IsEnabled(FakeAspNetDiagnosticSource.IncomingRequestEventName, activity));
            this.aspNetDiagnosticsSource.StartActivityWithoutChecks(activity);
            Assert.AreEqual(activity, Activity.Current);
            this.aspNetDiagnosticsSource.StopActivity();

            Assert.AreEqual(1, this.sendItems.Count);

            var requestTelemetry = this.sendItems[0] as RequestTelemetry;

            Assert.IsNotNull(requestTelemetry);
            Assert.AreEqual(activity.TraceId.ToHexString(), requestTelemetry.Context.Operation.Id);
            Assert.AreEqual("parent", requestTelemetry.Context.Operation.ParentId);
            Assert.AreEqual(FormatTelemetryId(activity.TraceId, activity.SpanId), requestTelemetry.Id);

            Assert.IsTrue(requestTelemetry.Properties.TryGetValue("ai_legacyRootId", out var legacyRootId));
            Assert.AreEqual("root", legacyRootId);
            Assert.AreEqual(1, requestTelemetry.Properties.Count);
        }
Example #2
0
        public void TelemetryTrackedBeforeOnBeginW3CEnabledWithHeaders()
        {
            var context = HttpModuleHelper.GetFakeHttpContext(new Dictionary <string, string>());
            var config  = this.CreateDefaultConfig(context);
            var module  = this.RequestTrackingTelemetryModuleFactory(config);
            var client  = new TelemetryClient(config);

            // will not be correlated to request
            client.TrackTrace("test1");

            module.OnBeginRequest(context);

            // will be correlated to request
            client.TrackTrace("test2");

            // initialize telemetry
            module.OnEndRequest(context);

            var trace1 = (TraceTelemetry)this.sentTelemetry.Single(t => t is TraceTelemetry tt && tt.Message == "test1");
            var trace2 = (TraceTelemetry)this.sentTelemetry.Single(t => t is TraceTelemetry tt && tt.Message == "test2");

            var request = (RequestTelemetry)this.sentTelemetry.Single(t => t is RequestTelemetry);

            Assert.Equal(trace1.Context.Operation.Id, request.Context.Operation.Id);
            Assert.Equal(trace2.Context.Operation.Id, request.Context.Operation.Id);

            Assert.Equal(trace1.Context.Operation.ParentId, request.Id);
            Assert.Equal(trace2.Context.Operation.ParentId, request.Id);
        }
Example #3
0
        private void TestRequestTrackingWithW3CSupportEnabledAndNoW3CHeaders(bool addRequestId)
        {
            var headers = new Dictionary <string, string>();

            if (addRequestId)
            {
                headers.Add("Request-Id", "|abc.1.2.3.");
            }

            var context = HttpModuleHelper.GetFakeHttpContext(headers);

            var module = this.RequestTrackingTelemetryModuleFactory(this.CreateDefaultConfig(context));

            module.OnBeginRequest(context);
            var activityInitializedByW3CHeader = Activity.Current;

            var requestTelemetry = context.GetRequestTelemetry();

            module.OnEndRequest(context);

            Assert.Equal(activityInitializedByW3CHeader.SpanId.ToHexString(), requestTelemetry.Id);
            Assert.Equal(activityInitializedByW3CHeader.TraceId.ToHexString(), requestTelemetry.Context.Operation.Id);

            if (addRequestId)
            {
                Assert.Equal("|abc.1.2.3.", requestTelemetry.Context.Operation.ParentId);
                Assert.Contains("ai_legacyRootId", requestTelemetry.Properties.Keys);
                Assert.Equal("abc", requestTelemetry.Properties["ai_legacyRootId"]);
            }
            else
            {
                Assert.Null(requestTelemetry.Context.Operation.ParentId);
            }
        }
Example #4
0
        public void OnBeginReadsRootAndParentIdFromCustomHeader()
        {
            var context = HttpModuleHelper.GetFakeHttpContext(new Dictionary <string, string>
            {
                ["parentHeaderName"] = "ParentId",
                ["rootHeaderName"]   = "RootId"
            });

            var config = this.CreateDefaultConfig(context, rootIdHeaderName: "rootHeaderName", parentIdHeaderName: "parentHeaderName");
            var module = this.RequestTrackingTelemetryModuleFactory(config);

            module.OnBeginRequest(context);
            var activity = Activity.Current;

            var requestTelemetry = context.GetRequestTelemetry();

            Assert.Equal("ParentId", requestTelemetry.Context.Operation.ParentId);

            Assert.Equal(activity.TraceId.ToHexString(), requestTelemetry.Context.Operation.Id);

            // Assert.NotEqual($"|{activity.TraceId.ToHexString()}.{activity.SpanId.ToHexString()}", requestTelemetry.Id);
            Assert.Equal(activity.SpanId.ToHexString(), requestTelemetry.Id);
            Assert.True(requestTelemetry.Properties.TryGetValue("ai_legacyRootId", out var legacyRootId));
            Assert.Equal("RootId", legacyRootId);
        }
Example #5
0
        public void TelemetryCreatedWithinRequestScopeIsRequestChildWhenActivityIsLost()
        {
            var context = HttpModuleHelper.GetFakeHttpContext(new Dictionary <string, string>
            {
                ["traceparent"]         = "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01",
                ["Correlation-Context"] = "k=v"
            });
            var config          = this.CreateDefaultConfig(context);
            var module          = this.RequestTrackingTelemetryModuleFactory(config);
            var telemetryClient = new TelemetryClient(config);

            module.OnBeginRequest(context);

            // simulate losing call context by cleaning up activity
            Assert.NotNull(Activity.Current);
            Activity.Current = null;
            Assert.Null(Activity.Current);

            var trace = new TraceTelemetry();

            telemetryClient.TrackTrace(trace);
            var requestTelemetry = context.GetRequestTelemetry();

            Assert.Equal(requestTelemetry.Context.Operation.Id, trace.Context.Operation.Id);

            // we created Activity for request and assigned Id for the request like guid1.1.12345
            // then we created Activity for request children and assigned it Id like guid1.1.12345_1
            // then we lost it and restored (started a new child activity), so the Id is guid1.1.123_1.abc
            // so the request is grand parent to the trace
            Assert.True(trace.Context.Operation.ParentId.StartsWith(requestTelemetry.Id, StringComparison.Ordinal));
            Assert.Equal("v", trace.Properties["k"]);
        }
Example #6
0
        public void TrackIntermediateRequestSetsProperties()
        {
            string requestId = "|standard-id.";
            var    context   = HttpModuleHelper.GetFakeHttpContext(new Dictionary <string, string>
            {
                ["Request-Id"] = requestId
            });

            var module = this.RequestTrackingTelemetryModuleFactory(this.CreateDefaultConfig(context));

            module.OnBeginRequest(context);

            var originalRequest = context.GetRequestTelemetry();

            originalRequest.Start(Stopwatch.GetTimestamp() - (1 * Stopwatch.Frequency));

            var restoredActivity = new Activity("dummy").SetParentId(originalRequest.Id).Start();

            module.TrackIntermediateRequest(context, restoredActivity);
            module.OnEndRequest(context);
            Assert.Equal(2, this.sentTelemetry.Count);

            var intermediateRequest = this.sentTelemetry.OfType <RequestTelemetry>().First();

            Assert.Equal(originalRequest.Id, intermediateRequest.Context.Operation.ParentId);
            Assert.Equal(originalRequest.Context.Operation.Id, intermediateRequest.Context.Operation.Id);
            Assert.Equal(restoredActivity.StartTimeUtc, intermediateRequest.Timestamp);
            Assert.Equal(restoredActivity.Duration, intermediateRequest.Duration);
            Assert.True(intermediateRequest.Properties.ContainsKey("AI internal"));
        }
Example #7
0
        public void OnBeginSetsOperationContextWithStandardHeadersW3COff()
        {
            var context = HttpModuleHelper.GetFakeHttpContext(new Dictionary <string, string>
            {
                ["Request-Id"]          = "|guid1.1",
                ["Correlation-Context"] = "k=v"
            });
            var module = this.RequestTrackingTelemetryModuleFactory(this.CreateDefaultConfig(context));

            Activity.DefaultIdFormat      = ActivityIdFormat.Hierarchical;
            Activity.ForceDefaultIdFormat = true;

            module.OnBeginRequest(context);
            var requestTelemetry = context.GetRequestTelemetry();

            // initialize telemetry
            module.OnEndRequest(context);

            Assert.Equal("guid1", requestTelemetry.Context.Operation.Id);
            Assert.Equal("|guid1.1", requestTelemetry.Context.Operation.ParentId);

            Assert.True(requestTelemetry.Id.StartsWith("|guid1.1.", StringComparison.Ordinal));
            Assert.NotEqual("|guid1.1", requestTelemetry.Id);
            Assert.Equal("guid1", this.GetActivityRootId(requestTelemetry.Id));
            Assert.Equal("v", requestTelemetry.Properties["k"]);
        }
Example #8
0
        public void TelemetryCreatedWithinRequestScopeIsRequestChildWhenActivityIsLost()
        {
            var context = HttpModuleHelper.GetFakeHttpContext(new Dictionary <string, string>
            {
                ["Request-Id"]          = "|guid1.1",
                ["Correlation-Context"] = "k=v"
            });

            var config = this.CreateDefaultConfig(context);
            var module = this.RequestTrackingTelemetryModuleFactory(config);

            module.OnBeginRequest(context);

            // simulate losing call context by cleaning up activity
            ActivityHelpers.CleanOperationContext();

            var telemetryClient = new TelemetryClient(config);

            var trace = new TraceTelemetry();

            telemetryClient.TrackTrace(trace);
            var requestTelemetry = context.GetRequestTelemetry();

            Assert.Equal(requestTelemetry.Context.Operation.Id, trace.Context.Operation.Id);
            Assert.Equal(requestTelemetry.Id, trace.Context.Operation.ParentId);
            Assert.Equal("v", trace.Context.Properties["k"]);
        }
        public void RequestIdBecomesParentAndRootIfCompatibleWhenThereAreNoW3CHeaders()
        {
            this.aspNetDiagnosticsSource.FakeContext =
                HttpModuleHelper.GetFakeHttpContext(new Dictionary <string, string>
            {
                ["Request-Id"] = "|4bf92f3577b34da6a3ce929d0e0e4736."
            });
            this.module = this.CreateModule(enableW3cSupport: true);

            var activity = new Activity(FakeAspNetDiagnosticSource.IncomingRequestEventName);

            activity.Extract(HttpContext.Current.Request.Headers);

            Assert.IsTrue(this.aspNetDiagnosticsSource.IsEnabled(FakeAspNetDiagnosticSource.IncomingRequestEventName, activity));
            this.aspNetDiagnosticsSource.StartActivityWithoutChecks(activity);
            this.aspNetDiagnosticsSource.StopActivity();

            Assert.AreEqual("4bf92f3577b34da6a3ce929d0e0e4736", activity.GetTraceId());
            Assert.AreEqual(16, activity.GetSpanId().Length);
            Assert.IsNull(activity.GetParentSpanId());

            Assert.AreEqual(1, this.sendItems.Count);

            var requestTelemetry = this.sendItems[0] as RequestTelemetry;

            Assert.IsNotNull(requestTelemetry);
            Assert.AreEqual(activity.GetTraceId(), requestTelemetry.Context.Operation.Id);
            Assert.AreEqual("|4bf92f3577b34da6a3ce929d0e0e4736.", requestTelemetry.Context.Operation.ParentId);
            Assert.AreEqual($"|{activity.GetTraceId()}.{activity.GetSpanId()}.", requestTelemetry.Id);

            Assert.IsFalse(requestTelemetry.Properties.ContainsKey(W3CConstants.LegacyRootIdProperty));

            Assert.IsTrue(requestTelemetry.Properties.ContainsKey(W3CConstants.LegacyRequestIdProperty));
            Assert.IsTrue(requestTelemetry.Properties[W3CConstants.LegacyRequestIdProperty].StartsWith("|4bf92f3577b34da6a3ce929d0e0e4736."));
        }
Example #10
0
        public void OnBeginTelemetryCreatedWithinRequestScopeIsRequestChild()
        {
            var context = HttpModuleHelper.GetFakeHttpContext(new Dictionary <string, string>
            {
                ["Request-Id"]          = "|guid1.1",
                ["Correlation-Context"] = "k=v"
            });

            var config = this.CreateDefaultConfig(context);
            var module = this.RequestTrackingTelemetryModuleFactory(config);

            module.OnBeginRequest(context);

            var requestTelemetry   = context.GetRequestTelemetry();
            var telemetryClient    = new TelemetryClient(config);
            var exceptionTelemetry = new ExceptionTelemetry();

            telemetryClient.Initialize(exceptionTelemetry);

            module.OnEndRequest(context);

            Assert.Equal("guid1", exceptionTelemetry.Context.Operation.Id);
            Assert.Equal(requestTelemetry.Id, exceptionTelemetry.Context.Operation.ParentId);
            Assert.Equal("v", exceptionTelemetry.Context.Properties["k"]);
        }
Example #11
0
        public void OnPreHandlerTelemetryCreatedWithinRequestScopeIsRequestChild()
        {
            var context = HttpModuleHelper.GetFakeHttpContext(new Dictionary <string, string>
            {
                ["Request-Id"]          = "|guid1.1",
                ["Correlation-Context"] = "k=v"
            });

            var config = this.CreateDefaultConfig(context);
            var module = this.RequestTrackingTelemetryModuleFactory(config);

            module.OnBeginRequest(context);

            // simulate losing call context by cleaning up activity
            ActivityHelpers.CleanOperationContext();

            // CallContext was lost after OnBegin, so OnPreRequestHandlerExecute will set it
            module.OnPreRequestHandlerExecute(context);

            // if OnPreRequestHandlerExecute set a CallContext, child telemetry will be properly filled
            var telemetryClient = new TelemetryClient(config);

            var trace = new TraceTelemetry();

            telemetryClient.TrackTrace(trace);
            var requestTelemetry = context.GetRequestTelemetry();

            Assert.Equal(requestTelemetry.Context.Operation.Id, trace.Context.Operation.Id);
            Assert.Equal(requestTelemetry.Id, trace.Context.Operation.ParentId);
            Assert.Equal("v", trace.Context.Properties["k"]);
        }
Example #12
0
        public void OnEndDoesNotAddSourceFieldIfDisableTrackingPropertiesIsSet()
        {
            // ARRANGE
            Dictionary <string, string> headers = new Dictionary <string, string>();

            headers.Add(RequestResponseHeaders.RequestContextHeader, this.GetCorrelationIdHeaderValue(TestApplicationId2));

            var context = HttpModuleHelper.GetFakeHttpContext(headers);

            // My instrumentation key and hence app id is random / newly generated. The appId header is different - hence a different component.
            var config = TelemetryConfiguration.CreateDefault();

            config.InstrumentationKey    = TestInstrumentationKey1;
            config.ApplicationIdProvider = new MockApplicationIdProvider(TestInstrumentationKey1, TestApplicationId1);
            config.ExperimentalFeatures.Add("DeferRequestTrackingProperties");

            var module = this.RequestTrackingTelemetryModuleFactory(null /*use default*/);

            module.Initialize(config);

            // ACT
            module.OnBeginRequest(context);
            module.OnEndRequest(context);

            // VALIDATE
            Assert.True(string.IsNullOrEmpty(context.GetRequestTelemetry().Source), "RequestTrackingTelemetryModule should not set source if DisableTrackingProperties=true");
        }
        public void OnBeginSetsOperationContextWithoutHeaders()
        {
            var context = HttpModuleHelper.GetFakeHttpContext();
            var module  = this.RequestTrackingTelemetryModuleFactory(this.CreateDefaultConfig(context));

            module.OnBeginRequest(context);
            var requestTelemetry = context.GetRequestTelemetry();

            module.OnEndRequest(context);

            var operationId = requestTelemetry.Context.Operation.Id;

            Assert.NotNull(operationId);
            Assert.Null(requestTelemetry.Context.Operation.ParentId);
            Assert.True(requestTelemetry.Id.StartsWith('|' + operationId + '.', StringComparison.Ordinal));
            Assert.NotEqual(operationId, requestTelemetry.Id);

            // This code should go away when Activity is fixed: https://github.com/dotnet/corefx/issues/18418
            // check that Ids are not generated by Activity
            // so they look like OperationTelemetry.Id:
            // length is like default RequestTelemetry.Id length
            Assert.Equal(new RequestTelemetry().Id.Length, operationId.Length);

            // operationId is ulong base64 encoded
            byte[] data = Convert.FromBase64String(operationId);
            Assert.Equal(8, data.Length);
            BitConverter.ToUInt64(data, 0);

            // does not look like root Id generated by Activity
            Assert.Equal(1, operationId.Split('-').Length);

            //// end of workaround test
        }
        public void CorrelationContextIsReadWithoutTraceparentAndRequestId()
        {
            this.aspNetDiagnosticsSource.FakeContext =
                HttpModuleHelper.GetFakeHttpContext(new Dictionary <string, string>
            {
                ["Correlation-Context"] = "k=v",
            });
            this.module = this.CreateModule();

            var activity = new Activity(FakeAspNetDiagnosticSource.IncomingRequestEventName);

            Assert.IsTrue(this.aspNetDiagnosticsSource.IsEnabled(FakeAspNetDiagnosticSource.IncomingRequestEventName, activity));
            this.aspNetDiagnosticsSource.StartActivityWithoutChecks(activity);
            var currentActivity = Activity.Current;

            Assert.AreEqual(1, activity.Baggage.Count());
            Assert.AreEqual("k", activity.Baggage.Single().Key);
            Assert.AreEqual("v", activity.Baggage.Single().Value);

            this.aspNetDiagnosticsSource.StopActivity();

            Assert.AreEqual(1, this.sendItems.Count);

            var requestTelemetry = this.sendItems[0] as RequestTelemetry;

            Assert.IsNotNull(requestTelemetry);
            Assert.AreEqual(currentActivity.TraceId.ToHexString(), requestTelemetry.Context.Operation.Id);
            Assert.IsNull(requestTelemetry.Context.Operation.ParentId);
            Assert.AreEqual($"|{currentActivity.TraceId.ToHexString()}.{currentActivity.SpanId.ToHexString()}.", requestTelemetry.Id);

            Assert.AreEqual(1, requestTelemetry.Properties.Count);
            Assert.IsTrue(requestTelemetry.Properties.TryGetValue("k", out var v));
            Assert.AreEqual("v", v);
        }
        public void OnEndAddsSourceFieldForRequestWithCorrelationIdAndRoleName()
        {
            // ARRANGE
            string appId    = "b3eb14d6-bb32-4542-9b93-473cd94aaedf";
            string roleName = "SomeRoleName";

            Dictionary <string, string> headers = new Dictionary <string, string>();

            // Add Request context With both appId and roleName.
            headers.Add(RequestResponseHeaders.RequestContextHeader, string.Format(CultureInfo.InvariantCulture, "{0}, {1}={2}", this.GetCorrelationIdHeaderValue(appId), RequestResponseHeaders.RequestContextSourceRoleNameKey, roleName));

            var context = HttpModuleHelper.GetFakeHttpContext(headers);

            var module = this.RequestTrackingTelemetryModuleFactory();
            var config = TelemetryConfiguration.CreateDefault();

            // My instrumentation key and hence app id is random / newly generated. The appId header is different - hence a different component.
            config.InstrumentationKey = Guid.NewGuid().ToString();

            // ACT
            module.Initialize(config);
            module.OnBeginRequest(context);
            module.OnEndRequest(context);

            // VALIDATE
            Assert.Equal(string.Format(CultureInfo.InvariantCulture, "{0} | {1}", this.GetCorrelationIdValue(appId), "roleName:SomeRoleName"), context.GetRequestTelemetry().Source);
        }
Example #16
0
        public void RequestTelemetryIsNotSetWithLegacyHeaders()
        {
            this.aspNetDiagnosticsSource.FakeContext =
                HttpModuleHelper.GetFakeHttpContext(new Dictionary <string, string>
            {
                ["x-ms-request-id"]      = "guid1",
                ["x-ms-request-root-id"] = "guid2"
            });

            this.module = this.CreateModule();

            var activity = new Activity(FakeAspNetDiagnosticSource.IncomingRequestEventName);

            this.aspNetDiagnosticsSource.StartActivityWithoutChecks(activity);
            this.aspNetDiagnosticsSource.StopActivity();

            Assert.AreEqual(1, this.sendItems.Count);

            var requestTelemetry = this.sendItems[0] as RequestTelemetry;

            Assert.IsNotNull(requestTelemetry);
            Assert.AreEqual(activity.RootId, requestTelemetry.Context.Operation.Id);
            Assert.IsNull(requestTelemetry.Context.Operation.ParentId);
            Assert.AreEqual(activity.Id, requestTelemetry.Id);
        }
Example #17
0
        public void OnEndAddsSourceFieldForRequestWithCorrelationId()
        {
            // ARRANGE
            Dictionary <string, string> headers = new Dictionary <string, string>();

            headers.Add(RequestResponseHeaders.RequestContextHeader, this.GetCorrelationIdHeaderValue(TestApplicationId2));

            var context = HttpModuleHelper.GetFakeHttpContext(headers);

            // My instrumentation key and hence app id is random / newly generated. The appId header is different - hence a different component.
            var config = TelemetryConfiguration.CreateDefault();

            config.InstrumentationKey    = TestInstrumentationKey1;
            config.ApplicationIdProvider = new MockApplicationIdProvider(TestInstrumentationKey1, TestApplicationId1);

            var module = this.RequestTrackingTelemetryModuleFactory(null /*use default*/);

            // ACT
            module.Initialize(config);
            module.OnBeginRequest(context);
            module.OnEndRequest(context);

            // VALIDATE
            Assert.Equal(TestApplicationId2, context.GetRequestTelemetry().Source);
        }
Example #18
0
        public void RequestTelemetryIsSetWithCustomHeaders()
        {
            this.module = this.CreateModule("rootHeaderName", "parentHeaderName");
            this.aspNetDiagnosticsSource.FakeContext =
                HttpModuleHelper.GetFakeHttpContext(new Dictionary <string, string>
            {
                ["parentHeaderName"] = "ParentId",
                ["rootHeaderName"]   = "RootId"
            });

            var activity = new Activity(FakeAspNetDiagnosticSource.IncomingRequestEventName);

            Assert.IsTrue(this.aspNetDiagnosticsSource.IsEnabled(FakeAspNetDiagnosticSource.IncomingRequestEventName, activity));
            Assert.AreEqual("RootId", activity.ParentId);

            this.aspNetDiagnosticsSource.StartActivityWithoutChecks(activity);
            this.aspNetDiagnosticsSource.StopActivity();

            Assert.AreEqual(1, this.sendItems.Count);

            var requestTelemetry = this.sendItems[0] as RequestTelemetry;

            Assert.IsNotNull(requestTelemetry);
            Assert.AreEqual("RootId", requestTelemetry.Context.Operation.Id);
            Assert.AreEqual("ParentId", requestTelemetry.Context.Operation.ParentId);
            Assert.AreEqual(activity.Id, requestTelemetry.Id);
        }
Example #19
0
        public void TrackRequestWithoutTraceparentOrRequestIdAndCorrelationContextW3COff()
        {
            var headers = new Dictionary <string, string> {
                ["Correlation-Context"] = "k=v"
            };

            var context = HttpModuleHelper.GetFakeHttpContext(headers);
            var module  = this.RequestTrackingTelemetryModuleFactory(this.CreateDefaultConfig(context));

            Activity.DefaultIdFormat      = ActivityIdFormat.Hierarchical;
            Activity.ForceDefaultIdFormat = true;

            module.OnBeginRequest(context);
            var activityInitializedByW3CHeader = Activity.Current;

            Assert.Equal("v", activityInitializedByW3CHeader.Baggage.Single(t => t.Key == "k").Value);

            var requestTelemetry = context.GetRequestTelemetry();

            module.OnEndRequest(context);

            Assert.Equal(activityInitializedByW3CHeader.Id, requestTelemetry.Id);
            Assert.Equal(activityInitializedByW3CHeader.RootId, requestTelemetry.Context.Operation.Id);
            Assert.Null(requestTelemetry.Context.Operation.ParentId);
        }
Example #20
0
        public void StandardHeadersWinOverLegacyHeaders()
        {
            this.aspNetDiagnosticsSource.FakeContext =
                HttpModuleHelper.GetFakeHttpContext(new Dictionary <string, string>
            {
                ["x-ms-request-id"]       = "legacy-id",
                ["x-ms-request-rooit-id"] = "legacy-root-id"
            });

            this.module = this.CreateModule();

            var activity = new Activity(FakeAspNetDiagnosticSource.IncomingRequestEventName);

            activity.SetParentId("|standard-id.");
            Assert.IsTrue(this.aspNetDiagnosticsSource.IsEnabled(FakeAspNetDiagnosticSource.IncomingRequestEventName, activity));
            Assert.AreEqual("|standard-id.", activity.ParentId);

            this.aspNetDiagnosticsSource.StartActivityWithoutChecks(activity);
            this.aspNetDiagnosticsSource.StopActivity();

            Assert.AreEqual(1, this.sendItems.Count);

            var requestTelemetry = this.sendItems[0] as RequestTelemetry;

            Assert.IsNotNull(requestTelemetry);
            Assert.AreEqual("standard-id", requestTelemetry.Context.Operation.Id);
            Assert.AreEqual("|standard-id.", requestTelemetry.Context.Operation.ParentId);
            Assert.AreEqual(activity.Id, requestTelemetry.Id);
        }
Example #21
0
        public void OnBeginSetsOperationContextWithDisabledLegacyHeaders()
        {
            var context = HttpModuleHelper.GetFakeHttpContext(new Dictionary <string, string>
            {
                ["x-ms-request-id"]      = "guid1",
                ["x-ms-request-root-id"] = "guid2"
            });

            var module = this.RequestTrackingTelemetryModuleFactory(this.CreateDefaultConfig(context,
                                                                                             "x-ms-request-root-id",
                                                                                             "x-ms-request-id"));

            module.OnBeginRequest(context);
            var activity = Activity.Current;

            var requestTelemetry = context.GetRequestTelemetry();

            module.OnEndRequest(context);

            Assert.Equal(activity.TraceId.ToHexString(), requestTelemetry.Context.Operation.Id);
            Assert.Equal(activity.SpanId.ToHexString(), requestTelemetry.Id);
            Assert.Equal("guid1", requestTelemetry.Context.Operation.ParentId);
            Assert.True(requestTelemetry.Properties.TryGetValue("ai_legacyRootId", out var legacyRootId));
            Assert.Equal("guid2", legacyRootId);
        }
Example #22
0
        public void TestActivityIdGenerationWithEmptyHeaders()
        {
            this.module = this.CreateModule();

            var activities = new Activity[5];

            for (int i = 0; i < activities.Length; i++)
            {
                this.aspNetDiagnosticsSource.StartActivity();
                activities[i] = Activity.Current;
                this.aspNetDiagnosticsSource.StopActivity();

                // clean up
                HttpContext.Current = HttpModuleHelper.GetFakeHttpContext();
            }

            Assert.AreEqual(activities.Length, this.sendItems.Count);

            var ids = this.sendItems.Select(i => ((RequestTelemetry)i).Context.Operation.Id);

            // This code should go away when Activity is fixed: https://github.com/dotnet/corefx/issues/18418
            // check that Ids are not generated by Activity
            // so they look like OperationTelemetry.Id
            foreach (var operationId in ids)
            {
                // W3C compatible-Id ( should go away when W3C is implemented in .NET https://github.com/dotnet/corefx/issues/30331 TODO)
                Assert.AreEqual(32, operationId.Length);
                Assert.IsTrue(Regex.Match(operationId, @"[a-z][0-9]").Success);
                // end of workaround test
            }

            //// end of workaround test
        }
Example #23
0
        public async Task OnPreHandlerTelemetryCreatedWithinRequestScopeIsRequestChild()
        {
            var context         = HttpModuleHelper.GetFakeHttpContext();
            var config          = this.CreateDefaultConfig(context);
            var module          = this.RequestTrackingTelemetryModuleFactory(config);
            var telemetryClient = new TelemetryClient(config);

            module.OnBeginRequest(context);

            var activity = Activity.Current;

            // simulate losing call context by cleaning up activity
            Activity.Current = null;

            var trace = new TraceTelemetry();

            // run track trace in the async task, so that HttpContext.Current is not available and we could be sure
            // telemetry is not initialized from it.
            await Task.Run(() =>
            {
                // CallContext was lost after OnBegin, so Asp.NET Http Module will restore it in OnPreRequestHandlerExecute
                Activity.Current = activity;

                // if OnPreRequestHandlerExecute set a CallContext, child telemetry will be properly filled
                telemetryClient.TrackTrace(trace);
            });

            var requestTelemetry = context.GetRequestTelemetry();

            Assert.Equal(requestTelemetry.Context.Operation.Id, trace.Context.Operation.Id);
            Assert.Equal(trace.Context.Operation.ParentId, requestTelemetry.Id);
        }
Example #24
0
        public void W3CHeadersWinOverRequestIdWhenEnabled()
        {
            this.aspNetDiagnosticsSource.FakeContext =
                HttpModuleHelper.GetFakeHttpContext(new Dictionary <string, string>
            {
                ["traceparent"] = "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01",
            });

            this.module = this.CreateModule(enableW3cSupport: true);

            var activity = new Activity(FakeAspNetDiagnosticSource.IncomingRequestEventName);

            activity.SetParentId("|requestId.");
            Assert.IsTrue(this.aspNetDiagnosticsSource.IsEnabled(FakeAspNetDiagnosticSource.IncomingRequestEventName, activity));
            this.aspNetDiagnosticsSource.StartActivityWithoutChecks(activity);
            this.aspNetDiagnosticsSource.StopActivity();

            Assert.AreEqual("4bf92f3577b34da6a3ce929d0e0e4736", activity.GetTraceId());
            Assert.AreEqual("00f067aa0ba902b7", activity.GetParentSpanId());

            Assert.AreEqual(1, this.sendItems.Count);

            var requestTelemetry = this.sendItems[0] as RequestTelemetry;

            Assert.IsNotNull(requestTelemetry);
            Assert.AreEqual("4bf92f3577b34da6a3ce929d0e0e4736", requestTelemetry.Context.Operation.Id);
            Assert.AreEqual("|4bf92f3577b34da6a3ce929d0e0e4736.00f067aa0ba902b7.", requestTelemetry.Context.Operation.ParentId);
            Assert.AreEqual($"|4bf92f3577b34da6a3ce929d0e0e4736.{activity.GetSpanId()}.", requestTelemetry.Id);

            Assert.IsTrue(requestTelemetry.Properties.ContainsKey(W3CConstants.LegacyRootIdProperty));
            Assert.AreEqual("requestId", requestTelemetry.Properties[W3CConstants.LegacyRootIdProperty]);

            Assert.IsTrue(requestTelemetry.Properties.ContainsKey(W3CConstants.LegacyRequestIdProperty));
            Assert.IsTrue(requestTelemetry.Properties[W3CConstants.LegacyRequestIdProperty].StartsWith("|requestId."));
        }
Example #25
0
        public void TelemetryTrackedBeforeOnBeginW3CEnabled()
        {
            var context = HttpModuleHelper.GetFakeHttpContext(new Dictionary <string, string>
            {
                ["traceparent"] = "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01"
            });
            var config = this.CreateDefaultConfig(context);
            var module = this.RequestTrackingTelemetryModuleFactory(config);
            var client = new TelemetryClient(config);

            // will not be correlated to request
            client.TrackTrace("test1");

            module.OnBeginRequest(context);

            // will be correlated to request
            client.TrackTrace("test2");

            // initialize telemetry
            module.OnEndRequest(context);

            var trace1 = (TraceTelemetry)this.sentTelemetry.Single(t => t is TraceTelemetry tt && tt.Message == "test1");
            var trace2 = (TraceTelemetry)this.sentTelemetry.Single(t => t is TraceTelemetry tt && tt.Message == "test2");

            var request = (RequestTelemetry)this.sentTelemetry.Single(t => t is RequestTelemetry);

            Assert.Equal("4bf92f3577b34da6a3ce929d0e0e4736", request.Context.Operation.Id);
            Assert.Equal("00f067aa0ba902b7", request.Context.Operation.ParentId);

            Assert.Equal(trace1.Context.Operation.Id, request.Context.Operation.Id);
            Assert.Equal(trace2.Context.Operation.Id, request.Context.Operation.Id);

            Assert.Equal(trace1.Context.Operation.ParentId, request.Id);
            Assert.Equal(trace2.Context.Operation.ParentId, request.Id);
        }
        public void OnEndAddsSourceFieldForRequestWithCorrelationId()
        {
            // ARRANGE
            string appId = "b3eb14d6-bb32-4542-9b93-473cd94aaedf";

            Dictionary <string, string> headers = new Dictionary <string, string>();

            headers.Add(RequestResponseHeaders.RequestContextHeader, this.GetCorrelationIdHeaderValue(appId));

            var context = HttpModuleHelper.GetFakeHttpContext(headers);

            var module = this.RequestTrackingTelemetryModuleFactory();
            var config = TelemetryConfiguration.CreateDefault();

            // My instrumentation key and hence app id is random / newly generated. The appId header is different - hence a different component.
            config.InstrumentationKey = Guid.NewGuid().ToString();

            // ACT
            module.Initialize(config);
            module.OnBeginRequest(context);
            module.OnEndRequest(context);

            // VALIDATE
            Assert.Equal(this.GetCorrelationIdValue(appId), context.GetRequestTelemetry().Source);
        }
Example #27
0
        public void OnBeginSetsOperationContextWithStandardHeadersWithNonHierarchialId()
        {
            var context = HttpModuleHelper.GetFakeHttpContext(new Dictionary <string, string>
            {
                ["Request-Id"]          = "guid1",
                ["Correlation-Context"] = "k=v"
            });
            var module = this.RequestTrackingTelemetryModuleFactory(this.CreateDefaultConfig(context));

            module.OnBeginRequest(context);
            var activity         = Activity.Current;
            var requestTelemetry = context.GetRequestTelemetry();

            module.OnEndRequest(context);

            Assert.Equal(activity.TraceId.ToHexString(), requestTelemetry.Context.Operation.Id);
            Assert.Equal(activity.SpanId.ToHexString(), requestTelemetry.Id);
            Assert.Equal("guid1", requestTelemetry.Context.Operation.ParentId);
            Assert.True(requestTelemetry.Properties.TryGetValue("ai_legacyRootId", out var legacyRootId));
            Assert.Equal("guid1", legacyRootId);

            // will initialize telemetry
            module.OnEndRequest(context);
            Assert.Equal("v", requestTelemetry.Properties["k"]);
        }
        public void OnEndAddsSourceFieldForRequestWithRoleName()
        {
            // ARRANGE
            string roleName = "SomeRoleName";

            Dictionary <string, string> headers = new Dictionary <string, string>();

            headers.Add(RequestResponseHeaders.RequestContextHeader, string.Format(CultureInfo.InvariantCulture, "{0}={1}", RequestResponseHeaders.RequestContextSourceRoleNameKey, roleName));

            var context = HttpModuleHelper.GetFakeHttpContext(headers);

            var module = this.RequestTrackingTelemetryModuleFactory();
            var config = TelemetryConfiguration.CreateDefault();

            // My instrumentation key and hence app id is random / newly generated. The appId header is different - hence a different component.
            config.InstrumentationKey = Guid.NewGuid().ToString();

            // ACT
            module.Initialize(config);
            module.OnBeginRequest(context);
            module.OnEndRequest(context);

            // VALIDATE
            Assert.Equal("roleName:" + roleName, context.GetRequestTelemetry().Source);
        }
Example #29
0
        public void InitializeFromStandardHeadersAlwaysWinsCustomHeadersW3COff()
        {
            Activity.DefaultIdFormat      = ActivityIdFormat.Hierarchical;
            Activity.ForceDefaultIdFormat = true;

            var context = HttpModuleHelper.GetFakeHttpContext(new Dictionary <string, string>
            {
                ["Request-Id"]           = "|standard-id.",
                ["x-ms-request-id"]      = "legacy-id",
                ["x-ms-request-root-id"] = "legacy-root-id"
            });

            var module = this.RequestTrackingTelemetryModuleFactory(this.CreateDefaultConfig(context));

            Activity.DefaultIdFormat      = ActivityIdFormat.Hierarchical;
            Activity.ForceDefaultIdFormat = true;

            module.OnBeginRequest(context);

            var requestTelemetry = context.GetRequestTelemetry();

            // initialize telemetry
            module.OnEndRequest(context);
            Assert.Equal("|standard-id.", requestTelemetry.Context.Operation.ParentId);
            Assert.Equal("standard-id", requestTelemetry.Context.Operation.Id);
            Assert.Equal("standard-id", this.GetActivityRootId(requestTelemetry.Id));
            Assert.NotEqual(requestTelemetry.Context.Operation.Id, requestTelemetry.Id);
        }
        public void W3CHeadersWinOverRequestId()
        {
            this.aspNetDiagnosticsSource.FakeContext =
                HttpModuleHelper.GetFakeHttpContext(new Dictionary <string, string>
            {
                ["traceparent"] = "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01",
                ["Request-Id"]  = "|requestId."
            });

            this.module = this.CreateModule();

            var activity = new Activity(FakeAspNetDiagnosticSource.IncomingRequestEventName);

            Assert.IsTrue(this.aspNetDiagnosticsSource.IsEnabled(FakeAspNetDiagnosticSource.IncomingRequestEventName, activity));
            this.aspNetDiagnosticsSource.StartActivityWithoutChecks(activity);
            Assert.AreEqual(activity, Activity.Current);
            this.aspNetDiagnosticsSource.StopActivity();

            Assert.AreEqual("4bf92f3577b34da6a3ce929d0e0e4736", activity.TraceId.ToHexString());
            Assert.AreEqual("00f067aa0ba902b7", activity.ParentSpanId.ToHexString());

            Assert.AreEqual(1, this.sendItems.Count);

            var requestTelemetry = this.sendItems[0] as RequestTelemetry;

            Assert.IsNotNull(requestTelemetry);
            Assert.AreEqual("4bf92f3577b34da6a3ce929d0e0e4736", requestTelemetry.Context.Operation.Id);
            Assert.AreEqual("|4bf92f3577b34da6a3ce929d0e0e4736.00f067aa0ba902b7.", requestTelemetry.Context.Operation.ParentId);
            Assert.AreEqual($"|4bf92f3577b34da6a3ce929d0e0e4736.{activity.SpanId.ToHexString()}.", requestTelemetry.Id);

            Assert.IsFalse(requestTelemetry.Properties.ContainsKey("ai_legacyRootId"));
            Assert.AreEqual(0, requestTelemetry.Properties.Count);
        }