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

Commit

Permalink
Support W3C distributed tracing standard (#945)
Browse files Browse the repository at this point in the history
 Support W3C propagation in the process and http W3C headers injection
  • Loading branch information
Liudmila Molkova committed Aug 15, 2018
1 parent bfa0428 commit 84a30c0
Show file tree
Hide file tree
Showing 40 changed files with 2,574 additions and 225 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Changelog

## Version 2.8.0-beta1
- [Adds opt-in support for W3C distributed tracing standard](https://github.com/Microsoft/ApplicationInsights-dotnet-server/pull/945)
- Update Base SDK to version 2.8.0-beta1

## Version 2.7.2
Expand Down
3 changes: 3 additions & 0 deletions Src/Common/Common.projitems
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
<Compile Include="$(MSBuildThisFileDirectory)RequestResponseHeaders.cs" />
<Compile Include="$(MSBuildThisFileDirectory)SdkVersionUtils.cs" />
<Compile Include="$(MSBuildThisFileDirectory)StringUtilities.cs" />
<Compile Include="$(MSBuildThisFileDirectory)W3C\W3CActivityExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)W3C\W3CConstants.cs" />
<Compile Include="$(MSBuildThisFileDirectory)W3C\W3COperationCorrelationTelemetryInitializer.cs" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' != 'netstandard1.6' ">
<Compile Include="$(MSBuildThisFileDirectory)WebHeaderCollectionExtensions.cs" />
Expand Down
34 changes: 32 additions & 2 deletions Src/Common/InjectionGuardConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,46 @@
/// These max limits are intentionally exaggerated to allow for unexpected responses, while still guarding against unreasonably large responses.
/// Example: While a 32 character response may be expected, 50 characters may be permitted while a 10,000 character response would be unreasonable and malicious.
/// </summary>
public static class InjectionGuardConstants
#if DEPENDENCY_COLLECTOR
public
#else
internal
#endif
static class InjectionGuardConstants
{
/// <summary>
/// Max length of AppId allowed in response from Breeze.
/// </summary>
public const int AppIdMaxLengeth = 50;
public const int AppIdMaxLength = 50;

/// <summary>
/// Max length of incoming Request Header value allowed.
/// </summary>
public const int RequestHeaderMaxLength = 1024;

/// <summary>
/// Max length of context header key.
/// </summary>
public const int ContextHeaderKeyMaxLength = 50;

/// <summary>
/// Max length of context header value.
/// </summary>
public const int ContextHeaderValueMaxLength = 1024;

/// <summary>
/// Max length of traceparent header value.
/// </summary>
public const int TraceParentHeaderMaxLength = 55;

/// <summary>
/// Max length of tracestate header value string.
/// </summary>
public const int TraceStateHeaderMaxLength = 512;

/// <summary>
/// Max number of key value pairs in the tracestate header.
/// </summary>
public const int TraceStateMaxPairs = 32;
}
}
69 changes: 64 additions & 5 deletions Src/Common/StringUtilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,17 @@
using System;
using System.Diagnostics;
using System.Globalization;
using Microsoft.ApplicationInsights.W3C;

/// <summary>
/// Generic functions to perform common operations on a string.
/// </summary>
public static class StringUtilities
#if DEPENDENCY_COLLECTOR
public
#else
internal
#endif
static class StringUtilities
{
private static readonly uint[] Lookup32 = CreateLookup32();

Expand Down Expand Up @@ -35,11 +41,64 @@ public static string EnforceMaxLength(string input, int maxLength)
/// <returns>Random 16 bytes array encoded as hex string</returns>
public static string GenerateTraceId()
{
// See https://stackoverflow.com/questions/311165/how-do-you-convert-a-byte-array-to-a-hexadecimal-string-and-vice-versa/24343727#24343727
var bytes = Guid.NewGuid().ToByteArray();
return GenerateId(Guid.NewGuid().ToByteArray(), 0, 16);
}

/// <summary>
/// Generates random span Id as per W3C Distributed tracing specification.
/// https://github.com/w3c/distributed-tracing/blob/master/trace_context/HTTP_HEADER_FORMAT.md#span-id
/// </summary>
/// <returns>Random 8 bytes array encoded as hex string</returns>
public static string GenerateSpanId()
{
return GenerateId(Guid.NewGuid().ToByteArray(), 0, 8);
}

var result = new char[32];
for (int i = 0; i < 16; i++)
/// <summary>
/// Formats trace Id and span Id into valid Request-Id: |trace.span.
/// </summary>
/// <param name="traceId">Trace Id.</param>
/// <param name="spanId">Span id.</param>
/// <returns>valid Request-Id.</returns>
public static string FormatRequestId(string traceId, string spanId)
{
return String.Concat("|", traceId, ".", spanId, ".");
}

/// <summary>
/// Gets root id (string between '|' and the first dot) from the hierarchical Id.
/// </summary>
/// <param name="hierarchicalId">Id to extract root from.</param>
/// <returns>Root operation id.</returns>
internal static string GetRootId(string hierarchicalId)
{
// Returns the root Id from the '|' to the first '.' if any.
int rootEnd = hierarchicalId.IndexOf('.');
if (rootEnd < 0)
{
rootEnd = hierarchicalId.Length;
}

int rootStart = hierarchicalId[0] == '|' ? 1 : 0;
return hierarchicalId.Substring(rootStart, rootEnd - rootStart);
}

#pragma warning disable 612, 618
internal static string FormatAzureTracestate(string appId)
{
return String.Concat(W3CConstants.AzureTracestateNamespace, "=", appId);
}
#pragma warning restore 612, 618

/// <summary>
/// Converts byte array to hex lower case string.
/// </summary>
/// <returns>Array encoded as hex string</returns>
private static string GenerateId(byte[] bytes, int start, int length)
{
// See https://stackoverflow.com/questions/311165/how-do-you-convert-a-byte-array-to-a-hexadecimal-string-and-vice-versa/24343727#24343727
var result = new char[length * 2];
for (int i = start; i < start + length; i++)
{
var val = Lookup32[bytes[i]];
result[2 * i] = (char)val;
Expand Down
Loading

0 comments on commit 84a30c0

Please sign in to comment.