Skip to content
This repository has been archived by the owner on Jun 10, 2020. It is now read-only.

Commit

Permalink
Read Correlation context always, update to beta2 of base (#973)
Browse files Browse the repository at this point in the history
* update base to beta and related changes
* read correlation context always
  • Loading branch information
cijothomas authored Sep 10, 2019
1 parent 59efae2 commit 64639fa
Show file tree
Hide file tree
Showing 11 changed files with 250 additions and 89 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
- [Make W3C Correlation default and leverage native W3C support from Activity for Asp.Net Core 3.0.](https://github.com/microsoft/ApplicationInsights-aspnetcore/pull/958)
- [Fix: Azure Functions performance degradation when W3C enabled.](https://github.com/microsoft/ApplicationInsights-aspnetcore/issues/900)
- [Fix: AppId is never set is Response Headers.](https://github.com/microsoft/ApplicationInsights-aspnetcore/issues/956)
- [Support correlation-context in absence of request-id or traceparent.](https://github.com/microsoft/ApplicationInsights-aspnetcore/issues/901)
- [Non Product - Asp.Net Core 3.0 Functional Tests Added. This leverages the built-in integration test capability of ASP.NET Core via Microsoft.AspNetCore.MVC.Testing](https://github.com/microsoft/ApplicationInsights-aspnetcore/issues/539)
- [Fix: System.NullReferenceException in WebSessionTelemetryInitializer.](https://github.com/microsoft/ApplicationInsights-aspnetcore/issues/903)
- Updated Base SDK version dependency to 2.11.0-beta2

## Version 2.8.0-beta2
- [Fix MVCBeforeAction property fetcher to work with .NET Core 3.0 changes.](https://github.com/microsoft/ApplicationInsights-aspnetcore/issues/936)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,12 +235,7 @@ public void OnHttpRequestInStart(HttpContext httpContext)
AspNetCoreEventSource.Instance.HostingListenerInformational(this.aspNetCoreMajorVersion, "Ignoring original Activity from Hosting to create new one using traceparent header retrieved by sdk.");

// read and populate tracestate
ReadTraceState(httpContext.Request.Headers, newActivity);

// If only W3C headers are present then 2.XX Hosting will not read correlation-context. (it is read only if request-id is present)
// SDK needs to do that.
// This is in line with what Hosting 3.xx will do which will read corr context if either traceparent or request-id is present
ReadCorrelationContext(httpContext.Request.Headers, newActivity);
ReadTraceState(httpContext.Request.Headers, newActivity);
}
else if (this.aspNetCoreMajorVersion == AspNetCoreMajorVersion.Three && headers.ContainsKey(W3CConstants.TraceParentHeader))
{
Expand Down Expand Up @@ -275,14 +270,17 @@ public void OnHttpRequestInStart(HttpContext httpContext)
AspNetCoreEventSource.Instance.HostingListenerInformational(this.aspNetCoreMajorVersion, "Incoming Request-ID is not W3C Compatible, and hence will be ignored for ID generation, but stored in custom property legacy_rootID.");
}
}
}
}

if (newActivity != null)
{
newActivity.Start();
currentActivity = newActivity;
}

// Read Correlation-Context is all scenarios irrespective of presence of either request-id or traceparent headers.
ReadCorrelationContext(httpContext.Request.Headers, currentActivity);

var requestTelemetry = this.InitializeRequestTelemetry(httpContext, currentActivity, Stopwatch.GetTimestamp(), legacyRootId);

requestTelemetry.Context.Operation.ParentId =
Expand Down Expand Up @@ -332,8 +330,7 @@ public void OnBeginRequest(HttpContext httpContext, long timestamp)
activity.SetParentId(parentTraceParent);
originalParentId = parentTraceParent;

ReadTraceState(requestHeaders, activity);
ReadCorrelationContext(requestHeaders, activity);
ReadTraceState(requestHeaders, activity);
}

// Request-Id
Expand All @@ -356,9 +353,7 @@ public void OnBeginRequest(HttpContext httpContext, long timestamp)
else
{
activity.SetParentId(originalParentId);
}

ReadCorrelationContext(requestHeaders, activity);
}
}

// no headers
Expand All @@ -369,6 +364,7 @@ public void OnBeginRequest(HttpContext httpContext, long timestamp)

activity.Start();

ReadCorrelationContext(requestHeaders, activity);
var requestTelemetry = this.InitializeRequestTelemetry(httpContext, activity, timestamp, legacyRootId);

requestTelemetry.Context.Operation.ParentId =
Expand Down Expand Up @@ -617,21 +613,31 @@ private static string FormatTelemetryId(string traceId, string spanId)

private static void ReadCorrelationContext(IHeaderDictionary requestHeaders, Activity activity)
{
string[] baggage = requestHeaders.GetCommaSeparatedValues(RequestResponseHeaders.CorrelationContextHeader);
if (baggage != StringValues.Empty && !activity.Baggage.Any())
try
{
foreach (var item in baggage)
if (!activity.Baggage.Any())
{
var parts = item.Split('=');
if (parts.Length == 2)
string[] baggage = requestHeaders.GetCommaSeparatedValues(RequestResponseHeaders.CorrelationContextHeader);
if (baggage != StringValues.Empty)
{
var itemName = StringUtilities.EnforceMaxLength(parts[0], InjectionGuardConstants.ContextHeaderKeyMaxLength);
var itemValue = StringUtilities.EnforceMaxLength(parts[1], InjectionGuardConstants.ContextHeaderValueMaxLength);
activity.AddBaggage(itemName, itemValue);
foreach (var item in baggage)
{
var parts = item.Split('=');
if (parts.Length == 2)
{
var itemName = StringUtilities.EnforceMaxLength(parts[0], InjectionGuardConstants.ContextHeaderKeyMaxLength);
var itemValue = StringUtilities.EnforceMaxLength(parts[1], InjectionGuardConstants.ContextHeaderValueMaxLength);
activity.AddBaggage(itemName.Trim(), itemValue.Trim());
}
}

AspNetCoreEventSource.Instance.HostingListenerVerbose("Correlation-Context retrived from header and stored into activity baggage.");
}
}

AspNetCoreEventSource.Instance.HostingListenerVerboe("Correlation-Context retrived from header and stored into activity baggage.");
}
catch (Exception ex)
{
AspNetCoreEventSource.Instance.HostingListenerWarning("CorrelationContext read failed.", ex.ToInvariantString());
}
}

Expand All @@ -644,7 +650,7 @@ private static void ReadTraceState(IHeaderDictionary requestHeaders, Activity ac
// make in the request context can continue propogation
// of tracestate.
activity.TraceStateString = traceState;
AspNetCoreEventSource.Instance.HostingListenerVerboe("TraceState retrived from header and stored into activity.TraceState");
AspNetCoreEventSource.Instance.HostingListenerVerbose("TraceState retrived from header and stored into activity.TraceState");
}
}

Expand Down Expand Up @@ -739,15 +745,15 @@ private RequestTelemetry InitializeRequestTelemetry(HttpContext httpContext, Act
&& this.configuration != null
&& !string.IsNullOrEmpty(requestTelemetry.Context.Operation.Id)
&& SamplingScoreGenerator.GetSamplingScore(requestTelemetry.Context.Operation.Id) >= this.configuration.GetLastObservedSamplingPercentage(requestTelemetry.ItemTypeFlag))
{
requestTelemetry.IsSampledOutAtHead = true;
{
requestTelemetry.ProactiveSamplingDecision = SamplingDecision.SampledOut;
AspNetCoreEventSource.Instance.TelemetryItemWasSampledOutAtHead(requestTelemetry.Context.Operation.Id);
}

//// When the item is proactively sampled out, we can avoid heavy operations that do not have known dependency later in the pipeline.
//// We mostly exclude operations that were deemed heavy as per the corresponding profiler trace of this code path.

if (!requestTelemetry.IsSampledOutAtHead)
if (requestTelemetry.ProactiveSamplingDecision != SamplingDecision.SampledOut)
{
foreach (var prop in activity.Baggage)
{
Expand Down Expand Up @@ -865,7 +871,7 @@ private void EndRequest(HttpContext httpContext, long timestamp)
telemetry.Name = httpContext.Request.Method + " " + httpContext.Request.Path.Value;
}

if (!telemetry.IsSampledOutAtHead)
if (telemetry.ProactiveSamplingDecision != SamplingDecision.SampledOut)
{
telemetry.Url = httpContext.Request.GetUri();
telemetry.Context.GetInternalContext().SdkVersion = this.sdkVersion;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ public void HostingListenerInformational(AspNetCoreMajorVersion hostingVersion,
20,
Message = "Message: '{0}'.",
Level = EventLevel.Verbose)]
public void HostingListenerVerboe(string message, string appDomainName = "Incorrect")
public void HostingListenerVerbose(string message, string appDomainName = "Incorrect")
{
this.WriteEvent(20, message, this.ApplicationName);
}
Expand All @@ -244,6 +244,18 @@ public void RequestTelemetryCreated(string correlationFormat, string requestId,
this.WriteEvent(21, correlationFormat, requestId, requestOperationId, this.ApplicationName);
}

/// <summary>
/// Logs a verbose event.
/// </summary>
[Event(
22,
Message = "Message: '{0}'. Exception: '{1}'",
Level = EventLevel.Warning)]
public void HostingListenerWarning(string message, string exception, string appDomainName = "Incorrect")
{
this.WriteEvent(22, message, exception, this.ApplicationName);
}

/// <summary>
/// Keywords for the AspNetEventSource.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace Microsoft.ApplicationInsights.AspNetCore.Extensions
using System;

namespace Microsoft.ApplicationInsights.AspNetCore.Extensions
{
/// <summary>
/// Request collection options define the custom behavior or non-default features of request collection.
Expand Down Expand Up @@ -38,6 +40,7 @@ public RequestCollectionOptions()
/// <summary>
/// Gets or sets a value indicating whether W3C distributed tracing standard is enabled.
/// </summary>
[Obsolete("This flag is obsolete and noop. Use System.Diagnostics.Activity.DefaultIdFormat (along with ForceDefaultIdFormat) flags instead.")]
public bool EnableW3CDistributedTracing { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,7 @@ public void Configure(TelemetryConfiguration configuration)
this.AddQuickPulse(configuration);
this.AddSampling(configuration);
this.DisableHeartBeatIfConfigured();

configuration.EnableW3CCorrelation = this.applicationInsightsServiceOptions.RequestCollectionOptions.EnableW3CDistributedTracing;

configuration.DefaultTelemetrySink.TelemetryProcessorChainBuilder.Build();
configuration.TelemetryProcessorChainBuilder.Build();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,11 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.ApplicationInsights" Version="2.11.0-beta1-build12825" />
<PackageReference Include="Microsoft.ApplicationInsights" Version="2.11.0-beta2" />
<PackageReference Include="Microsoft.ApplicationInsights.DependencyCollector" Version="2.11.0-beta1" />
<PackageReference Include="Microsoft.ApplicationInsights.PerfCounterCollector" Version="2.11.0-beta1" />
<PackageReference Include="Microsoft.ApplicationInsights.WindowsServer" Version="2.11.0-beta1" />
<PackageReference Include="Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel" Version="2.11.0-beta1-build12825" />
<PackageReference Include="Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel" Version="2.11.0-beta2" />
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="1.0.2" />
<PackageReference Include="System.Text.Encodings.Web" Version="4.3.1" />
<PackageReference Include="System.Diagnostics.DiagnosticSource" Version="4.6.0-preview7.19362.9" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,6 @@ public void Initialize(TelemetryConfiguration configuration)

this.subscriptions?.Add(DiagnosticListener.AllListeners.Subscribe(this));

// Questionable to modify the configuration here.
configuration.EnableW3CCorrelation = this.CollectionOptions.EnableW3CDistributedTracing;
this.isInitialized = true;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1070,27 +1070,6 @@ public static void W3CIsEnabledByDefault()
Assert.True(dependencyTracking.Single().EnableW3CHeadersInjection);
}

[Fact]
public static void W3CIsDisabledWhenConfiguredInOptions()
{
var services = CreateServicesAndAddApplicationinsightsTelemetry(null,
"http://localhost:1234/v2/track/",
o => o.RequestCollectionOptions.EnableW3CDistributedTracing = false);
IServiceProvider serviceProvider = services.BuildServiceProvider();
var telemetryConfiguration = serviceProvider.GetTelemetryConfiguration();

var modules = serviceProvider.GetServices<ITelemetryModule>().ToList();

var requestTracking = modules.OfType<RequestTrackingTelemetryModule>().ToList();
var dependencyTracking = modules.OfType<DependencyTrackingTelemetryModule>().ToList();
Assert.Single(requestTracking);
Assert.Single(dependencyTracking);

Assert.False(requestTracking.Single().CollectionOptions.EnableW3CDistributedTracing);
Assert.False(dependencyTracking.Single().EnableW3CHeadersInjection);
Assert.False(telemetryConfiguration.EnableW3CCorrelation);
}

private static int GetTelemetryProcessorsCountInConfiguration<T>(TelemetryConfiguration telemetryConfiguration)
{
return telemetryConfiguration.TelemetryProcessors.Where(processor => processor.GetType() == typeof(T)).Count();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
namespace Microsoft.ApplicationInsights.AspNetCore.Tests.Helpers
{
using System;
using System.Diagnostics;
using Microsoft.ApplicationInsights.Channel;
using Microsoft.ApplicationInsights.Extensibility;

Expand All @@ -11,11 +12,20 @@ public static class CommonMocks

public static TelemetryClient MockTelemetryClient(Action<ITelemetry> onSendCallback, bool isW3C = true)
{
if(isW3C)
{
Activity.DefaultIdFormat = ActivityIdFormat.W3C;
}
else
{
Activity.DefaultIdFormat = ActivityIdFormat.Hierarchical;
}
Activity.ForceDefaultIdFormat = true;

return new TelemetryClient(new TelemetryConfiguration()
{
InstrumentationKey = InstrumentationKey,
TelemetryChannel = new FakeTelemetryChannel { OnSend = onSendCallback },
EnableW3CCorrelation = isW3C
TelemetryChannel = new FakeTelemetryChannel { OnSend = onSendCallback },
});
}

Expand Down
Loading

0 comments on commit 64639fa

Please sign in to comment.