Rename of Propagators (#1427)

* Rename IPropagator to ITextMapPropagator, TextMapPropagator to TraceContextPropagator

* changelogs

* build fix

* make ITextMapPropagator an abstract class

* Renaming ITextMapPropagator to TextMapPropagator

* CompositeTextMapPropagator rename

* fix changhelog
This commit is contained in:
Cijo Thomas 2020-10-30 12:18:07 -07:00 committed by GitHub
parent be5a7a752d
commit 4975fb062b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 391 additions and 367 deletions

View File

@ -40,7 +40,7 @@ namespace Examples.Console
// Following shows how to use the OpenTracing shim
var tracer = new TracerShim(TracerProvider.Default.GetTracer("MyCompany.MyProduct.MyWebServer"), new TextMapPropagator());
var tracer = new TracerShim(TracerProvider.Default.GetTracer("MyCompany.MyProduct.MyWebServer"), new TraceContextPropagator());
using (IScope parentScope = tracer.BuildSpan("Parent").StartActive(finishSpanOnDispose: true))
{

View File

@ -30,7 +30,7 @@ namespace Utils.Messaging
public class MessageReceiver : IDisposable
{
private static readonly ActivitySource ActivitySource = new ActivitySource(nameof(MessageReceiver));
private static readonly IPropagator Propagator = new TextMapPropagator();
private static readonly TextMapPropagator Propagator = new TraceContextPropagator();
private readonly ILogger<MessageReceiver> logger;
private readonly IConnection connection;

View File

@ -28,7 +28,7 @@ namespace Utils.Messaging
public class MessageSender : IDisposable
{
private static readonly ActivitySource ActivitySource = new ActivitySource(nameof(MessageSender));
private static readonly IPropagator Propagator = new TextMapPropagator();
private static readonly TextMapPropagator Propagator = new TraceContextPropagator();
private readonly ILogger<MessageSender> logger;
private readonly IConnection connection;

View File

@ -9,6 +9,10 @@
* `B3Propagator` now supports the value `true` to be passed in for the header
`X-B3-Sampled`.
([#1413](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1413))
* Renamed TextMapPropagator to TraceContextPropagator, CompositePropapagor
to CompositeTextMapPropagator. IPropagator is renamed to TextMapPropagator
and changed from interface to abstract class.
([#1427](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1427))
## 0.7.0-beta.1

View File

@ -24,9 +24,9 @@ using OpenTelemetry.Internal;
namespace OpenTelemetry.Context.Propagation
{
/// <summary>
/// B3 text propagator. See https://github.com/openzipkin/b3-propagation for the specification.
/// A text map propagator for B3. See https://github.com/openzipkin/b3-propagation.
/// </summary>
public sealed class B3Propagator : IPropagator
public sealed class B3Propagator : TextMapPropagator
{
internal const string XB3TraceId = "X-B3-TraceId";
internal const string XB3SpanId = "X-B3-SpanId";
@ -73,10 +73,10 @@ namespace OpenTelemetry.Context.Propagation
}
/// <inheritdoc/>
public ISet<string> Fields => AllFields;
public override ISet<string> Fields => AllFields;
/// <inheritdoc/>
public PropagationContext Extract<T>(PropagationContext context, T carrier, Func<T, string, IEnumerable<string>> getter)
public override PropagationContext Extract<T>(PropagationContext context, T carrier, Func<T, string, IEnumerable<string>> getter)
{
if (context.ActivityContext.IsValid())
{
@ -107,7 +107,7 @@ namespace OpenTelemetry.Context.Propagation
}
/// <inheritdoc/>
public void Inject<T>(PropagationContext context, T carrier, Action<T, string, string> setter)
public override void Inject<T>(PropagationContext context, T carrier, Action<T, string, string> setter)
{
if (context.ActivityContext.TraceId == default || context.ActivityContext.SpanId == default)
{

View File

@ -24,9 +24,9 @@ using OpenTelemetry.Internal;
namespace OpenTelemetry.Context.Propagation
{
/// <summary>
/// W3C baggage: https://github.com/w3c/baggage/blob/master/baggage/HTTP_HEADER_FORMAT.md.
/// A text map propagator for W3C Baggage. See https://w3c.github.io/baggage/.
/// </summary>
public class BaggagePropagator : IPropagator
public class BaggagePropagator : TextMapPropagator
{
internal const string BaggageHeaderName = "Baggage";
@ -34,10 +34,10 @@ namespace OpenTelemetry.Context.Propagation
private const int MaxBaggageItems = 180;
/// <inheritdoc/>
public ISet<string> Fields => new HashSet<string> { BaggageHeaderName };
public override ISet<string> Fields => new HashSet<string> { BaggageHeaderName };
/// <inheritdoc/>
public PropagationContext Extract<T>(PropagationContext context, T carrier, Func<T, string, IEnumerable<string>> getter)
public override PropagationContext Extract<T>(PropagationContext context, T carrier, Func<T, string, IEnumerable<string>> getter)
{
if (context.Baggage != default)
{
@ -79,7 +79,7 @@ namespace OpenTelemetry.Context.Propagation
}
/// <inheritdoc/>
public void Inject<T>(PropagationContext context, T carrier, Action<T, string, string> setter)
public override void Inject<T>(PropagationContext context, T carrier, Action<T, string, string> setter)
{
if (carrier == null)
{

View File

@ -1,4 +1,4 @@
// <copyright file="CompositePropagator.cs" company="OpenTelemetry Authors">
// <copyright file="CompositeTextMapPropagator.cs" company="OpenTelemetry Authors">
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
@ -20,27 +20,28 @@ using System.Collections.Generic;
namespace OpenTelemetry.Context.Propagation
{
/// <summary>
/// CompositePropagator provides a mechanism for combining multiple propagators into a single one.
/// CompositeTextMapPropagator provides a mechanism for combining multiple
/// textmap propagators into a single one.
/// </summary>
public class CompositePropagator : IPropagator
public class CompositeTextMapPropagator : TextMapPropagator
{
private static readonly ISet<string> EmptyFields = new HashSet<string>();
private readonly List<IPropagator> propagators;
private readonly List<TextMapPropagator> propagators;
/// <summary>
/// Initializes a new instance of the <see cref="CompositePropagator"/> class.
/// Initializes a new instance of the <see cref="CompositeTextMapPropagator"/> class.
/// </summary>
/// <param name="propagators">List of <see cref="IPropagator"/> wire context propagator.</param>
public CompositePropagator(IEnumerable<IPropagator> propagators)
/// <param name="propagators">List of <see cref="TextMapPropagator"/> wire context propagator.</param>
public CompositeTextMapPropagator(IEnumerable<TextMapPropagator> propagators)
{
this.propagators = new List<IPropagator>(propagators ?? throw new ArgumentNullException(nameof(propagators)));
this.propagators = new List<TextMapPropagator>(propagators ?? throw new ArgumentNullException(nameof(propagators)));
}
/// <inheritdoc/>
public ISet<string> Fields => EmptyFields;
public override ISet<string> Fields => EmptyFields;
/// <inheritdoc/>
public PropagationContext Extract<T>(PropagationContext context, T carrier, Func<T, string, IEnumerable<string>> getter)
public override PropagationContext Extract<T>(PropagationContext context, T carrier, Func<T, string, IEnumerable<string>> getter)
{
foreach (var propagator in this.propagators)
{
@ -51,7 +52,7 @@ namespace OpenTelemetry.Context.Propagation
}
/// <inheritdoc/>
public void Inject<T>(PropagationContext context, T carrier, Action<T, string, string> setter)
public override void Inject<T>(PropagationContext context, T carrier, Action<T, string, string> setter)
{
foreach (var propagator in this.propagators)
{

View File

@ -1,54 +0,0 @@
// <copyright file="IPropagator.cs" company="OpenTelemetry Authors">
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>
using System;
using System.Collections.Generic;
namespace OpenTelemetry.Context.Propagation
{
/// <summary>
/// Defines an interface for Propagator, which is used to read and write
/// context data from and to message exchanges by the applications.
/// </summary>
public interface IPropagator
{
/// <summary>
/// Gets the list of headers used by propagator. The use cases of this are:
/// * allow pre-allocation of fields, especially in systems like gRPC Metadata
/// * allow a single-pass over an iterator (ex OpenTracing has no getter in TextMap).
/// </summary>
ISet<string> Fields { get; }
/// <summary>
/// Injects the context into a carrier.
/// </summary>
/// <typeparam name="T">Type of an object to set context on. Typically HttpRequest or similar.</typeparam>
/// <param name="context">The default context to transmit over the wire.</param>
/// <param name="carrier">Object to set context on. Instance of this object will be passed to setter.</param>
/// <param name="setter">Action that will set name and value pair on the object.</param>
void Inject<T>(PropagationContext context, T carrier, Action<T, string, string> setter);
/// <summary>
/// Extracts the context from a carrier.
/// </summary>
/// <typeparam name="T">Type of object to extract context from. Typically HttpRequest or similar.</typeparam>
/// <param name="context">The default context to be used if Extract fails.</param>
/// <param name="carrier">Object to extract context from. Instance of this object will be passed to the getter.</param>
/// <param name="getter">Function that will return string value of a key with the specified name.</param>
/// <returns>Context from it's text representation.</returns>
PropagationContext Extract<T>(PropagationContext context, T carrier, Func<T, string, IEnumerable<string>> getter);
}
}

View File

@ -16,250 +16,40 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using OpenTelemetry.Internal;
namespace OpenTelemetry.Context.Propagation
{
/// <summary>
/// W3C trace context text wire protocol formatter. See https://github.com/w3c/distributed-tracing/.
/// Defines an interface for a Propagator of TextMap type,
/// which uses string key/value pairs to inject and extract
/// propagation data.
/// </summary>
public class TextMapPropagator : IPropagator
public abstract class TextMapPropagator
{
private const string TraceParent = "traceparent";
private const string TraceState = "tracestate";
/// <summary>
/// Gets the list of headers used by propagator. The use cases of this are:
/// * allow pre-allocation of fields, especially in systems like gRPC Metadata
/// * allow a single-pass over an iterator (ex OpenTracing has no getter in TextMap).
/// </summary>
public abstract ISet<string> Fields { get; }
private static readonly int VersionPrefixIdLength = "00-".Length;
private static readonly int TraceIdLength = "0af7651916cd43dd8448eb211c80319c".Length;
private static readonly int VersionAndTraceIdLength = "00-0af7651916cd43dd8448eb211c80319c-".Length;
private static readonly int SpanIdLength = "00f067aa0ba902b7".Length;
private static readonly int VersionAndTraceIdAndSpanIdLength = "00-0af7651916cd43dd8448eb211c80319c-00f067aa0ba902b7-".Length;
private static readonly int OptionsLength = "00".Length;
private static readonly int TraceparentLengthV0 = "00-0af7651916cd43dd8448eb211c80319c-00f067aa0ba902b7-00".Length;
/// <summary>
/// Injects the context into a carrier.
/// </summary>
/// <typeparam name="T">Type of an object to set context on. Typically HttpRequest or similar.</typeparam>
/// <param name="context">The default context to transmit over the wire.</param>
/// <param name="carrier">Object to set context on. Instance of this object will be passed to setter.</param>
/// <param name="setter">Action that will set name and value pair on the object.</param>
public abstract void Inject<T>(PropagationContext context, T carrier, Action<T, string, string> setter);
/// <inheritdoc/>
public ISet<string> Fields => new HashSet<string> { TraceState, TraceParent };
/// <inheritdoc/>
public PropagationContext Extract<T>(PropagationContext context, T carrier, Func<T, string, IEnumerable<string>> getter)
{
if (context.ActivityContext.IsValid())
{
// If a valid context has already been extracted, perform a noop.
return context;
}
if (carrier == null)
{
OpenTelemetryApiEventSource.Log.FailedToExtractActivityContext(nameof(TextMapPropagator), "null carrier");
return context;
}
if (getter == null)
{
OpenTelemetryApiEventSource.Log.FailedToExtractActivityContext(nameof(TextMapPropagator), "null getter");
return context;
}
try
{
var traceparentCollection = getter(carrier, TraceParent);
// There must be a single traceparent
if (traceparentCollection == null || traceparentCollection.Count() != 1)
{
return context;
}
var traceparent = traceparentCollection.First();
var traceparentParsed = TryExtractTraceparent(traceparent, out var traceId, out var spanId, out var traceoptions);
if (!traceparentParsed)
{
return context;
}
string tracestate = null;
var tracestateCollection = getter(carrier, TraceState);
if (tracestateCollection?.Any() ?? false)
{
TryExtractTracestate(tracestateCollection.ToArray(), out tracestate);
}
return new PropagationContext(
new ActivityContext(traceId, spanId, traceoptions, tracestate, isRemote: true),
context.Baggage);
}
catch (Exception ex)
{
OpenTelemetryApiEventSource.Log.ActivityContextExtractException(nameof(TextMapPropagator), ex);
}
// in case of exception indicate to upstream that there is no parseable context from the top
return context;
}
/// <inheritdoc/>
public void Inject<T>(PropagationContext context, T carrier, Action<T, string, string> setter)
{
if (context.ActivityContext.TraceId == default || context.ActivityContext.SpanId == default)
{
OpenTelemetryApiEventSource.Log.FailedToInjectActivityContext(nameof(TextMapPropagator), "Invalid context");
return;
}
if (carrier == null)
{
OpenTelemetryApiEventSource.Log.FailedToInjectActivityContext(nameof(TextMapPropagator), "null carrier");
return;
}
if (setter == null)
{
OpenTelemetryApiEventSource.Log.FailedToInjectActivityContext(nameof(TextMapPropagator), "null setter");
return;
}
var traceparent = string.Concat("00-", context.ActivityContext.TraceId.ToHexString(), "-", context.ActivityContext.SpanId.ToHexString());
traceparent = string.Concat(traceparent, (context.ActivityContext.TraceFlags & ActivityTraceFlags.Recorded) != 0 ? "-01" : "-00");
setter(carrier, TraceParent, traceparent);
string tracestateStr = context.ActivityContext.TraceState;
if (tracestateStr?.Length > 0)
{
setter(carrier, TraceState, tracestateStr);
}
}
internal static bool TryExtractTraceparent(string traceparent, out ActivityTraceId traceId, out ActivitySpanId spanId, out ActivityTraceFlags traceOptions)
{
// from https://github.com/w3c/distributed-tracing/blob/master/trace_context/HTTP_HEADER_FORMAT.md
// traceparent: 00-0af7651916cd43dd8448eb211c80319c-00f067aa0ba902b7-01
traceId = default;
spanId = default;
traceOptions = default;
var bestAttempt = false;
if (string.IsNullOrWhiteSpace(traceparent) || traceparent.Length < TraceparentLengthV0)
{
return false;
}
// if version does not end with delimiter
if (traceparent[VersionPrefixIdLength - 1] != '-')
{
return false;
}
// or version is not a hex (will throw)
var version0 = HexCharToByte(traceparent[0]);
var version1 = HexCharToByte(traceparent[1]);
if (version0 == 0xf && version1 == 0xf)
{
return false;
}
if (version0 > 0)
{
// expected version is 00
// for higher versions - best attempt parsing of trace id, span id, etc.
bestAttempt = true;
}
if (traceparent[VersionAndTraceIdLength - 1] != '-')
{
return false;
}
try
{
traceId = ActivityTraceId.CreateFromString(traceparent.AsSpan().Slice(VersionPrefixIdLength, TraceIdLength));
}
catch (ArgumentOutOfRangeException)
{
// it's ok to still parse tracestate
return false;
}
if (traceparent[VersionAndTraceIdAndSpanIdLength - 1] != '-')
{
return false;
}
byte options1;
try
{
spanId = ActivitySpanId.CreateFromString(traceparent.AsSpan().Slice(VersionAndTraceIdLength, SpanIdLength));
options1 = HexCharToByte(traceparent[VersionAndTraceIdAndSpanIdLength + 1]);
}
catch (ArgumentOutOfRangeException)
{
// it's ok to still parse tracestate
return false;
}
if ((options1 & 1) == 1)
{
traceOptions |= ActivityTraceFlags.Recorded;
}
if ((!bestAttempt) && (traceparent.Length != VersionAndTraceIdAndSpanIdLength + OptionsLength))
{
return false;
}
if (bestAttempt)
{
if ((traceparent.Length > TraceparentLengthV0) && (traceparent[TraceparentLengthV0] != '-'))
{
return false;
}
}
return true;
}
internal static bool TryExtractTracestate(string[] tracestateCollection, out string tracestateResult)
{
tracestateResult = string.Empty;
if (tracestateCollection != null)
{
var result = new StringBuilder();
// Iterate in reverse order because when call builder set the elements is added in the
// front of the list.
for (int i = tracestateCollection.Length - 1; i >= 0; i--)
{
if (string.IsNullOrEmpty(tracestateCollection[i]))
{
return false;
}
result.Append(tracestateCollection[i]);
}
tracestateResult = result.ToString();
}
return true;
}
private static byte HexCharToByte(char c)
{
if (((c >= '0') && (c <= '9'))
|| ((c >= 'a') && (c <= 'f'))
|| ((c >= 'A') && (c <= 'F')))
{
return Convert.ToByte(c);
}
throw new ArgumentOutOfRangeException(nameof(c), $"Invalid character: {c}.");
}
/// <summary>
/// Extracts the context from a carrier.
/// </summary>
/// <typeparam name="T">Type of object to extract context from. Typically HttpRequest or similar.</typeparam>
/// <param name="context">The default context to be used if Extract fails.</param>
/// <param name="carrier">Object to extract context from. Instance of this object will be passed to the getter.</param>
/// <param name="getter">Function that will return string value of a key with the specified name.</param>
/// <returns>Context from it's text representation.</returns>
public abstract PropagationContext Extract<T>(PropagationContext context, T carrier, Func<T, string, IEnumerable<string>> getter);
}
}

View File

@ -0,0 +1,265 @@
// <copyright file="TraceContextPropagator.cs" company="OpenTelemetry Authors">
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using OpenTelemetry.Internal;
namespace OpenTelemetry.Context.Propagation
{
/// <summary>
/// A text map propagator for W3C trace context. See https://w3c.github.io/trace-context/.
/// </summary>
public class TraceContextPropagator : TextMapPropagator
{
private const string TraceParent = "traceparent";
private const string TraceState = "tracestate";
private static readonly int VersionPrefixIdLength = "00-".Length;
private static readonly int TraceIdLength = "0af7651916cd43dd8448eb211c80319c".Length;
private static readonly int VersionAndTraceIdLength = "00-0af7651916cd43dd8448eb211c80319c-".Length;
private static readonly int SpanIdLength = "00f067aa0ba902b7".Length;
private static readonly int VersionAndTraceIdAndSpanIdLength = "00-0af7651916cd43dd8448eb211c80319c-00f067aa0ba902b7-".Length;
private static readonly int OptionsLength = "00".Length;
private static readonly int TraceparentLengthV0 = "00-0af7651916cd43dd8448eb211c80319c-00f067aa0ba902b7-00".Length;
/// <inheritdoc/>
public override ISet<string> Fields => new HashSet<string> { TraceState, TraceParent };
/// <inheritdoc/>
public override PropagationContext Extract<T>(PropagationContext context, T carrier, Func<T, string, IEnumerable<string>> getter)
{
if (context.ActivityContext.IsValid())
{
// If a valid context has already been extracted, perform a noop.
return context;
}
if (carrier == null)
{
OpenTelemetryApiEventSource.Log.FailedToExtractActivityContext(nameof(TraceContextPropagator), "null carrier");
return context;
}
if (getter == null)
{
OpenTelemetryApiEventSource.Log.FailedToExtractActivityContext(nameof(TraceContextPropagator), "null getter");
return context;
}
try
{
var traceparentCollection = getter(carrier, TraceParent);
// There must be a single traceparent
if (traceparentCollection == null || traceparentCollection.Count() != 1)
{
return context;
}
var traceparent = traceparentCollection.First();
var traceparentParsed = TryExtractTraceparent(traceparent, out var traceId, out var spanId, out var traceoptions);
if (!traceparentParsed)
{
return context;
}
string tracestate = null;
var tracestateCollection = getter(carrier, TraceState);
if (tracestateCollection?.Any() ?? false)
{
TryExtractTracestate(tracestateCollection.ToArray(), out tracestate);
}
return new PropagationContext(
new ActivityContext(traceId, spanId, traceoptions, tracestate, isRemote: true),
context.Baggage);
}
catch (Exception ex)
{
OpenTelemetryApiEventSource.Log.ActivityContextExtractException(nameof(TraceContextPropagator), ex);
}
// in case of exception indicate to upstream that there is no parseable context from the top
return context;
}
/// <inheritdoc/>
public override void Inject<T>(PropagationContext context, T carrier, Action<T, string, string> setter)
{
if (context.ActivityContext.TraceId == default || context.ActivityContext.SpanId == default)
{
OpenTelemetryApiEventSource.Log.FailedToInjectActivityContext(nameof(TraceContextPropagator), "Invalid context");
return;
}
if (carrier == null)
{
OpenTelemetryApiEventSource.Log.FailedToInjectActivityContext(nameof(TraceContextPropagator), "null carrier");
return;
}
if (setter == null)
{
OpenTelemetryApiEventSource.Log.FailedToInjectActivityContext(nameof(TraceContextPropagator), "null setter");
return;
}
var traceparent = string.Concat("00-", context.ActivityContext.TraceId.ToHexString(), "-", context.ActivityContext.SpanId.ToHexString());
traceparent = string.Concat(traceparent, (context.ActivityContext.TraceFlags & ActivityTraceFlags.Recorded) != 0 ? "-01" : "-00");
setter(carrier, TraceParent, traceparent);
string tracestateStr = context.ActivityContext.TraceState;
if (tracestateStr?.Length > 0)
{
setter(carrier, TraceState, tracestateStr);
}
}
internal static bool TryExtractTraceparent(string traceparent, out ActivityTraceId traceId, out ActivitySpanId spanId, out ActivityTraceFlags traceOptions)
{
// from https://github.com/w3c/distributed-tracing/blob/master/trace_context/HTTP_HEADER_FORMAT.md
// traceparent: 00-0af7651916cd43dd8448eb211c80319c-00f067aa0ba902b7-01
traceId = default;
spanId = default;
traceOptions = default;
var bestAttempt = false;
if (string.IsNullOrWhiteSpace(traceparent) || traceparent.Length < TraceparentLengthV0)
{
return false;
}
// if version does not end with delimiter
if (traceparent[VersionPrefixIdLength - 1] != '-')
{
return false;
}
// or version is not a hex (will throw)
var version0 = HexCharToByte(traceparent[0]);
var version1 = HexCharToByte(traceparent[1]);
if (version0 == 0xf && version1 == 0xf)
{
return false;
}
if (version0 > 0)
{
// expected version is 00
// for higher versions - best attempt parsing of trace id, span id, etc.
bestAttempt = true;
}
if (traceparent[VersionAndTraceIdLength - 1] != '-')
{
return false;
}
try
{
traceId = ActivityTraceId.CreateFromString(traceparent.AsSpan().Slice(VersionPrefixIdLength, TraceIdLength));
}
catch (ArgumentOutOfRangeException)
{
// it's ok to still parse tracestate
return false;
}
if (traceparent[VersionAndTraceIdAndSpanIdLength - 1] != '-')
{
return false;
}
byte options1;
try
{
spanId = ActivitySpanId.CreateFromString(traceparent.AsSpan().Slice(VersionAndTraceIdLength, SpanIdLength));
options1 = HexCharToByte(traceparent[VersionAndTraceIdAndSpanIdLength + 1]);
}
catch (ArgumentOutOfRangeException)
{
// it's ok to still parse tracestate
return false;
}
if ((options1 & 1) == 1)
{
traceOptions |= ActivityTraceFlags.Recorded;
}
if ((!bestAttempt) && (traceparent.Length != VersionAndTraceIdAndSpanIdLength + OptionsLength))
{
return false;
}
if (bestAttempt)
{
if ((traceparent.Length > TraceparentLengthV0) && (traceparent[TraceparentLengthV0] != '-'))
{
return false;
}
}
return true;
}
internal static bool TryExtractTracestate(string[] tracestateCollection, out string tracestateResult)
{
tracestateResult = string.Empty;
if (tracestateCollection != null)
{
var result = new StringBuilder();
// Iterate in reverse order because when call builder set the elements is added in the
// front of the list.
for (int i = tracestateCollection.Length - 1; i >= 0; i--)
{
if (string.IsNullOrEmpty(tracestateCollection[i]))
{
return false;
}
result.Append(tracestateCollection[i]);
}
tracestateResult = result.ToString();
}
return true;
}
private static byte HexCharToByte(char c)
{
if (((c >= '0') && (c <= '9'))
|| ((c >= 'a') && (c <= 'f'))
|| ((c >= 'A') && (c <= 'F')))
{
return Convert.ToByte(c);
}
throw new ArgumentOutOfRangeException(nameof(c), $"Invalid character: {c}.");
}
}
}

View File

@ -27,11 +27,11 @@ namespace OpenTelemetry.Instrumentation.AspNet
public class AspNetInstrumentationOptions
{
/// <summary>
/// Gets or sets <see cref="IPropagator"/> for context propagation. Default value: <see cref="CompositePropagator"/> with <see cref="TextMapPropagator"/> &amp; <see cref="BaggagePropagator"/>.
/// Gets or sets <see cref="TextMapPropagator"/> for context propagation. Default value: <see cref="CompositeTextMapPropagator"/> with <see cref="TraceContextPropagator"/> &amp; <see cref="BaggagePropagator"/>.
/// </summary>
public IPropagator Propagator { get; set; } = new CompositePropagator(new IPropagator[]
public TextMapPropagator Propagator { get; set; } = new CompositeTextMapPropagator(new TextMapPropagator[]
{
new TextMapPropagator(),
new TraceContextPropagator(),
new BaggagePropagator(),
});

View File

@ -2,6 +2,11 @@
## Unreleased
* Renamed TextMapPropagator to TraceContextPropagator, CompositePropapagor
to CompositeTextMapPropagator. IPropagator is renamed to TextMapPropagator
and changed from interface to abstract class.
([#1427](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1427))
## 0.7.0-beta.1
Released 2020-Oct-16

View File

@ -70,7 +70,7 @@ namespace OpenTelemetry.Instrumentation.AspNet.Implementation
var request = context.Request;
var requestValues = request.Unvalidated;
if (!(this.options.Propagator is TextMapPropagator))
if (!(this.options.Propagator is TraceContextPropagator))
{
var ctx = this.options.Propagator.Extract(default, request, HttpRequestHeaderValuesGetter);
@ -139,7 +139,7 @@ namespace OpenTelemetry.Instrumentation.AspNet.Implementation
Activity activityToEnrich = activity;
Activity createdActivity = null;
bool isCustomPropagator = !(this.options.Propagator is TextMapPropagator);
bool isCustomPropagator = !(this.options.Propagator is TraceContextPropagator);
if (isCustomPropagator)
{

View File

@ -27,11 +27,11 @@ namespace OpenTelemetry.Instrumentation.AspNetCore
public class AspNetCoreInstrumentationOptions
{
/// <summary>
/// Gets or sets <see cref="IPropagator"/> for context propagation. Default value: <see cref="CompositePropagator"/> with <see cref="TextMapPropagator"/> &amp; <see cref="BaggagePropagator"/>.
/// Gets or sets <see cref="TextMapPropagator"/> for context propagation. Default value: <see cref="CompositeTextMapPropagator"/> with <see cref="TraceContextPropagator"/> &amp; <see cref="BaggagePropagator"/>.
/// </summary>
public IPropagator Propagator { get; set; } = new CompositePropagator(new IPropagator[]
public TextMapPropagator Propagator { get; set; } = new CompositeTextMapPropagator(new TextMapPropagator[]
{
new TextMapPropagator(),
new TraceContextPropagator(),
new BaggagePropagator(),
});

View File

@ -10,6 +10,10 @@
[Grpc.AspNetCore](https://www.nuget.org/packages/Grpc.AspNetCore/).
This option is enabled by default.
([#1423](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1423))
* Renamed TextMapPropagator to TraceContextPropagator, CompositePropapagor
to CompositeTextMapPropagator. IPropagator is renamed to TextMapPropagator
and changed from interface to abstract class.
([#1427](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1427))
## 0.7.0-beta.1

View File

@ -78,7 +78,7 @@ namespace OpenTelemetry.Instrumentation.AspNetCore.Implementation
}
var request = context.Request;
if (!this.hostingSupportsW3C || !(this.options.Propagator is TextMapPropagator))
if (!this.hostingSupportsW3C || !(this.options.Propagator is TraceContextPropagator))
{
var ctx = this.options.Propagator.Extract(default, request, HttpRequestHeaderValuesGetter);

View File

@ -6,6 +6,10 @@
`HttpWebRequest` in Activity.CustomProperty. To enrich activity, use the
Enrich action on the instrumentation.
([#1407](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1407))
* Renamed TextMapPropagator to TraceContextPropagator, CompositePropapagor
to CompositeTextMapPropagator. IPropagator is renamed to TextMapPropagator
and changed from interface to abstract class.
([#1427](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1427))
## 0.7.0-beta.1

View File

@ -35,11 +35,11 @@ namespace OpenTelemetry.Instrumentation.Http
public bool SetHttpFlavor { get; set; }
/// <summary>
/// Gets or sets <see cref="IPropagator"/> for context propagation. Default value: <see cref="CompositePropagator"/> with <see cref="TextMapPropagator"/> &amp; <see cref="BaggagePropagator"/>.
/// Gets or sets <see cref="TextMapPropagator"/> for context propagation. Default value: <see cref="CompositeTextMapPropagator"/> with <see cref="TraceContextPropagator"/> &amp; <see cref="BaggagePropagator"/>.
/// </summary>
public IPropagator Propagator { get; set; } = new CompositePropagator(new IPropagator[]
public TextMapPropagator Propagator { get; set; } = new CompositeTextMapPropagator(new TextMapPropagator[]
{
new TextMapPropagator(),
new TraceContextPropagator(),
new BaggagePropagator(),
});

View File

@ -35,11 +35,11 @@ namespace OpenTelemetry.Instrumentation.Http
public bool SetHttpFlavor { get; set; }
/// <summary>
/// Gets or sets <see cref="IPropagator"/> for context propagation. Default value: <see cref="CompositePropagator"/> with <see cref="TextMapPropagator"/> &amp; <see cref="BaggagePropagator"/>.
/// Gets or sets <see cref="TextMapPropagator"/> for context propagation. Default value: <see cref="CompositeTextMapPropagator"/> with <see cref="TraceContextPropagator"/> &amp; <see cref="BaggagePropagator"/>.
/// </summary>
public IPropagator Propagator { get; set; } = new CompositePropagator(new IPropagator[]
public TextMapPropagator Propagator { get; set; } = new CompositeTextMapPropagator(new TextMapPropagator[]
{
new TextMapPropagator(),
new TraceContextPropagator(),
new BaggagePropagator(),
});

View File

@ -115,7 +115,7 @@ namespace OpenTelemetry.Instrumentation.Http.Implementation
}
}
if (!(this.httpClientSupportsW3C && this.options.Propagator is TextMapPropagator))
if (!(this.httpClientSupportsW3C && this.options.Propagator is TraceContextPropagator))
{
this.options.Propagator.Inject(new PropagationContext(activity.Context, Baggage.Current), request, HttpRequestMessageHeaderValueSetter);
}

View File

@ -2,6 +2,11 @@
## Unreleased
* Renamed TextMapPropagator to TraceContextPropagator, CompositePropapagor
to CompositeTextMapPropagator. IPropagator is renamed to TextMapPropagator
and changed from interface to abstract class.
([#1427](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1427))
## 0.7.0-beta.1
Released 2020-Oct-16

View File

@ -24,9 +24,9 @@ namespace OpenTelemetry.Shims.OpenTracing
public class TracerShim : global::OpenTracing.ITracer
{
private readonly Trace.Tracer tracer;
private readonly IPropagator propagator;
private readonly TextMapPropagator propagator;
public TracerShim(Trace.Tracer tracer, IPropagator textFormat)
public TracerShim(Trace.Tracer tracer, TextMapPropagator textFormat)
{
this.tracer = tracer ?? throw new ArgumentNullException(nameof(tracer));
this.propagator = textFormat ?? throw new ArgumentNullException(nameof(textFormat));

View File

@ -128,7 +128,7 @@ namespace OpenTelemetry.Instrumentation.AspNet.Tests
var expectedTraceId = ActivityTraceId.CreateRandom();
var expectedSpanId = ActivitySpanId.CreateRandom();
var propagator = new Mock<IPropagator>();
var propagator = new Mock<TextMapPropagator>();
propagator.Setup(m => m.Extract<HttpRequest>(It.IsAny<PropagationContext>(), It.IsAny<HttpRequest>(), It.IsAny<Func<HttpRequest, string, IEnumerable<string>>>())).Returns(new PropagationContext(
new ActivityContext(
expectedTraceId,

View File

@ -196,7 +196,7 @@ namespace OpenTelemetry.Instrumentation.AspNetCore.Tests
var expectedTraceId = ActivityTraceId.CreateRandom();
var expectedSpanId = ActivitySpanId.CreateRandom();
var propagator = new Mock<IPropagator>();
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(

View File

@ -75,7 +75,7 @@ namespace OpenTelemetry.Instrumentation.Http.Tests
parent.ActivityTraceFlags = ActivityTraceFlags.Recorded;
// Ensure that the header value func does not throw if the header key can't be found
var mockPropagator = new Mock<IPropagator>();
var mockPropagator = new Mock<TextMapPropagator>();
// var isInjectedHeaderValueGetterThrows = false;
// mockTextFormat
@ -133,7 +133,7 @@ namespace OpenTelemetry.Instrumentation.Http.Tests
[InlineData(false)]
public async Task HttpClientInstrumentationInjectsHeadersAsync_CustomFormat(bool shouldEnrich)
{
var propagator = new Mock<IPropagator>();
var propagator = new Mock<TextMapPropagator>();
propagator.Setup(m => m.Inject<HttpRequestMessage>(It.IsAny<PropagationContext>(), It.IsAny<HttpRequestMessage>(), It.IsAny<Action<HttpRequestMessage, string, string>>()))
.Callback<PropagationContext, HttpRequestMessage, Action<HttpRequestMessage, string, string>>((context, message, action) =>
{

View File

@ -98,7 +98,7 @@ namespace OpenTelemetry.Instrumentation.Http.Tests
[Fact]
public async Task HttpWebRequestInstrumentationInjectsHeadersAsync_CustomFormat()
{
var propagator = new Mock<IPropagator>();
var propagator = new Mock<TextMapPropagator>();
propagator.Setup(m => m.Inject(It.IsAny<PropagationContext>(), It.IsAny<HttpWebRequest>(), It.IsAny<Action<HttpWebRequest, string, string>>()))
.Callback<PropagationContext, HttpWebRequest, Action<HttpWebRequest, string, string>>((context, message, action) =>
{

View File

@ -39,7 +39,7 @@ namespace OpenTelemetry.Shims.OpenTracing.Tests
Assert.Throws<ArgumentNullException>(() => new TracerShim(null, null));
// null tracer
Assert.Throws<ArgumentNullException>(() => new TracerShim(null, new TextMapPropagator()));
Assert.Throws<ArgumentNullException>(() => new TracerShim(null, new TraceContextPropagator()));
// null context format
var tracerMock = new Mock<Trace.Tracer>();
@ -50,7 +50,7 @@ namespace OpenTelemetry.Shims.OpenTracing.Tests
public void ScopeManager_NotNull()
{
var tracer = TracerProvider.Default.GetTracer(TracerName);
var shim = new TracerShim(tracer, new TextMapPropagator());
var shim = new TracerShim(tracer, new TraceContextPropagator());
// Internals of the ScopeManagerShim tested elsewhere
Assert.NotNull(shim.ScopeManager as ScopeManagerShim);
@ -60,7 +60,7 @@ namespace OpenTelemetry.Shims.OpenTracing.Tests
public void BuildSpan_NotNull()
{
var tracer = TracerProvider.Default.GetTracer(TracerName);
var shim = new TracerShim(tracer, new TextMapPropagator());
var shim = new TracerShim(tracer, new TraceContextPropagator());
// Internals of the SpanBuilderShim tested elsewhere
Assert.NotNull(shim.BuildSpan("foo") as SpanBuilderShim);
@ -70,7 +70,7 @@ namespace OpenTelemetry.Shims.OpenTracing.Tests
public void Inject_ArgumentValidation()
{
var tracer = TracerProvider.Default.GetTracer(TracerName);
var shim = new TracerShim(tracer, new TextMapPropagator());
var shim = new TracerShim(tracer, new TraceContextPropagator());
var spanContextShim = new SpanContextShim(new SpanContext(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.None));
var mockFormat = new Mock<IFormat<ITextMap>>();
@ -86,7 +86,7 @@ namespace OpenTelemetry.Shims.OpenTracing.Tests
public void Inject_UnknownFormatIgnored()
{
var tracer = TracerProvider.Default.GetTracer(TracerName);
var shim = new TracerShim(tracer, new TextMapPropagator());
var shim = new TracerShim(tracer, new TraceContextPropagator());
var spanContextShim = new SpanContextShim(new SpanContext(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.Recorded));
@ -102,7 +102,7 @@ namespace OpenTelemetry.Shims.OpenTracing.Tests
public void Extract_ArgumentValidation()
{
var tracer = TracerProvider.Default.GetTracer(TracerName);
var shim = new TracerShim(tracer, new TextMapPropagator());
var shim = new TracerShim(tracer, new TraceContextPropagator());
Assert.Throws<ArgumentNullException>(() => shim.Extract(null, new Mock<ITextMap>().Object));
Assert.Throws<ArgumentNullException>(() => shim.Extract(new Mock<IFormat<ITextMap>>().Object, null));
@ -112,7 +112,7 @@ namespace OpenTelemetry.Shims.OpenTracing.Tests
public void Extract_UnknownFormatIgnored()
{
var tracer = TracerProvider.Default.GetTracer(TracerName);
var shim = new TracerShim(tracer, new TextMapPropagator());
var shim = new TracerShim(tracer, new TraceContextPropagator());
var spanContextShim = new SpanContextShim(new SpanContext(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.None));
@ -128,11 +128,11 @@ namespace OpenTelemetry.Shims.OpenTracing.Tests
public void Extract_InvalidTraceParent()
{
var tracer = TracerProvider.Default.GetTracer(TracerName);
var shim = new TracerShim(tracer, new TextMapPropagator());
var shim = new TracerShim(tracer, new TraceContextPropagator());
var mockCarrier = new Mock<ITextMap>();
// The ProxyTracer uses OpenTelemetry.Context.Propagation.TextMapPropagator, so we need to satisfy the traceparent key at the least
// The ProxyTracer uses OpenTelemetry.Context.Propagation.TraceContextPropagator, so we need to satisfy the traceparent key at the least
var carrierMap = new Dictionary<string, string>
{
// This is an invalid traceparent value
@ -155,7 +155,7 @@ namespace OpenTelemetry.Shims.OpenTracing.Tests
var spanContextShim = new SpanContextShim(new SpanContext(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.None));
var format = new TextMapPropagator();
var format = new TraceContextPropagator();
var tracer = TracerProvider.Default.GetTracer(TracerName);
var shim = new TracerShim(tracer, format);

View File

@ -49,13 +49,13 @@ namespace OpenTelemetry.Context.Propagation.Tests
[Fact]
public void CompositePropagator_NullTextFormatList()
{
Assert.Throws<ArgumentNullException>(() => new CompositePropagator(null));
Assert.Throws<ArgumentNullException>(() => new CompositeTextMapPropagator(null));
}
[Fact]
public void CompositePropagator_TestPropagator()
{
var compositePropagator = new CompositePropagator(new List<IPropagator>
var compositePropagator = new CompositeTextMapPropagator(new List<TextMapPropagator>
{
new TestPropagator("custom-traceparent-1", "custom-tracestate-1"),
new TestPropagator("custom-traceparent-2", "custom-tracestate-2"),
@ -77,7 +77,7 @@ namespace OpenTelemetry.Context.Propagation.Tests
const string header01 = "custom-tracestate-01";
const string header02 = "custom-tracestate-02";
var compositePropagator = new CompositePropagator(new List<IPropagator>
var compositePropagator = new CompositeTextMapPropagator(new List<TextMapPropagator>
{
new TestPropagator("custom-traceparent", header01, true),
new TestPropagator("custom-traceparent", header02),
@ -106,9 +106,9 @@ namespace OpenTelemetry.Context.Propagation.Tests
[Fact]
public void CompositePropagator_ActivityContext_Baggage()
{
var compositePropagator = new CompositePropagator(new List<IPropagator>
var compositePropagator = new CompositeTextMapPropagator(new List<TextMapPropagator>
{
new TextMapPropagator(),
new TraceContextPropagator(),
new BaggagePropagator(),
});

View File

@ -21,7 +21,7 @@ using System.Linq;
namespace OpenTelemetry.Context.Propagation.Tests
{
public class TestPropagator : IPropagator
public class TestPropagator : TextMapPropagator
{
private readonly string idHeaderName;
private readonly string stateHeaderName;
@ -34,9 +34,9 @@ namespace OpenTelemetry.Context.Propagation.Tests
this.defaultContext = defaultContext;
}
public ISet<string> Fields => new HashSet<string>() { this.idHeaderName, this.stateHeaderName };
public override ISet<string> Fields => new HashSet<string>() { this.idHeaderName, this.stateHeaderName };
public PropagationContext Extract<T>(PropagationContext context, T carrier, Func<T, string, IEnumerable<string>> getter)
public override PropagationContext Extract<T>(PropagationContext context, T carrier, Func<T, string, IEnumerable<string>> getter)
{
if (this.defaultContext)
{
@ -49,7 +49,7 @@ namespace OpenTelemetry.Context.Propagation.Tests
return context;
}
var traceparentParsed = TextMapPropagator.TryExtractTraceparent(id.First(), out var traceId, out var spanId, out var traceoptions);
var traceparentParsed = TraceContextPropagator.TryExtractTraceparent(id.First(), out var traceId, out var spanId, out var traceoptions);
if (!traceparentParsed)
{
return context;
@ -59,7 +59,7 @@ namespace OpenTelemetry.Context.Propagation.Tests
IEnumerable<string> tracestateCollection = getter(carrier, this.stateHeaderName);
if (tracestateCollection?.Any() ?? false)
{
TextMapPropagator.TryExtractTracestate(tracestateCollection.ToArray(), out tracestate);
TraceContextPropagator.TryExtractTracestate(tracestateCollection.ToArray(), out tracestate);
}
return new PropagationContext(
@ -67,7 +67,7 @@ namespace OpenTelemetry.Context.Propagation.Tests
context.Baggage);
}
public void Inject<T>(PropagationContext context, T carrier, Action<T, string, string> setter)
public override void Inject<T>(PropagationContext context, T carrier, Action<T, string, string> setter)
{
string headerNumber = this.stateHeaderName.Split('-').Last();

View File

@ -52,7 +52,7 @@ namespace OpenTelemetry.Context.Propagation.Tests
{ TraceState, $"congo=lZWRzIHRoNhcm5hbCBwbGVhc3VyZS4,rojo=00-{TraceId}-00f067aa0ba902b7-01" },
};
var f = new TextMapPropagator();
var f = new TraceContextPropagator();
var ctx = f.Extract(default, headers, Getter);
Assert.Equal(ActivityTraceId.CreateFromString(TraceId.AsSpan()), ctx.ActivityContext.TraceId);
@ -73,7 +73,7 @@ namespace OpenTelemetry.Context.Propagation.Tests
{ TraceParent, $"00-{TraceId}-{SpanId}-00" },
};
var f = new TextMapPropagator();
var f = new TraceContextPropagator();
var ctx = f.Extract(default, headers, Getter);
Assert.Equal(ActivityTraceId.CreateFromString(TraceId.AsSpan()), ctx.ActivityContext.TraceId);
@ -89,7 +89,7 @@ namespace OpenTelemetry.Context.Propagation.Tests
{
var headers = new Dictionary<string, string>();
var f = new TextMapPropagator();
var f = new TraceContextPropagator();
var ctx = f.Extract(default, headers, Getter);
Assert.False(ctx.ActivityContext.IsValid());
@ -103,7 +103,7 @@ namespace OpenTelemetry.Context.Propagation.Tests
{ TraceParent, $"00-xyz7651916cd43dd8448eb211c80319c-{SpanId}-01" },
};
var f = new TextMapPropagator();
var f = new TraceContextPropagator();
var ctx = f.Extract(default, headers, Getter);
Assert.False(ctx.ActivityContext.IsValid());
@ -117,7 +117,7 @@ namespace OpenTelemetry.Context.Propagation.Tests
{ TraceParent, $"00-{TraceId}-{SpanId}-01" },
};
var f = new TextMapPropagator();
var f = new TraceContextPropagator();
var ctx = f.Extract(default, headers, Getter);
Assert.Null(ctx.ActivityContext.TraceState);
@ -132,7 +132,7 @@ namespace OpenTelemetry.Context.Propagation.Tests
{ TraceState, "k1=v1,k2=v2,k3=v3" },
};
var f = new TextMapPropagator();
var f = new TraceContextPropagator();
var ctx = f.Extract(default, headers, Getter);
Assert.Equal("k1=v1,k2=v2,k3=v3", ctx.ActivityContext.TraceState);
@ -151,7 +151,7 @@ namespace OpenTelemetry.Context.Propagation.Tests
var activityContext = new ActivityContext(traceId, spanId, ActivityTraceFlags.Recorded, traceState: null);
PropagationContext propagationContext = new PropagationContext(activityContext, default);
var carrier = new Dictionary<string, string>();
var f = new TextMapPropagator();
var f = new TraceContextPropagator();
f.Inject(propagationContext, carrier, Setter);
Assert.Equal(expectedHeaders, carrier);
@ -171,7 +171,7 @@ namespace OpenTelemetry.Context.Propagation.Tests
var activityContext = new ActivityContext(traceId, spanId, ActivityTraceFlags.Recorded, expectedHeaders[TraceState]);
PropagationContext propagationContext = new PropagationContext(activityContext, default);
var carrier = new Dictionary<string, string>();
var f = new TextMapPropagator();
var f = new TraceContextPropagator();
f.Inject(propagationContext, carrier, Setter);
Assert.Equal(expectedHeaders, carrier);