CorrelationContext -> Baggage (#1106)

* Baggage context part 1.

* A little cleanup.

* Return strings instead of objects. Removed default value in ctor because it generates a compiler warning about struct default constructor being used.

* Updated SDK & API projects for BaggageContext.

* Fixed broken areas, except for CorrelationContext tests.

* First round of tests and bug fixes.

* FIxed up HTTP instrumentation tests.

* Fixed up shim tests.

* More tests and improvements.

* Fixed broken test.

* Test coverage and bug fixes.

* Deterministic GetHashCode + tests.

* Added a link to the baggage api.

* Updated CHANGELOG.

* Renamed BaggageContext -> Baggage.

* CHANGELOG update.

Co-authored-by: Cijo Thomas <cithomas@microsoft.com>
This commit is contained in:
Mikel Blanchard 2020-08-27 16:03:38 -07:00 committed by GitHub
parent 4915d74b1c
commit d11dc0a962
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
41 changed files with 792 additions and 532 deletions

View File

@ -19,6 +19,7 @@ using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Text; using System.Text;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using OpenTelemetry;
using OpenTelemetry.Context.Propagation; using OpenTelemetry.Context.Propagation;
using RabbitMQ.Client; using RabbitMQ.Client;
@ -61,7 +62,7 @@ namespace Utils.Messaging
if (activity != null) if (activity != null)
{ {
// Inject the ActivityContext into the message headers to propagate trace context to the receiving service. // Inject the ActivityContext into the message headers to propagate trace context to the receiving service.
TextFormat.Inject(new PropagationContext(activity.Context, activity.Baggage), props, this.InjectTraceContextIntoBasicProperties); TextFormat.Inject(new PropagationContext(activity.Context, Baggage.Current), props, this.InjectTraceContextIntoBasicProperties);
// The OpenTelemetry messaging specification defines a number of attributes. These attributes are added here. // The OpenTelemetry messaging specification defines a number of attributes. These attributes are added here.
RabbitMqHelper.AddMessagingTags(activity); RabbitMqHelper.AddMessagingTags(activity);

View File

@ -0,0 +1,305 @@
// <copyright file="Baggage.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.Linq;
using OpenTelemetry.Context;
namespace OpenTelemetry
{
/// <summary>
/// Baggage implementation.
/// </summary>
/// <remarks>
/// Spec reference: <a href="https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/baggage/api.md">Baggage API</a>.
/// </remarks>
public readonly struct Baggage : IEquatable<Baggage>
{
private static readonly RuntimeContextSlot<Baggage> RuntimeContextSlot = RuntimeContext.RegisterSlot<Baggage>("otel.baggage");
private static readonly Dictionary<string, string> EmptyBaggage = new Dictionary<string, string>();
private readonly Dictionary<string, string> baggage;
/// <summary>
/// Initializes a new instance of the <see cref="Baggage"/> struct.
/// </summary>
/// <param name="baggage">Baggage key/value pairs.</param>
internal Baggage(Dictionary<string, string> baggage)
{
this.baggage = baggage;
}
/// <summary>
/// Gets or sets the current <see cref="Baggage"/>.
/// </summary>
public static Baggage Current
{
get => RuntimeContextSlot.Get();
set => RuntimeContextSlot.Set(value);
}
/// <summary>
/// Gets the number of key/value pairs in the baggage.
/// </summary>
public int Count => this.baggage?.Count ?? 0;
/// <summary>
/// Compare two entries of <see cref="Baggage"/> for equality.
/// </summary>
/// <param name="left">First Entry to compare.</param>
/// <param name="right">Second Entry to compare.</param>
public static bool operator ==(Baggage left, Baggage right) => left.Equals(right);
/// <summary>
/// Compare two entries of <see cref="Baggage"/> for not equality.
/// </summary>
/// <param name="left">First Entry to compare.</param>
/// <param name="right">Second Entry to compare.</param>
public static bool operator !=(Baggage left, Baggage right) => !(left == right);
/// <summary>
/// Create a <see cref="Baggage"/> instance from dictionary of baggage key/value pairs.
/// </summary>
/// <param name="baggageItems">Baggage key/value pairs.</param>
/// <returns><see cref="Baggage"/>.</returns>
public static Baggage Create(Dictionary<string, string> baggageItems = null)
{
if (baggageItems == null)
{
return default;
}
Dictionary<string, string> baggageCopy = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
foreach (KeyValuePair<string, string> baggageItem in baggageItems)
{
if (string.IsNullOrEmpty(baggageItem.Value))
{
baggageCopy.Remove(baggageItem.Key);
continue;
}
baggageCopy[baggageItem.Key] = baggageItem.Value;
}
return new Baggage(baggageCopy);
}
/// <summary>
/// Returns the name/value pairs in the <see cref="Baggage"/>.
/// </summary>
/// <param name="baggage">Optional <see cref="Baggage"/>. <see cref="Current"/> is used if not specified.</param>
/// <returns>Baggage key/value pairs.</returns>
public static IReadOnlyDictionary<string, string> GetBaggage(Baggage baggage = default)
=> baggage == default ? Current.GetBaggage() : baggage.GetBaggage();
/// <summary>
/// Returns an enumerator that iterates through the <see cref="Baggage"/>.
/// </summary>
/// <param name="baggage">Optional <see cref="Baggage"/>. <see cref="Current"/> is used if not specified.</param>
/// <returns><see cref="Dictionary{TKey, TValue}.Enumerator"/>.</returns>
public static Dictionary<string, string>.Enumerator GetEnumerator(Baggage baggage = default)
=> baggage == default ? Current.GetEnumerator() : baggage.GetEnumerator();
/// <summary>
/// Returns the value associated with the given name, or <see langword="null"/> if the given name is not present.
/// </summary>
/// <param name="name">Baggage item name.</param>
/// <param name="baggage">Optional <see cref="Baggage"/>. <see cref="Current"/> is used if not specified.</param>
/// <returns>Baggage item or <see langword="null"/> if nothing was found.</returns>
public static string GetBaggage(string name, Baggage baggage = default)
=> baggage == default ? Current.GetBaggage(name) : baggage.GetBaggage(name);
/// <summary>
/// Returns a new <see cref="Baggage"/> which contains the new key/value pair.
/// </summary>
/// <param name="name">Baggage item name.</param>
/// <param name="value">Baggage item value.</param>
/// <param name="baggage">Optional <see cref="Baggage"/>. <see cref="Current"/> is used if not specified.</param>
/// <returns>New <see cref="Baggage"/> containing the key/value pair.</returns>
public static Baggage SetBaggage(string name, string value, Baggage baggage = default)
=> baggage == default ? Current.SetBaggage(name, value) : baggage.SetBaggage(name, value);
/// <summary>
/// Returns a new <see cref="Baggage"/> which contains the new key/value pair.
/// </summary>
/// <param name="baggageItems">Baggage key/value pairs.</param>
/// <param name="baggage">Optional <see cref="Baggage"/>. <see cref="Current"/> is used if not specified.</param>
/// <returns>New <see cref="Baggage"/> containing the key/value pair.</returns>
public static Baggage SetBaggage(IEnumerable<KeyValuePair<string, string>> baggageItems, Baggage baggage = default)
=> baggage == default ? Current.SetBaggage(baggageItems) : baggage.SetBaggage(baggageItems);
/// <summary>
/// Returns a new <see cref="Baggage"/> with the key/value pair removed.
/// </summary>
/// <param name="name">Baggage item name.</param>
/// <param name="baggage">Optional <see cref="Baggage"/>. <see cref="Current"/> is used if not specified.</param>
/// <returns>New <see cref="Baggage"/> containing the key/value pair.</returns>
public static Baggage RemoveBaggage(string name, Baggage baggage = default)
=> baggage == default ? Current.RemoveBaggage(name) : baggage.RemoveBaggage(name);
/// <summary>
/// Returns a new <see cref="Baggage"/> with all the key/value pairs removed.
/// </summary>
/// <param name="baggage">Optional <see cref="Baggage"/>. <see cref="Current"/> is used if not specified.</param>
/// <returns>New <see cref="Baggage"/> containing the key/value pair.</returns>
public static Baggage ClearBaggage(Baggage baggage = default)
=> baggage == default ? Current.ClearBaggage() : baggage.ClearBaggage();
/// <summary>
/// Returns the name/value pairs in the <see cref="Baggage"/>.
/// </summary>
/// <returns>Baggage key/value pairs.</returns>
public IReadOnlyDictionary<string, string> GetBaggage()
=> this.baggage ?? EmptyBaggage;
/// <summary>
/// Returns the value associated with the given name, or <see langword="null"/> if the given name is not present.
/// </summary>
/// <param name="name">Baggage item name.</param>
/// <returns>Baggage item or <see langword="null"/> if nothing was found.</returns>
public string GetBaggage(string name)
{
if (string.IsNullOrEmpty(name))
{
throw new ArgumentNullException(nameof(name));
}
return this.baggage != null && this.baggage.TryGetValue(name, out string value)
? value
: null;
}
/// <summary>
/// Returns a new <see cref="Baggage"/> which contains the new key/value pair.
/// </summary>
/// <param name="name">Baggage item name.</param>
/// <param name="value">Baggage item value.</param>
/// <returns>New <see cref="Baggage"/> containing the key/value pair.</returns>
public Baggage SetBaggage(string name, string value)
{
if (string.IsNullOrEmpty(value))
{
return this.RemoveBaggage(name);
}
return Current = new Baggage(
new Dictionary<string, string>(this.baggage ?? EmptyBaggage, StringComparer.OrdinalIgnoreCase)
{
[name] = value,
});
}
/// <summary>
/// Returns a new <see cref="Baggage"/> which contains the new key/value pair.
/// </summary>
/// <param name="baggageItems">Baggage key/value pairs.</param>
/// <returns>New <see cref="Baggage"/> containing the key/value pair.</returns>
public Baggage SetBaggage(params KeyValuePair<string, string>[] baggageItems)
=> this.SetBaggage((IEnumerable<KeyValuePair<string, string>>)baggageItems);
/// <summary>
/// Returns a new <see cref="Baggage"/> which contains the new key/value pair.
/// </summary>
/// <param name="baggageItems">Baggage key/value pairs.</param>
/// <returns>New <see cref="Baggage"/> containing the key/value pair.</returns>
public Baggage SetBaggage(IEnumerable<KeyValuePair<string, string>> baggageItems)
{
if ((baggageItems?.Count() ?? 0) <= 0)
{
return this;
}
var newBaggage = new Dictionary<string, string>(this.baggage ?? EmptyBaggage, StringComparer.OrdinalIgnoreCase);
foreach (var item in baggageItems)
{
if (string.IsNullOrEmpty(item.Value))
{
newBaggage.Remove(item.Key);
}
else
{
newBaggage[item.Key] = item.Value;
}
}
return Current = new Baggage(newBaggage);
}
/// <summary>
/// Returns a new <see cref="Baggage"/> with the key/value pair removed.
/// </summary>
/// <param name="name">Baggage item name.</param>
/// <returns>New <see cref="Baggage"/> containing the key/value pair.</returns>
public Baggage RemoveBaggage(string name)
{
var baggage = new Dictionary<string, string>(this.baggage ?? EmptyBaggage, StringComparer.OrdinalIgnoreCase);
baggage.Remove(name);
return Current = new Baggage(baggage);
}
/// <summary>
/// Returns a new <see cref="Baggage"/> with all the key/value pairs removed.
/// </summary>
/// <returns>New <see cref="Baggage"/> containing the key/value pair.</returns>
public Baggage ClearBaggage()
=> Current = default;
/// <summary>
/// Returns an enumerator that iterates through the <see cref="Baggage"/>.
/// </summary>
/// <returns><see cref="Dictionary{TKey, TValue}.Enumerator"/>.</returns>
public Dictionary<string, string>.Enumerator GetEnumerator()
=> (this.baggage ?? EmptyBaggage).GetEnumerator();
/// <inheritdoc/>
public bool Equals(Baggage other)
{
bool baggageIsNullOrEmpty = this.baggage == null || this.baggage.Count <= 0;
if (baggageIsNullOrEmpty != (other.baggage == null || other.baggage.Count <= 0))
{
return false;
}
return baggageIsNullOrEmpty || this.baggage.SequenceEqual(other.baggage);
}
/// <inheritdoc/>
public override bool Equals(object obj)
=> (obj is Baggage baggage) && this.Equals(baggage);
/// <inheritdoc/>
public override int GetHashCode()
{
var baggage = this.baggage ?? EmptyBaggage;
unchecked
{
int res = 17;
foreach (var item in baggage)
{
res = (res * 23) + baggage.Comparer.GetHashCode(item.Key);
res = (res * 23) + item.Value.GetHashCode();
}
return res;
}
}
}
}

View File

@ -44,6 +44,11 @@
* Changed `StartSpan` to not set the created span as Active to match the spec * Changed `StartSpan` to not set the created span as Active to match the spec
([#994](https://github.com/open-telemetry/opentelemetry-dotnet/pull/994)) ([#994](https://github.com/open-telemetry/opentelemetry-dotnet/pull/994))
* Updated System.Diagnostics.DiagnosticSource to version 5.0.0-preview.8.20407.11. * Updated System.Diagnostics.DiagnosticSource to version 5.0.0-preview.8.20407.11.
* Removed `CorrelationContext` and added `Baggage`, an implementation of the
[`Baggage
API`](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/baggage/api.md)
spec
([#1106](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1106))
## 0.4.0-beta.2 ## 0.4.0-beta.2

View File

@ -1,152 +0,0 @@
// <copyright file="CorrelationContext.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;
namespace OpenTelemetry.Context
{
/// <summary>
/// Correlation context.
/// </summary>
public readonly struct CorrelationContext : IEquatable<CorrelationContext>
{
internal static readonly CorrelationContext Empty = new CorrelationContext(null);
#if NET452
internal static readonly IEnumerable<KeyValuePair<string, string>> EmptyBaggage = new KeyValuePair<string, string>[0];
#else
internal static readonly IEnumerable<KeyValuePair<string, string>> EmptyBaggage = Array.Empty<KeyValuePair<string, string>>();
#endif
private readonly Activity activity;
internal CorrelationContext(in Activity activity)
{
this.activity = activity;
}
/// <summary>
/// Gets the current <see cref="CorrelationContext"/>.
/// </summary>
public static CorrelationContext Current
{
get
{
Activity activity = Activity.Current;
return activity == null
? Empty
: new CorrelationContext(activity);
}
}
/// <summary>
/// Gets the correlation values.
/// </summary>
public IEnumerable<KeyValuePair<string, string>> Correlations => this.activity?.Baggage ?? EmptyBaggage;
/// <summary>
/// Compare two entries of <see cref="CorrelationContext"/> for equality.
/// </summary>
/// <param name="left">First Entry to compare.</param>
/// <param name="right">Second Entry to compare.</param>
public static bool operator ==(CorrelationContext left, CorrelationContext right) => left.Equals(right);
/// <summary>
/// Compare two entries of <see cref="CorrelationContext"/> for equality.
/// </summary>
/// <param name="left">First Entry to compare.</param>
/// <param name="right">Second Entry to compare.</param>
public static bool operator !=(CorrelationContext left, CorrelationContext right) => !(left == right);
/// <summary>
/// Retrieves a correlation item.
/// </summary>
/// <param name="key">Correlation item key.</param>
/// <returns>Retrieved correlation value or <see langword="null"/> if no match was found.</returns>
public string GetCorrelation(string key)
=> this.activity?.GetBaggageItem(key);
/// <summary>
/// Adds a correlation item.
/// </summary>
/// <param name="key">Correlation item key.</param>
/// <param name="value">Correlation item value.</param>
/// <returns>The <see cref="CorrelationContext"/> instance for chaining.</returns>
public CorrelationContext AddCorrelation(string key, string value)
{
this.activity?.AddBaggage(key, value);
return this;
}
/// <summary>
/// Adds correlation items.
/// </summary>
/// <param name="correlations">Correlation items.</param>
/// <returns>The <see cref="CorrelationContext"/> instance for chaining.</returns>
public CorrelationContext AddCorrelation(IEnumerable<KeyValuePair<string, string>> correlations)
{
if (correlations != null)
{
foreach (KeyValuePair<string, string> correlation in correlations)
{
this.activity?.AddBaggage(correlation.Key, correlation.Value);
}
}
return this;
}
/// <inheritdoc/>
public bool Equals(CorrelationContext other)
{
var thisCorrelations = this.Correlations;
var otherCorrelations = other.Correlations;
if (thisCorrelations.Count() != otherCorrelations.Count())
{
return false;
}
var thisEnumerator = thisCorrelations.GetEnumerator();
var otherEnumerator = otherCorrelations.GetEnumerator();
while (thisEnumerator.MoveNext() && otherEnumerator.MoveNext())
{
if (thisEnumerator.Current.Key != otherEnumerator.Current.Key
|| thisEnumerator.Current.Value != otherEnumerator.Current.Value)
{
return false;
}
}
return true;
}
/// <inheritdoc/>
public override bool Equals(object obj)
{
return obj is CorrelationContext context && this.Equals(context);
}
/// <inheritdoc/>
public override int GetHashCode()
{
return this.Correlations.GetHashCode();
}
}
}

View File

@ -188,7 +188,7 @@ namespace OpenTelemetry.Context.Propagation
return new PropagationContext( return new PropagationContext(
new ActivityContext(traceId, spanId, traceOptions, isRemote: true), new ActivityContext(traceId, spanId, traceOptions, isRemote: true),
context.ActivityBaggage); context.Baggage);
} }
catch (Exception e) catch (Exception e)
{ {
@ -248,7 +248,7 @@ namespace OpenTelemetry.Context.Propagation
return new PropagationContext( return new PropagationContext(
new ActivityContext(traceId, spanId, traceOptions, isRemote: true), new ActivityContext(traceId, spanId, traceOptions, isRemote: true),
context.ActivityBaggage); context.Baggage);
} }
catch (Exception e) catch (Exception e)
{ {

View File

@ -39,7 +39,7 @@ namespace OpenTelemetry.Context.Propagation
/// <inheritdoc/> /// <inheritdoc/>
public PropagationContext Extract<T>(PropagationContext context, T carrier, Func<T, string, IEnumerable<string>> getter) public PropagationContext Extract<T>(PropagationContext context, T carrier, Func<T, string, IEnumerable<string>> getter)
{ {
if (context.ActivityBaggage != null) if (context.Baggage != default)
{ {
// If baggage has already been extracted, perform a noop. // If baggage has already been extracted, perform a noop.
return context; return context;
@ -59,7 +59,7 @@ namespace OpenTelemetry.Context.Propagation
try try
{ {
IEnumerable<KeyValuePair<string, string>> baggage = null; Dictionary<string, string> baggage = null;
var baggageCollection = getter(carrier, BaggageHeaderName); var baggageCollection = getter(carrier, BaggageHeaderName);
if (baggageCollection?.Any() ?? false) if (baggageCollection?.Any() ?? false)
{ {
@ -68,7 +68,7 @@ namespace OpenTelemetry.Context.Propagation
return new PropagationContext( return new PropagationContext(
context.ActivityContext, context.ActivityContext,
baggage ?? context.ActivityBaggage); baggage == null ? context.Baggage : new Baggage(baggage));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -93,24 +93,29 @@ namespace OpenTelemetry.Context.Propagation
return; return;
} }
using IEnumerator<KeyValuePair<string, string>> e = context.ActivityBaggage?.GetEnumerator(); using var e = context.Baggage.GetEnumerator();
if (e?.MoveNext() == true) if (e.MoveNext() == true)
{ {
int itemCount = 1; int itemCount = 0;
StringBuilder baggage = new StringBuilder(); StringBuilder baggage = new StringBuilder();
do do
{ {
KeyValuePair<string, string> item = e.Current; KeyValuePair<string, string> item = e.Current;
if (string.IsNullOrEmpty(item.Value))
{
continue;
}
baggage.Append(WebUtility.UrlEncode(item.Key)).Append('=').Append(WebUtility.UrlEncode(item.Value)).Append(','); baggage.Append(WebUtility.UrlEncode(item.Key)).Append('=').Append(WebUtility.UrlEncode(item.Value)).Append(',');
} }
while (e.MoveNext() && itemCount++ < MaxBaggageItems && baggage.Length < MaxBaggageLength); while (e.MoveNext() && ++itemCount < MaxBaggageItems && baggage.Length < MaxBaggageLength);
baggage.Remove(baggage.Length - 1, 1); baggage.Remove(baggage.Length - 1, 1);
setter(carrier, BaggageHeaderName, baggage.ToString()); setter(carrier, BaggageHeaderName, baggage.ToString());
} }
} }
internal static bool TryExtractBaggage(string[] baggageCollection, out IEnumerable<KeyValuePair<string, string>> baggage) internal static bool TryExtractBaggage(string[] baggageCollection, out Dictionary<string, string> baggage)
{ {
int baggageLength = -1; int baggageLength = -1;
bool done = false; bool done = false;
@ -140,6 +145,11 @@ namespace OpenTelemetry.Context.Propagation
if (NameValueHeaderValue.TryParse(pair, out NameValueHeaderValue baggageItem)) if (NameValueHeaderValue.TryParse(pair, out NameValueHeaderValue baggageItem))
{ {
if (string.IsNullOrEmpty(baggageItem.Name) || string.IsNullOrEmpty(baggageItem.Value))
{
continue;
}
if (baggageDictionary == null) if (baggageDictionary == null)
{ {
baggageDictionary = new Dictionary<string, string>(); baggageDictionary = new Dictionary<string, string>();

View File

@ -15,9 +15,7 @@
// </copyright> // </copyright>
using System; using System;
using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq;
namespace OpenTelemetry.Context.Propagation namespace OpenTelemetry.Context.Propagation
{ {
@ -29,23 +27,23 @@ namespace OpenTelemetry.Context.Propagation
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="PropagationContext"/> struct. /// Initializes a new instance of the <see cref="PropagationContext"/> struct.
/// </summary> /// </summary>
/// <param name="activityContext">Entries for activity context.</param> /// <param name="activityContext"><see cref="System.Diagnostics.ActivityContext"/>.</param>
/// <param name="activityBaggage">Entries for activity baggage.</param> /// <param name="baggage"><see cref="Baggage"/>.</param>
public PropagationContext(ActivityContext activityContext, IEnumerable<KeyValuePair<string, string>> activityBaggage) public PropagationContext(ActivityContext activityContext, Baggage baggage)
{ {
this.ActivityContext = activityContext; this.ActivityContext = activityContext;
this.ActivityBaggage = activityBaggage; this.Baggage = baggage;
} }
/// <summary> /// <summary>
/// Gets <see cref="ActivityContext"/>. /// Gets <see cref="System.Diagnostics.ActivityContext"/>.
/// </summary> /// </summary>
public ActivityContext ActivityContext { get; } public ActivityContext ActivityContext { get; }
/// <summary> /// <summary>
/// Gets ActivityBaggage. /// Gets <see cref="Baggage"/>.
/// </summary> /// </summary>
public IEnumerable<KeyValuePair<string, string>> ActivityBaggage { get; } public Baggage Baggage { get; }
/// <summary> /// <summary>
/// Compare two entries of <see cref="PropagationContext"/> for equality. /// Compare two entries of <see cref="PropagationContext"/> for equality.
@ -64,35 +62,8 @@ namespace OpenTelemetry.Context.Propagation
/// <inheritdoc/> /// <inheritdoc/>
public bool Equals(PropagationContext value) public bool Equals(PropagationContext value)
{ {
if (this.ActivityContext != value.ActivityContext return this.ActivityContext == value.ActivityContext
|| this.ActivityBaggage is null != value.ActivityBaggage is null) && this.Baggage == value.Baggage;
{
return false;
}
if (this.ActivityBaggage is null)
{
return true;
}
if (this.ActivityBaggage.Count() != value.ActivityBaggage.Count())
{
return false;
}
var thisEnumerator = this.ActivityBaggage.GetEnumerator();
var valueEnumerator = value.ActivityBaggage.GetEnumerator();
while (thisEnumerator.MoveNext() && valueEnumerator.MoveNext())
{
if (thisEnumerator.Current.Key != valueEnumerator.Current.Key
|| thisEnumerator.Current.Value != valueEnumerator.Current.Value)
{
return false;
}
}
return true;
} }
/// <inheritdoc/> /// <inheritdoc/>
@ -103,7 +74,7 @@ namespace OpenTelemetry.Context.Propagation
{ {
var hashCode = 323591981; var hashCode = 323591981;
hashCode = (hashCode * -1521134295) + this.ActivityContext.GetHashCode(); hashCode = (hashCode * -1521134295) + this.ActivityContext.GetHashCode();
hashCode = (hashCode * -1521134295) + EqualityComparer<IEnumerable<KeyValuePair<string, string>>>.Default.GetHashCode(this.ActivityBaggage); hashCode = (hashCode * -1521134295) + this.Baggage.GetHashCode();
return hashCode; return hashCode;
} }
} }

View File

@ -90,7 +90,7 @@ namespace OpenTelemetry.Context.Propagation
return new PropagationContext( return new PropagationContext(
new ActivityContext(traceId, spanId, traceoptions, tracestate, isRemote: true), new ActivityContext(traceId, spanId, traceoptions, tracestate, isRemote: true),
context.ActivityBaggage); context.Baggage);
} }
catch (Exception ex) catch (Exception ex)
{ {

View File

@ -29,15 +29,15 @@ namespace OpenTelemetry.Metrics
/// <summary> /// <summary>
/// Adds the given value to the bound counter metric. /// Adds the given value to the bound counter metric.
/// </summary> /// </summary>
/// <param name="context">the associated span context.</param> /// <param name="context">the associated <see cref="SpanContext"/>.</param>
/// <param name="value">value by which the bound counter metric should be added.</param> /// <param name="value">value by which the bound counter metric should be added.</param>
public abstract void Add(in SpanContext context, T value); public abstract void Add(in SpanContext context, T value);
/// <summary> /// <summary>
/// Adds the given value to the bound counter metric. /// Adds the given value to the bound counter metric.
/// </summary> /// </summary>
/// <param name="context">the associated distributed context.</param> /// <param name="context">the associated <see cref="Baggage"/>.</param>
/// <param name="value">value by which the bound counter metric should be added.</param> /// <param name="value">value by which the bound counter metric should be added.</param>
public abstract void Add(in CorrelationContext context, T value); public abstract void Add(in Baggage context, T value);
} }
} }

View File

@ -29,15 +29,15 @@ namespace OpenTelemetry.Metrics
/// <summary> /// <summary>
/// Record the given value to the bound measure metric. /// Record the given value to the bound measure metric.
/// </summary> /// </summary>
/// <param name="context">the associated span context.</param> /// <param name="context">the associated <see cref="SpanContext"/>.</param>
/// <param name="value">the measurement to be recorded.</param> /// <param name="value">the measurement to be recorded.</param>
public abstract void Record(in SpanContext context, T value); public abstract void Record(in SpanContext context, T value);
/// <summary> /// <summary>
/// Record the given value to the bound measure metric. /// Record the given value to the bound measure metric.
/// </summary> /// </summary>
/// <param name="context">the associated distributed context.</param> /// <param name="context">the associated <see cref="Baggage"/>.</param>
/// <param name="value">the measurement to be recorded.</param> /// <param name="value">the measurement to be recorded.</param>
public abstract void Record(in CorrelationContext context, T value); public abstract void Record(in Baggage context, T value);
} }
} }

View File

@ -30,7 +30,7 @@ namespace OpenTelemetry.Metrics
/// <summary> /// <summary>
/// Adds or Increments the counter. /// Adds or Increments the counter.
/// </summary> /// </summary>
/// <param name="context">the associated span context.</param> /// <param name="context">the associated <see cref="SpanContext"/>.</param>
/// <param name="value">value by which the counter should be incremented.</param> /// <param name="value">value by which the counter should be incremented.</param>
/// <param name="labelset">The labelset associated with this value.</param> /// <param name="labelset">The labelset associated with this value.</param>
public abstract void Add(in SpanContext context, T value, LabelSet labelset); public abstract void Add(in SpanContext context, T value, LabelSet labelset);
@ -38,7 +38,7 @@ namespace OpenTelemetry.Metrics
/// <summary> /// <summary>
/// Adds or Increments the counter. /// Adds or Increments the counter.
/// </summary> /// </summary>
/// <param name="context">the associated span context.</param> /// <param name="context">the associated <see cref="SpanContext"/>.</param>
/// <param name="value">value by which the counter should be incremented.</param> /// <param name="value">value by which the counter should be incremented.</param>
/// <param name="labels">The labels or dimensions associated with this value.</param> /// <param name="labels">The labels or dimensions associated with this value.</param>
public abstract void Add(in SpanContext context, T value, IEnumerable<KeyValuePair<string, string>> labels); public abstract void Add(in SpanContext context, T value, IEnumerable<KeyValuePair<string, string>> labels);
@ -46,18 +46,18 @@ namespace OpenTelemetry.Metrics
/// <summary> /// <summary>
/// Adds or Increments the counter. /// Adds or Increments the counter.
/// </summary> /// </summary>
/// <param name="context">the associated distributed context.</param> /// <param name="context">the associated <see cref="Baggage"/>.</param>
/// <param name="value">value by which the counter should be incremented.</param> /// <param name="value">value by which the counter should be incremented.</param>
/// <param name="labelset">The labelset associated with this value.</param> /// <param name="labelset">The labelset associated with this value.</param>
public abstract void Add(in CorrelationContext context, T value, LabelSet labelset); public abstract void Add(in Baggage context, T value, LabelSet labelset);
/// <summary> /// <summary>
/// Adds or Increments the counter. /// Adds or Increments the counter.
/// </summary> /// </summary>
/// <param name="context">the associated distributed context.</param> /// <param name="context">the associated <see cref="Baggage"/>.</param>
/// <param name="value">value by which the counter should be incremented.</param> /// <param name="value">value by which the counter should be incremented.</param>
/// <param name="labels">The labels or dimensions associated with this value.</param> /// <param name="labels">The labels or dimensions associated with this value.</param>
public abstract void Add(in CorrelationContext context, T value, IEnumerable<KeyValuePair<string, string>> labels); public abstract void Add(in Baggage context, T value, IEnumerable<KeyValuePair<string, string>> labels);
/// <summary> /// <summary>
/// Gets the bound counter metric with given labelset. /// Gets the bound counter metric with given labelset.

View File

@ -30,7 +30,7 @@ namespace OpenTelemetry.Metrics
/// <summary> /// <summary>
/// Records a measure. /// Records a measure.
/// </summary> /// </summary>
/// <param name="context">the associated span context.</param> /// <param name="context">the associated <see cref="SpanContext"/>.</param>
/// <param name="value">value to record.</param> /// <param name="value">value to record.</param>
/// <param name="labelset">The labelset associated with this value.</param> /// <param name="labelset">The labelset associated with this value.</param>
public void Record(in SpanContext context, T value, LabelSet labelset) => this.Bind(labelset).Record(context, value); public void Record(in SpanContext context, T value, LabelSet labelset) => this.Bind(labelset).Record(context, value);
@ -38,7 +38,7 @@ namespace OpenTelemetry.Metrics
/// <summary> /// <summary>
/// Records a measure. /// Records a measure.
/// </summary> /// </summary>
/// <param name="context">the associated span context.</param> /// <param name="context">the associated <see cref="SpanContext"/>.</param>
/// <param name="value">value to record.</param> /// <param name="value">value to record.</param>
/// <param name="labels">The labels or dimensions associated with this value.</param> /// <param name="labels">The labels or dimensions associated with this value.</param>
public void Record(in SpanContext context, T value, IEnumerable<KeyValuePair<string, string>> labels) => this.Bind(labels).Record(context, value); public void Record(in SpanContext context, T value, IEnumerable<KeyValuePair<string, string>> labels) => this.Bind(labels).Record(context, value);
@ -46,18 +46,18 @@ namespace OpenTelemetry.Metrics
/// <summary> /// <summary>
/// Records a measure. /// Records a measure.
/// </summary> /// </summary>
/// <param name="context">the associated distributed context.</param> /// <param name="context">the associated <see cref="Baggage"/>.</param>
/// <param name="value">value to record.</param> /// <param name="value">value to record.</param>
/// <param name="labelset">The labelset associated with this value.</param> /// <param name="labelset">The labelset associated with this value.</param>
public void Record(in CorrelationContext context, T value, LabelSet labelset) => this.Bind(labelset).Record(context, value); public void Record(in Baggage context, T value, LabelSet labelset) => this.Bind(labelset).Record(context, value);
/// <summary> /// <summary>
/// Records a measure. /// Records a measure.
/// </summary> /// </summary>
/// <param name="context">the associated distributed context.</param> /// <param name="context">the associated <see cref="Baggage"/>.</param>
/// <param name="value">value to record.</param> /// <param name="value">value to record.</param>
/// <param name="labels">The labels or dimensions associated with this value.</param> /// <param name="labels">The labels or dimensions associated with this value.</param>
public void Record(in CorrelationContext context, T value, IEnumerable<KeyValuePair<string, string>> labels) => this.Bind(labels).Record(context, value); public void Record(in Baggage context, T value, IEnumerable<KeyValuePair<string, string>> labels) => this.Bind(labels).Record(context, value);
/// <summary> /// <summary>
/// Gets the bound measure metric with given labelset. /// Gets the bound measure metric with given labelset.

View File

@ -37,7 +37,7 @@ namespace OpenTelemetry.Metrics
} }
/// <inheritdoc/> /// <inheritdoc/>
public override void Add(in CorrelationContext context, T value) public override void Add(in Baggage context, T value)
{ {
} }
} }

View File

@ -37,7 +37,7 @@ namespace OpenTelemetry.Metrics
} }
/// <inheritdoc/> /// <inheritdoc/>
public override void Record(in CorrelationContext context, T value) public override void Record(in Baggage context, T value)
{ {
} }
} }

View File

@ -43,12 +43,12 @@ namespace OpenTelemetry.Metrics
} }
/// <inheritdoc/> /// <inheritdoc/>
public override void Add(in CorrelationContext context, T value, LabelSet labelset) public override void Add(in Baggage context, T value, LabelSet labelset)
{ {
} }
/// <inheritdoc/> /// <inheritdoc/>
public override void Add(in CorrelationContext context, T value, IEnumerable<KeyValuePair<string, string>> labels) public override void Add(in Baggage context, T value, IEnumerable<KeyValuePair<string, string>> labels)
{ {
} }

View File

@ -31,11 +31,6 @@ namespace OpenTelemetry.Trace
{ {
internal static readonly TelemetrySpan NoopInstance = new TelemetrySpan(null); internal static readonly TelemetrySpan NoopInstance = new TelemetrySpan(null);
internal readonly Activity Activity; internal readonly Activity Activity;
#if NET452
private static readonly IEnumerable<KeyValuePair<string, string>> EmptyBaggage = new KeyValuePair<string, string>[0];
#else
private static readonly IEnumerable<KeyValuePair<string, string>> EmptyBaggage = Array.Empty<KeyValuePair<string, string>>();
#endif
internal TelemetrySpan(Activity activity) internal TelemetrySpan(Activity activity)
{ {
@ -71,11 +66,6 @@ namespace OpenTelemetry.Trace
} }
} }
/// <summary>
/// Gets the span baggage.
/// </summary>
public IEnumerable<KeyValuePair<string, string>> Baggage => this.Activity?.Baggage ?? EmptyBaggage;
/// <summary> /// <summary>
/// Sets the status of the span execution. /// Sets the status of the span execution.
/// </summary> /// </summary>
@ -281,30 +271,6 @@ namespace OpenTelemetry.Trace
this.Activity?.Stop(); this.Activity?.Stop();
} }
/// <summary>
/// Retrieves a baggage item.
/// </summary>
/// <param name="key">Baggage item key.</param>
/// <returns>Retrieved baggage value or <see langword="null"/> if no match was found.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public string GetBaggageItem(string key)
{
return this.Activity?.GetBaggageItem(key);
}
/// <summary>
/// Adds a baggage item to the <see cref="TelemetrySpan"/>.
/// </summary>
/// <param name="key">Baggage item key.</param>
/// <param name="value">Baggage item value.</param>
/// <returns>The <see cref="TelemetrySpan"/> instance for chaining.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public TelemetrySpan AddBaggage(string key, string value)
{
this.Activity?.AddBaggage(key, value);
return this;
}
/// <summary> /// <summary>
/// Record Exception. /// Record Exception.
/// </summary> /// </summary>

View File

@ -19,6 +19,7 @@ using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Web; using System.Web;
using System.Web.Routing; using System.Web.Routing;
using OpenTelemetry.Context;
using OpenTelemetry.Context.Propagation; using OpenTelemetry.Context.Propagation;
using OpenTelemetry.Trace; using OpenTelemetry.Trace;
@ -86,12 +87,9 @@ namespace OpenTelemetry.Instrumentation.AspNet.Implementation
activity = newOne; activity = newOne;
} }
if (ctx.ActivityBaggage != null) if (ctx.Baggage != default)
{ {
foreach (var baggageItem in ctx.ActivityBaggage) Baggage.Current = ctx.Baggage;
{
activity.AddBaggage(baggageItem.Key, baggageItem.Value);
}
} }
} }
@ -134,7 +132,7 @@ namespace OpenTelemetry.Instrumentation.AspNet.Implementation
// this instrumentation created in Start. // this instrumentation created in Start.
// This is because Asp.Net, under certain circumstances, restores Activity.Current // This is because Asp.Net, under certain circumstances, restores Activity.Current
// to its own activity. // to its own activity.
if (activity.OperationName.Equals("Microsoft.AspNet.HttpReqIn.Start", StringComparison.Ordinal)) if (activity.OperationName.Equals("Microsoft.AspNet.HttpReqIn.Start"))
{ {
// This block is hit if Asp.Net did restore Current to its own activity, // This block is hit if Asp.Net did restore Current to its own activity,
// and we need to retrieve the one created by HttpInListener, // and we need to retrieve the one created by HttpInListener,
@ -194,7 +192,7 @@ namespace OpenTelemetry.Instrumentation.AspNet.Implementation
if (!(this.options.TextFormat is TraceContextFormat)) if (!(this.options.TextFormat is TraceContextFormat))
{ {
if (activity.OperationName.Equals(ActivityNameByHttpInListener, StringComparison.Ordinal)) if (activity.OperationName.Equals(ActivityNameByHttpInListener))
{ {
// If instrumentation started a new Activity, it must // If instrumentation started a new Activity, it must
// be stopped here. // be stopped here.

View File

@ -17,11 +17,11 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Globalization;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.Http.Features;
using OpenTelemetry.Context;
using OpenTelemetry.Context.Propagation; using OpenTelemetry.Context.Propagation;
using OpenTelemetry.Instrumentation.GrpcNetClient; using OpenTelemetry.Instrumentation.GrpcNetClient;
using OpenTelemetry.Trace; using OpenTelemetry.Trace;
@ -87,12 +87,9 @@ namespace OpenTelemetry.Instrumentation.AspNetCore.Implementation
activity = newOne; activity = newOne;
} }
if (ctx.ActivityBaggage != null) if (ctx.Baggage != default)
{ {
foreach (var baggageItem in ctx.ActivityBaggage) Baggage.Current = ctx.Baggage;
{
activity.AddBaggage(baggageItem.Key, baggageItem.Value);
}
} }
} }
@ -155,7 +152,7 @@ namespace OpenTelemetry.Instrumentation.AspNetCore.Implementation
} }
} }
if (activity.OperationName.Equals(ActivityNameByHttpInListener, StringComparison.Ordinal)) if (activity.OperationName.Equals(ActivityNameByHttpInListener))
{ {
// If instrumentation started a new Activity, it must // If instrumentation started a new Activity, it must
// be stopped here. // be stopped here.
@ -261,7 +258,7 @@ namespace OpenTelemetry.Instrumentation.AspNetCore.Implementation
} }
activity.AddTag(SemanticConventions.AttributeNetPeerIp, context.Connection.RemoteIpAddress.ToString()); activity.AddTag(SemanticConventions.AttributeNetPeerIp, context.Connection.RemoteIpAddress.ToString());
activity.AddTag(SemanticConventions.AttributeNetPeerPort, context.Connection.RemotePort.ToString(CultureInfo.InvariantCulture)); activity.AddTag(SemanticConventions.AttributeNetPeerPort, context.Connection.RemotePort.ToString());
activity.SetStatus(GrpcTagHelper.GetGrpcStatusCodeFromActivity(activity)); activity.SetStatus(GrpcTagHelper.GetGrpcStatusCodeFromActivity(activity));
} }
} }

View File

@ -16,13 +16,13 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Globalization;
using System.Net.Http; using System.Net.Http;
using System.Net.Sockets; using System.Net.Sockets;
using System.Reflection; using System.Reflection;
using System.Runtime.Versioning; using System.Runtime.Versioning;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using OpenTelemetry.Context;
using OpenTelemetry.Context.Propagation; using OpenTelemetry.Context.Propagation;
using OpenTelemetry.Trace; using OpenTelemetry.Trace;
@ -71,7 +71,7 @@ namespace OpenTelemetry.Instrumentation.Http.Implementation
{ {
var match = CoreAppMajorVersionCheckRegex.Match(framework); var match = CoreAppMajorVersionCheckRegex.Match(framework);
this.httpClientSupportsW3C = match.Success && int.Parse(match.Groups[1].Value, CultureInfo.InvariantCulture) >= 3; this.httpClientSupportsW3C = match.Success && int.Parse(match.Groups[1].Value) >= 3;
} }
this.options = options; this.options = options;
@ -113,7 +113,7 @@ namespace OpenTelemetry.Instrumentation.Http.Implementation
if (!(this.httpClientSupportsW3C && this.options.TextFormat is TraceContextFormat)) if (!(this.httpClientSupportsW3C && this.options.TextFormat is TraceContextFormat))
{ {
this.options.TextFormat.Inject(new PropagationContext(activity.Context, activity.Baggage), request, HttpRequestMessageHeaderValueSetter); this.options.TextFormat.Inject(new PropagationContext(activity.Context, Baggage.Current), request, HttpRequestMessageHeaderValueSetter);
} }
} }

View File

@ -23,6 +23,7 @@ using System.Reflection;
using System.Reflection.Emit; using System.Reflection.Emit;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Text; using System.Text;
using OpenTelemetry.Context;
using OpenTelemetry.Context.Propagation; using OpenTelemetry.Context.Propagation;
using OpenTelemetry.Trace; using OpenTelemetry.Trace;
@ -189,7 +190,7 @@ namespace OpenTelemetry.Instrumentation.Http.Implementation
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void InstrumentRequest(HttpWebRequest request, Activity activity) private static void InstrumentRequest(HttpWebRequest request, Activity activity)
=> Options.TextFormat.Inject(new PropagationContext(activity.Context, activity.Baggage), request, HttpWebRequestHeaderValuesSetter); => Options.TextFormat.Inject(new PropagationContext(activity.Context, Baggage.Current), request, HttpWebRequestHeaderValuesSetter);
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool IsRequestInstrumented(HttpWebRequest request) private static bool IsRequestInstrumented(HttpWebRequest request)

View File

@ -17,22 +17,20 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using global::OpenTracing; using global::OpenTracing;
using OpenTelemetry.Context;
namespace OpenTelemetry.Shims.OpenTracing namespace OpenTelemetry.Shims.OpenTracing
{ {
public sealed class SpanContextShim : ISpanContext public sealed class SpanContextShim : ISpanContext
{ {
private readonly IEnumerable<KeyValuePair<string, string>> baggage; public SpanContextShim(in Trace.SpanContext spanContext)
public SpanContextShim(in Trace.SpanContext spanContext, IEnumerable<KeyValuePair<string, string>> baggage = null)
{ {
if (!spanContext.IsValid) if (!spanContext.IsValid)
{ {
throw new ArgumentException($"{nameof(spanContext)} must be valid."); throw new ArgumentException(nameof(spanContext));
} }
this.SpanContext = spanContext; this.SpanContext = spanContext;
this.baggage = baggage;
} }
public Trace.SpanContext SpanContext { get; private set; } public Trace.SpanContext SpanContext { get; private set; }
@ -43,8 +41,7 @@ namespace OpenTelemetry.Shims.OpenTracing
/// <inheritdoc/> /// <inheritdoc/>
public string SpanId => this.SpanContext.SpanId.ToString(); public string SpanId => this.SpanContext.SpanId.ToString();
/// <inheritdoc/>
public IEnumerable<KeyValuePair<string, string>> GetBaggageItems() public IEnumerable<KeyValuePair<string, string>> GetBaggageItems()
=> this.baggage; => Baggage.GetBaggage();
} }
} }

View File

@ -18,6 +18,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using global::OpenTracing; using global::OpenTracing;
using OpenTelemetry.Context;
using OpenTelemetry.Trace; using OpenTelemetry.Trace;
namespace OpenTelemetry.Shims.OpenTracing namespace OpenTelemetry.Shims.OpenTracing
@ -52,7 +53,7 @@ namespace OpenTelemetry.Shims.OpenTracing
throw new ArgumentException(nameof(this.Span.Context)); throw new ArgumentException(nameof(this.Span.Context));
} }
this.spanContextShim = new SpanContextShim(this.Span.Context, this.Span.Baggage); this.spanContextShim = new SpanContextShim(this.Span.Context);
} }
public ISpanContext Context => this.spanContextShim; public ISpanContext Context => this.spanContextShim;
@ -73,14 +74,7 @@ namespace OpenTelemetry.Shims.OpenTracing
/// <inheritdoc/> /// <inheritdoc/>
public string GetBaggageItem(string key) public string GetBaggageItem(string key)
{ => Baggage.GetBaggage(key);
if (key is null)
{
throw new ArgumentNullException(nameof(key));
}
return this.Context.GetBaggageItems().FirstOrDefault(kvp => kvp.Key.Equals(key, StringComparison.Ordinal)).Value;
}
/// <inheritdoc/> /// <inheritdoc/>
public global::OpenTracing.ISpan Log(DateTimeOffset timestamp, IEnumerable<KeyValuePair<string, object>> fields) public global::OpenTracing.ISpan Log(DateTimeOffset timestamp, IEnumerable<KeyValuePair<string, object>> fields)
@ -173,13 +167,8 @@ namespace OpenTelemetry.Shims.OpenTracing
/// <inheritdoc/> /// <inheritdoc/>
public global::OpenTracing.ISpan SetBaggageItem(string key, string value) public global::OpenTracing.ISpan SetBaggageItem(string key, string value)
{ {
if (key is null) Baggage.SetBaggage(key, value);
{ return this;
throw new ArgumentNullException(nameof(key));
}
// TODO Revisit once CorrelationContext is finalized
throw new NotImplementedException();
} }
/// <inheritdoc/> /// <inheritdoc/>

View File

@ -17,6 +17,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using global::OpenTracing.Propagation; using global::OpenTracing.Propagation;
using OpenTelemetry.Context;
using OpenTelemetry.Context.Propagation; using OpenTelemetry.Context.Propagation;
namespace OpenTelemetry.Shims.OpenTracing namespace OpenTelemetry.Shims.OpenTracing
@ -83,7 +84,12 @@ namespace OpenTelemetry.Shims.OpenTracing
propagationContext = this.textFormat.Extract(propagationContext, carrierMap, GetCarrierKeyValue); propagationContext = this.textFormat.Extract(propagationContext, carrierMap, GetCarrierKeyValue);
} }
return !propagationContext.ActivityContext.IsValid() ? null : new SpanContextShim(new Trace.SpanContext(propagationContext.ActivityContext), propagationContext.ActivityBaggage); // TODO:
// Not sure what to do here. Really, Baggage should be returned and not set until this ISpanContext is turned into a live Span.
// But that code doesn't seem to exist.
// Baggage.Current = propagationContext.Baggage;
return !propagationContext.ActivityContext.IsValid() ? null : new SpanContextShim(new Trace.SpanContext(propagationContext.ActivityContext));
} }
/// <inheritdoc/> /// <inheritdoc/>
@ -115,7 +121,7 @@ namespace OpenTelemetry.Shims.OpenTracing
if ((format == BuiltinFormats.TextMap || format == BuiltinFormats.HttpHeaders) && carrier is ITextMap textMapCarrier) if ((format == BuiltinFormats.TextMap || format == BuiltinFormats.HttpHeaders) && carrier is ITextMap textMapCarrier)
{ {
this.textFormat.Inject( this.textFormat.Inject(
new PropagationContext(shim.SpanContext, shim.GetBaggageItems()), new PropagationContext(shim.SpanContext, Baggage.Current),
textMapCarrier, textMapCarrier,
(instrumentation, key, value) => instrumentation.Set(key, value)); (instrumentation, key, value) => instrumentation.Set(key, value));
} }

View File

@ -34,7 +34,7 @@ namespace OpenTelemetry.Metrics
this.sumAggregator.Update(value); this.sumAggregator.Update(value);
} }
public override void Add(in CorrelationContext context, double value) public override void Add(in Baggage context, double value)
{ {
this.sumAggregator.Update(value); this.sumAggregator.Update(value);
} }

View File

@ -29,7 +29,7 @@ namespace OpenTelemetry.Metrics
this.measureAggregator.Update(value); this.measureAggregator.Update(value);
} }
public override void Record(in CorrelationContext context, double value) public override void Record(in Baggage context, double value)
{ {
this.measureAggregator.Update(value); this.measureAggregator.Update(value);
} }

View File

@ -39,13 +39,13 @@ namespace OpenTelemetry.Metrics
this.Bind(new LabelSetSdk(labels), isShortLived: true).Add(context, value); this.Bind(new LabelSetSdk(labels), isShortLived: true).Add(context, value);
} }
public override void Add(in CorrelationContext context, double value, LabelSet labelset) public override void Add(in Baggage context, double value, LabelSet labelset)
{ {
// user not using bound instrument. Hence create a short-lived bound instrument. // user not using bound instrument. Hence create a short-lived bound instrument.
this.Bind(labelset, isShortLived: true).Add(context, value); this.Bind(labelset, isShortLived: true).Add(context, value);
} }
public override void Add(in CorrelationContext context, double value, IEnumerable<KeyValuePair<string, string>> labels) public override void Add(in Baggage context, double value, IEnumerable<KeyValuePair<string, string>> labels)
{ {
// user not using bound instrument. Hence create a short-lived bound instrument. // user not using bound instrument. Hence create a short-lived bound instrument.
this.Bind(new LabelSetSdk(labels), isShortLived: true).Add(context, value); this.Bind(new LabelSetSdk(labels), isShortLived: true).Add(context, value);

View File

@ -34,7 +34,7 @@ namespace OpenTelemetry.Metrics
this.sumAggregator.Update(value); this.sumAggregator.Update(value);
} }
public override void Add(in CorrelationContext context, long value) public override void Add(in Baggage context, long value)
{ {
this.sumAggregator.Update(value); this.sumAggregator.Update(value);
} }

View File

@ -29,7 +29,7 @@ namespace OpenTelemetry.Metrics
this.measureAggregator.Update(value); this.measureAggregator.Update(value);
} }
public override void Record(in CorrelationContext context, long value) public override void Record(in Baggage context, long value)
{ {
this.measureAggregator.Update(value); this.measureAggregator.Update(value);
} }

View File

@ -39,13 +39,13 @@ namespace OpenTelemetry.Metrics
this.Bind(new LabelSetSdk(labels), isShortLived: true).Add(context, value); this.Bind(new LabelSetSdk(labels), isShortLived: true).Add(context, value);
} }
public override void Add(in CorrelationContext context, long value, LabelSet labelset) public override void Add(in Baggage context, long value, LabelSet labelset)
{ {
// user not using bound instrument. Hence create a short-lived bound instrument. // user not using bound instrument. Hence create a short-lived bound instrument.
this.Bind(labelset, isShortLived: true).Add(context, value); this.Bind(labelset, isShortLived: true).Add(context, value);
} }
public override void Add(in CorrelationContext context, long value, IEnumerable<KeyValuePair<string, string>> labels) public override void Add(in Baggage context, long value, IEnumerable<KeyValuePair<string, string>> labels)
{ {
// user not using bound instrument. Hence create a short-lived bound instrument. // user not using bound instrument. Hence create a short-lived bound instrument.
this.Bind(new LabelSetSdk(labels), isShortLived: true).Add(context, value); this.Bind(new LabelSetSdk(labels), isShortLived: true).Add(context, value);

View File

@ -133,7 +133,7 @@ namespace OpenTelemetry.Instrumentation.AspNet.Tests
expectedTraceId, expectedTraceId,
expectedSpanId, expectedSpanId,
ActivityTraceFlags.Recorded), ActivityTraceFlags.Recorded),
null)); default));
var activity = new Activity(ActivityNameAspNet).AddBaggage("Stuff", "123"); var activity = new Activity(ActivityNameAspNet).AddBaggage("Stuff", "123");
activity.SetParentId(expectedTraceId, expectedSpanId, ActivityTraceFlags.Recorded); activity.SetParentId(expectedTraceId, expectedSpanId, ActivityTraceFlags.Recorded);

View File

@ -143,11 +143,13 @@ namespace OpenTelemetry.Instrumentation.AspNetCore.Tests
var expectedSpanId = ActivitySpanId.CreateRandom(); var expectedSpanId = ActivitySpanId.CreateRandom();
var textFormat = new Mock<ITextFormat>(); var textFormat = new Mock<ITextFormat>();
textFormat.Setup(m => m.Extract(It.IsAny<PropagationContext>(), It.IsAny<HttpRequest>(), It.IsAny<Func<HttpRequest, string, IEnumerable<string>>>())).Returns(new PropagationContext( textFormat.Setup(m => m.Extract(It.IsAny<PropagationContext>(), It.IsAny<HttpRequest>(), It.IsAny<Func<HttpRequest, string, IEnumerable<string>>>())).Returns(
new ActivityContext( new PropagationContext(
expectedTraceId, new ActivityContext(
expectedSpanId, expectedTraceId,
ActivityTraceFlags.Recorded), null)); expectedSpanId,
ActivityTraceFlags.Recorded),
default));
// Arrange // Arrange
using (var testFactory = this.factory using (var testFactory = this.factory

View File

@ -21,6 +21,7 @@ using System.Net.Http;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Moq; using Moq;
using OpenTelemetry.Context;
using OpenTelemetry.Context.Propagation; using OpenTelemetry.Context.Propagation;
using OpenTelemetry.Instrumentation.Http.Implementation; using OpenTelemetry.Instrumentation.Http.Implementation;
using OpenTelemetry.Tests; using OpenTelemetry.Tests;
@ -250,6 +251,43 @@ namespace OpenTelemetry.Instrumentation.Http.Tests
Assert.Equal(2, processor.Invocations.Count); // OnShutdown/Dispose called. Assert.Equal(2, processor.Invocations.Count); // OnShutdown/Dispose called.
} }
[Fact]
public async Task HttpClientInstrumentationCorrelationAndBaggage()
{
var activityProcessor = new Mock<ActivityProcessor>();
using var parent = new Activity("w3c activity");
parent.SetIdFormat(ActivityIdFormat.W3C);
parent.AddBaggage("k1", "v1");
parent.ActivityTraceFlags = ActivityTraceFlags.Recorded;
parent.Start();
Baggage.SetBaggage("k2", "v2");
using (Sdk.CreateTracerProviderBuilder()
.AddHttpClientInstrumentation()
.AddProcessor(activityProcessor.Object)
.Build())
{
using var c = new HttpClient();
using var r = await c.GetAsync("https://opentelemetry.io/").ConfigureAwait(false);
}
Assert.Equal(4, activityProcessor.Invocations.Count);
var activity = (Activity)activityProcessor.Invocations[1].Arguments[0];
HttpRequestMessage thisRequest = (HttpRequestMessage)activity.GetCustomProperty(HttpHandlerDiagnosticListener.RequestCustomPropertyName);
string[] correlationContext = thisRequest.Headers.GetValues("Correlation-Context").First().Split(',');
Assert.Single(correlationContext);
Assert.Contains("k1=v1", correlationContext);
string[] baggage = thisRequest.Headers.GetValues("Baggage").First().Split(',');
Assert.Single(baggage);
Assert.Contains("k2=v2", baggage);
}
public void Dispose() public void Dispose()
{ {
this.serverLifeTime?.Dispose(); this.serverLifeTime?.Dispose();

View File

@ -24,6 +24,7 @@ using System.Net;
using System.Net.Http; using System.Net.Http;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using OpenTelemetry.Context;
using OpenTelemetry.Instrumentation.Http.Implementation; using OpenTelemetry.Instrumentation.Http.Implementation;
using OpenTelemetry.Tests; using OpenTelemetry.Tests;
using OpenTelemetry.Trace; using OpenTelemetry.Trace;
@ -375,7 +376,7 @@ namespace OpenTelemetry.Instrumentation.Http.Tests
} }
[Fact] [Fact]
public async Task TestTraceStateAndCorrelationContext() public async Task TestTraceStateAndBaggage()
{ {
try try
{ {
@ -384,9 +385,10 @@ namespace OpenTelemetry.Instrumentation.Http.Tests
var parent = new Activity("w3c activity"); var parent = new Activity("w3c activity");
parent.SetParentId(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom()); parent.SetParentId(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom());
parent.TraceStateString = "some=state"; parent.TraceStateString = "some=state";
parent.AddBaggage("k", "v");
parent.Start(); parent.Start();
Baggage.SetBaggage("k", "v");
// Send a random Http request to generate some events // Send a random Http request to generate some events
using (var client = new HttpClient()) using (var client = new HttpClient())
{ {
@ -402,10 +404,10 @@ namespace OpenTelemetry.Instrumentation.Http.Tests
var traceparent = startRequest.Headers["traceparent"]; var traceparent = startRequest.Headers["traceparent"];
var tracestate = startRequest.Headers["tracestate"]; var tracestate = startRequest.Headers["tracestate"];
var correlationContext = startRequest.Headers["baggage"]; var baggage = startRequest.Headers["baggage"];
Assert.NotNull(traceparent); Assert.NotNull(traceparent);
Assert.Equal("some=state", tracestate); Assert.Equal("some=state", tracestate);
Assert.Equal("k=v", correlationContext); Assert.Equal("k=v", baggage);
Assert.StartsWith($"00-{parent.TraceId.ToHexString()}-", traceparent); Assert.StartsWith($"00-{parent.TraceId.ToHexString()}-", traceparent);
Assert.Matches("^[0-9a-f]{2}-[0-9a-f]{32}-[0-9a-f]{16}-[0-9a-f]{2}$", traceparent); Assert.Matches("^[0-9a-f]{2}-[0-9a-f]{32}-[0-9a-f]{16}-[0-9a-f]{2}$", traceparent);
} }
@ -692,32 +694,29 @@ namespace OpenTelemetry.Instrumentation.Http.Tests
[Fact] [Fact]
public async Task TestInvalidBaggage() public async Task TestInvalidBaggage()
{ {
var parentActivity = new Activity("parent") Baggage
.AddBaggage("key", "value") .SetBaggage("key", "value")
.AddBaggage("bad/key", "value") .SetBaggage("bad/key", "value")
.AddBaggage("goodkey", "bad/value") .SetBaggage("goodkey", "bad/value");
.Start();
using (var eventRecords = new ActivitySourceRecorder()) using var eventRecords = new ActivitySourceRecorder();
using (var client = new HttpClient())
{ {
using (var client = new HttpClient()) (await client.GetAsync(this.BuildRequestUrl())).Dispose();
{
(await client.GetAsync(this.BuildRequestUrl())).Dispose();
}
Assert.Equal(2, eventRecords.Records.Count());
Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Start"));
Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Stop"));
WebRequest thisRequest = (WebRequest)eventRecords.Records.First().Value.GetCustomProperty(HttpWebRequestActivitySource.RequestCustomPropertyName);
string[] correlationContext = thisRequest.Headers["baggage"].Split(',');
Assert.Equal(3, correlationContext.Length);
Assert.Contains("key=value", correlationContext);
Assert.Contains("bad%2Fkey=value", correlationContext);
Assert.Contains("goodkey=bad%2Fvalue", correlationContext);
} }
parentActivity.Stop(); Assert.Equal(2, eventRecords.Records.Count());
Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Start"));
Assert.Equal(1, eventRecords.Records.Count(rec => rec.Key == "Stop"));
WebRequest thisRequest = (WebRequest)eventRecords.Records.First().Value.GetCustomProperty(HttpWebRequestActivitySource.RequestCustomPropertyName);
string[] baggage = thisRequest.Headers["Baggage"].Split(',');
Assert.Equal(3, baggage.Length);
Assert.Contains("key=value", baggage);
Assert.Contains("bad%2Fkey=value", baggage);
Assert.Contains("goodkey=bad%2Fvalue", baggage);
} }
/// <summary> /// <summary>

View File

@ -51,7 +51,7 @@ namespace OpenTelemetry.Shims.OpenTracing.Tests
{ {
var shim = GetSpanContextShim(); var shim = GetSpanContextShim();
var baggage = shim.GetBaggageItems(); var baggage = shim.GetBaggageItems();
Assert.Null(baggage); Assert.Empty(baggage);
} }
internal static SpanContextShim GetSpanContextShim() internal static SpanContextShim GetSpanContextShim()

View File

@ -0,0 +1,273 @@
// <copyright file="BaggageTests.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 Xunit;
namespace OpenTelemetry.Tests
{
public class BaggageTests
{
private const string K1 = "Key1";
private const string K2 = "Key2";
private const string K3 = "Key3";
private const string V1 = "Value1";
private const string V2 = "Value2";
private const string V3 = "Value3";
[Fact]
public void EmptyTest()
{
Assert.Empty(Baggage.GetBaggage());
Assert.Empty(Baggage.Current.GetBaggage());
}
[Fact]
public void SetAndGetTest()
{
var list = new List<KeyValuePair<string, string>>(2)
{
new KeyValuePair<string, string>(K1, V1),
new KeyValuePair<string, string>(K2, V2),
};
Baggage.SetBaggage(K1, V1);
Baggage.Current.SetBaggage(K2, V2);
Assert.NotEmpty(Baggage.GetBaggage());
Assert.Equal(list, Baggage.GetBaggage(Baggage.Current));
Assert.Equal(V1, Baggage.GetBaggage(K1));
Assert.Equal(V1, Baggage.GetBaggage(K1.ToLower()));
Assert.Equal(V1, Baggage.GetBaggage(K1.ToUpper()));
Assert.Null(Baggage.GetBaggage("NO_KEY"));
Assert.Equal(V2, Baggage.Current.GetBaggage(K2));
Assert.Throws<ArgumentNullException>(() => Baggage.GetBaggage(null));
}
[Fact]
public void SetExistingKeyTest()
{
var list = new List<KeyValuePair<string, string>>(2)
{
new KeyValuePair<string, string>(K1, V1),
};
Baggage.Current.SetBaggage(new KeyValuePair<string, string>(K1, V1));
var baggage = Baggage.SetBaggage(K1, V1);
Baggage.SetBaggage(new Dictionary<string, string> { [K1] = V1 }, baggage);
Assert.Equal(list, Baggage.GetBaggage());
}
[Fact]
public void SetNullValueTest()
{
var baggage = Baggage.Current;
baggage = Baggage.SetBaggage(K1, V1, baggage);
Assert.Equal(1, Baggage.Current.Count);
Assert.Equal(1, baggage.Count);
Baggage.Current.SetBaggage(K2, null);
Assert.Equal(1, Baggage.Current.Count);
Assert.Empty(Baggage.SetBaggage(K1, null).GetBaggage());
Baggage.SetBaggage(K1, V1);
Baggage.SetBaggage(new Dictionary<string, string>
{
[K1] = null,
[K2] = V2,
});
Assert.Equal(1, Baggage.Current.Count);
Assert.Contains(Baggage.GetBaggage(), kvp => kvp.Key == K2);
}
[Fact]
public void RemoveTest()
{
var empty = Baggage.Current;
var empty2 = Baggage.RemoveBaggage(K1);
Assert.True(empty == empty2);
var baggage = Baggage.SetBaggage(new Dictionary<string, string>
{
[K1] = V1,
[K2] = V2,
[K3] = V3,
});
var baggage2 = Baggage.RemoveBaggage(K1, baggage);
Assert.Equal(3, baggage.Count);
Assert.Equal(2, baggage2.Count);
Assert.DoesNotContain(new KeyValuePair<string, string>(K1, V1), baggage2.GetBaggage());
}
[Fact]
public void ClearTest()
{
var baggage = Baggage.SetBaggage(new Dictionary<string, string>
{
[K1] = V1,
[K2] = V2,
[K3] = V3,
});
Assert.Equal(3, baggage.Count);
Baggage.ClearBaggage();
Assert.Equal(0, Baggage.Current.Count);
}
[Fact]
public void ContextFlowTest()
{
var baggage = Baggage.SetBaggage(K1, V1);
var baggage2 = Baggage.Current.SetBaggage(K2, V2);
var baggage3 = Baggage.SetBaggage(K3, V3);
Assert.Equal(1, baggage.Count);
Assert.Equal(2, baggage2.Count);
Assert.Equal(3, baggage3.Count);
Baggage.Current = baggage;
var baggage4 = Baggage.SetBaggage(K3, V3);
Assert.Equal(2, baggage4.Count);
Assert.DoesNotContain(new KeyValuePair<string, string>(K2, V2), baggage4.GetBaggage());
}
[Fact]
public void EnumeratorTest()
{
var list = new List<KeyValuePair<string, string>>(2)
{
new KeyValuePair<string, string>(K1, V1),
new KeyValuePair<string, string>(K2, V2),
};
var baggage = Baggage.SetBaggage(K1, V1);
baggage = Baggage.SetBaggage(K2, V2, baggage);
var enumerator = Baggage.GetEnumerator(baggage);
Assert.True(enumerator.MoveNext());
var tag1 = enumerator.Current;
Assert.True(enumerator.MoveNext());
var tag2 = enumerator.Current;
Assert.False(enumerator.MoveNext());
Assert.Equal(list, new List<KeyValuePair<string, string>> { tag1, tag2 });
Baggage.ClearBaggage();
enumerator = Baggage.GetEnumerator();
Assert.False(enumerator.MoveNext());
}
[Fact]
public void EqualsTest()
{
var bc1 = new Baggage(new Dictionary<string, string>() { [K1] = V1, [K2] = V2 });
var bc2 = new Baggage(new Dictionary<string, string>() { [K1] = V1, [K2] = V2 });
var bc3 = new Baggage(new Dictionary<string, string>() { [K2] = V2, [K1] = V1 });
var bc4 = new Baggage(new Dictionary<string, string>() { [K1] = V1, [K2] = V1 });
var bc5 = new Baggage(new Dictionary<string, string>() { [K1] = V2, [K2] = V1 });
Assert.True(bc1.Equals(bc2));
Assert.False(bc1.Equals(bc3));
Assert.False(bc1.Equals(bc4));
Assert.False(bc2.Equals(bc4));
Assert.False(bc3.Equals(bc4));
Assert.False(bc5.Equals(bc4));
Assert.False(bc4.Equals(bc5));
}
[Fact]
public void CreateBaggageTest()
{
var baggage = Baggage.Create(null);
Assert.Equal(default, baggage);
baggage = Baggage.Create(new Dictionary<string, string>
{
[K1] = V1,
["key2"] = "value2",
["KEY2"] = "VALUE2",
["KEY3"] = "VALUE3",
["Key3"] = null,
});
Assert.Equal(2, baggage.Count);
Assert.Contains(baggage.GetBaggage(), kvp => kvp.Key == K1);
Assert.Equal("VALUE2", Baggage.GetBaggage("key2", baggage));
}
[Fact]
public void EqualityTests()
{
var emptyBaggage = Baggage.Create(null);
var baggage = Baggage.SetBaggage(K1, V1);
Assert.NotEqual(emptyBaggage, baggage);
Assert.True(emptyBaggage != baggage);
baggage = Baggage.ClearBaggage(baggage);
Assert.Equal(emptyBaggage, baggage);
baggage = Baggage.SetBaggage(K1, V1);
var baggage2 = Baggage.SetBaggage(null);
Assert.Equal(baggage, baggage2);
Assert.False(baggage.Equals(this));
Assert.True(baggage.Equals((object)baggage2));
}
[Fact]
public void GetHashCodeTests()
{
var baggage = Baggage.Current;
var emptyBaggage = Baggage.Create(null);
Assert.Equal(emptyBaggage.GetHashCode(), baggage.GetHashCode());
baggage = Baggage.SetBaggage(K1, V1, baggage);
Assert.NotEqual(emptyBaggage.GetHashCode(), baggage.GetHashCode());
var expectedBaggage = Baggage.Create(new Dictionary<string, string> { [K1] = V1 });
Assert.Equal(expectedBaggage.GetHashCode(), baggage.GetHashCode());
}
}
}

View File

@ -1,148 +0,0 @@
// <copyright file="CorrelationContextTest.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.Collections.Generic;
using System.Diagnostics;
using Xunit;
namespace OpenTelemetry.Context.Tests
{
public class CorrelationContextTest
{
private const string K1 = "Key1";
private const string K2 = "Key2";
private const string V1 = "Value1";
private const string V2 = "Value2";
[Fact]
public void EmptyContext()
{
var cc = CorrelationContext.Current;
Assert.Empty(cc.Correlations);
Assert.Equal(CorrelationContext.Empty, cc);
cc.AddCorrelation(K1, V1);
Assert.Empty(cc.Correlations);
Assert.Null(cc.GetCorrelation(K1));
}
[Fact]
public void NonEmptyContext()
{
using Activity activity = new Activity("TestActivity");
activity.Start();
var list = new List<KeyValuePair<string, string>>(2)
{
new KeyValuePair<string, string>(K1, V1),
new KeyValuePair<string, string>(K2, V2),
};
var cc = CorrelationContext.Current;
cc.AddCorrelation(K1, V1);
cc.AddCorrelation(K2, V2);
Assert.NotEqual(CorrelationContext.Empty, cc);
Assert.Equal(list, cc.Correlations);
Assert.Equal(V1, cc.GetCorrelation(K1));
Assert.Null(cc.GetCorrelation(K1.ToLower()));
Assert.Null(cc.GetCorrelation(K1.ToUpper()));
Assert.Null(cc.GetCorrelation("NO_KEY"));
}
[Fact]
public void AddExistingKey()
{
using Activity activity = new Activity("TestActivity");
activity.Start();
var list = new List<KeyValuePair<string, string>>(2)
{
new KeyValuePair<string, string>(K1, V1),
new KeyValuePair<string, string>(K1, V1),
};
var cc = CorrelationContext.Current;
cc.AddCorrelation(K1, V1);
cc.AddCorrelation(K1, V1);
Assert.Equal(list, cc.Correlations);
}
[Fact]
public void TestIterator()
{
using Activity activity = new Activity("TestActivity");
activity.Start();
var list = new List<KeyValuePair<string, string>>(2)
{
new KeyValuePair<string, string>(K1, V1),
new KeyValuePair<string, string>(K2, V2),
};
var cc = CorrelationContext.Current;
cc.AddCorrelation(K1, V1);
cc.AddCorrelation(K2, V2);
var i = cc.Correlations.GetEnumerator();
Assert.True(i.MoveNext());
var tag1 = i.Current;
Assert.True(i.MoveNext());
var tag2 = i.Current;
Assert.False(i.MoveNext());
Assert.Equal(list, new List<KeyValuePair<string, string>> { tag1, tag2 });
}
[Fact]
public void TestEquals()
{
var cc1 = CreateCorrelationContext(new KeyValuePair<string, string>(K1, V1), new KeyValuePair<string, string>(K2, V2));
var cc2 = CreateCorrelationContext(new KeyValuePair<string, string>(K1, V1), new KeyValuePair<string, string>(K2, V2));
var cc3 = CreateCorrelationContext(new KeyValuePair<string, string>(K2, V2), new KeyValuePair<string, string>(K1, V1));
var cc4 = CreateCorrelationContext(new KeyValuePair<string, string>(K1, V1), new KeyValuePair<string, string>(K2, V1));
var cc5 = CreateCorrelationContext(new KeyValuePair<string, string>(K1, V2), new KeyValuePair<string, string>(K2, V1));
Assert.True(cc1.Equals(cc2));
Assert.False(cc1.Equals(cc3));
Assert.False(cc1.Equals(cc4));
Assert.False(cc2.Equals(cc4));
Assert.False(cc3.Equals(cc4));
Assert.False(cc5.Equals(cc4));
Assert.False(cc4.Equals(cc5));
}
private static CorrelationContext CreateCorrelationContext(params KeyValuePair<string, string>[] correlations)
{
using Activity activity = new Activity("TestActivity");
activity.Start();
var cc = CorrelationContext.Current;
cc.AddCorrelation(correlations);
return cc;
}
}
}

View File

@ -56,7 +56,7 @@ namespace OpenTelemetry.Context.Propagation.Tests
public void Serialize_SampledContext() public void Serialize_SampledContext()
{ {
var carrier = new Dictionary<string, string>(); var carrier = new Dictionary<string, string>();
this.b3Format.Inject(new PropagationContext(new ActivityContext(TraceId, SpanId, TraceOptions), null), carrier, Setter); this.b3Format.Inject(new PropagationContext(new ActivityContext(TraceId, SpanId, TraceOptions), default), carrier, Setter);
this.ContainsExactly(carrier, new Dictionary<string, string> { { B3Format.XB3TraceId, TraceIdBase16 }, { B3Format.XB3SpanId, SpanIdBase16 }, { B3Format.XB3Sampled, "1" } }); this.ContainsExactly(carrier, new Dictionary<string, string> { { B3Format.XB3TraceId, TraceIdBase16 }, { B3Format.XB3SpanId, SpanIdBase16 }, { B3Format.XB3Sampled, "1" } });
} }
@ -66,7 +66,7 @@ namespace OpenTelemetry.Context.Propagation.Tests
var carrier = new Dictionary<string, string>(); var carrier = new Dictionary<string, string>();
var context = new ActivityContext(TraceId, SpanId, ActivityTraceFlags.None); var context = new ActivityContext(TraceId, SpanId, ActivityTraceFlags.None);
this.output.WriteLine(context.ToString()); this.output.WriteLine(context.ToString());
this.b3Format.Inject(new PropagationContext(context, null), carrier, Setter); this.b3Format.Inject(new PropagationContext(context, default), carrier, Setter);
this.ContainsExactly(carrier, new Dictionary<string, string> { { B3Format.XB3TraceId, TraceIdBase16 }, { B3Format.XB3SpanId, SpanIdBase16 } }); this.ContainsExactly(carrier, new Dictionary<string, string> { { B3Format.XB3TraceId, TraceIdBase16 }, { B3Format.XB3SpanId, SpanIdBase16 } });
} }
@ -78,7 +78,7 @@ namespace OpenTelemetry.Context.Propagation.Tests
{ B3Format.XB3TraceId, TraceIdBase16 }, { B3Format.XB3SpanId, SpanIdBase16 }, { B3Format.XB3TraceId, TraceIdBase16 }, { B3Format.XB3SpanId, SpanIdBase16 },
}; };
var spanContext = new ActivityContext(TraceId, SpanId, ActivityTraceFlags.None); var spanContext = new ActivityContext(TraceId, SpanId, ActivityTraceFlags.None);
Assert.Equal(new PropagationContext(spanContext, null), this.b3Format.Extract(default, headersNotSampled, Getter)); Assert.Equal(new PropagationContext(spanContext, default), this.b3Format.Extract(default, headersNotSampled, Getter));
} }
[Fact] [Fact]
@ -89,7 +89,7 @@ namespace OpenTelemetry.Context.Propagation.Tests
{ B3Format.XB3TraceId, TraceIdBase16 }, { B3Format.XB3SpanId, SpanIdBase16 }, { B3Format.XB3Sampled, "1" }, { B3Format.XB3TraceId, TraceIdBase16 }, { B3Format.XB3SpanId, SpanIdBase16 }, { B3Format.XB3Sampled, "1" },
}; };
var activityContext = new ActivityContext(TraceId, SpanId, TraceOptions); var activityContext = new ActivityContext(TraceId, SpanId, TraceOptions);
Assert.Equal(new PropagationContext(activityContext, null), this.b3Format.Extract(default, headersSampled, Getter)); Assert.Equal(new PropagationContext(activityContext, default), this.b3Format.Extract(default, headersSampled, Getter));
} }
[Fact] [Fact]
@ -100,7 +100,7 @@ namespace OpenTelemetry.Context.Propagation.Tests
{ B3Format.XB3TraceId, TraceIdBase16 }, { B3Format.XB3SpanId, SpanIdBase16 }, { B3Format.XB3Sampled, "0" }, { B3Format.XB3TraceId, TraceIdBase16 }, { B3Format.XB3SpanId, SpanIdBase16 }, { B3Format.XB3Sampled, "0" },
}; };
var activityContext = new ActivityContext(TraceId, SpanId, ActivityTraceFlags.None); var activityContext = new ActivityContext(TraceId, SpanId, ActivityTraceFlags.None);
Assert.Equal(new PropagationContext(activityContext, null), this.b3Format.Extract(default, headersNotSampled, Getter)); Assert.Equal(new PropagationContext(activityContext, default), this.b3Format.Extract(default, headersNotSampled, Getter));
} }
[Fact] [Fact]
@ -111,7 +111,7 @@ namespace OpenTelemetry.Context.Propagation.Tests
{ B3Format.XB3TraceId, TraceIdBase16 }, { B3Format.XB3SpanId, SpanIdBase16 }, { B3Format.XB3Flags, "1" }, { B3Format.XB3TraceId, TraceIdBase16 }, { B3Format.XB3SpanId, SpanIdBase16 }, { B3Format.XB3Flags, "1" },
}; };
var activityContext = new ActivityContext(TraceId, SpanId, TraceOptions); var activityContext = new ActivityContext(TraceId, SpanId, TraceOptions);
Assert.Equal(new PropagationContext(activityContext, null), this.b3Format.Extract(default, headersFlagSampled, Getter)); Assert.Equal(new PropagationContext(activityContext, default), this.b3Format.Extract(default, headersFlagSampled, Getter));
} }
[Fact] [Fact]
@ -122,7 +122,7 @@ namespace OpenTelemetry.Context.Propagation.Tests
{ B3Format.XB3TraceId, TraceIdBase16 }, { B3Format.XB3SpanId, SpanIdBase16 }, { B3Format.XB3Flags, "0" }, { B3Format.XB3TraceId, TraceIdBase16 }, { B3Format.XB3SpanId, SpanIdBase16 }, { B3Format.XB3Flags, "0" },
}; };
var activityContext = new ActivityContext(TraceId, SpanId, ActivityTraceFlags.None); var activityContext = new ActivityContext(TraceId, SpanId, ActivityTraceFlags.None);
Assert.Equal(new PropagationContext(activityContext, null), this.b3Format.Extract(default, headersFlagNotSampled, Getter)); Assert.Equal(new PropagationContext(activityContext, default), this.b3Format.Extract(default, headersFlagNotSampled, Getter));
} }
[Fact] [Fact]
@ -135,7 +135,7 @@ namespace OpenTelemetry.Context.Propagation.Tests
{ B3Format.XB3Sampled, "1" }, { B3Format.XB3Sampled, "1" },
}; };
var activityContext = new ActivityContext(TraceIdEightBytes, SpanId, TraceOptions); var activityContext = new ActivityContext(TraceIdEightBytes, SpanId, TraceOptions);
Assert.Equal(new PropagationContext(activityContext, null), this.b3Format.Extract(default, headersEightBytes, Getter)); Assert.Equal(new PropagationContext(activityContext, default), this.b3Format.Extract(default, headersEightBytes, Getter));
} }
[Fact] [Fact]
@ -146,7 +146,7 @@ namespace OpenTelemetry.Context.Propagation.Tests
{ B3Format.XB3TraceId, TraceIdBase16EightBytes }, { B3Format.XB3SpanId, SpanIdBase16 }, { B3Format.XB3TraceId, TraceIdBase16EightBytes }, { B3Format.XB3SpanId, SpanIdBase16 },
}; };
var activityContext = new ActivityContext(TraceIdEightBytes, SpanId, ActivityTraceFlags.None); var activityContext = new ActivityContext(TraceIdEightBytes, SpanId, ActivityTraceFlags.None);
Assert.Equal(new PropagationContext(activityContext, null), this.b3Format.Extract(default, headersEightBytes, Getter)); Assert.Equal(new PropagationContext(activityContext, default), this.b3Format.Extract(default, headersEightBytes, Getter));
} }
[Fact] [Fact]
@ -209,7 +209,7 @@ namespace OpenTelemetry.Context.Propagation.Tests
{ {
var carrier = new Dictionary<string, string>(); var carrier = new Dictionary<string, string>();
var activityContext = new ActivityContext(TraceId, SpanId, TraceOptions); var activityContext = new ActivityContext(TraceId, SpanId, TraceOptions);
this.b3FormatSingleHeader.Inject(new PropagationContext(activityContext, null), carrier, Setter); this.b3FormatSingleHeader.Inject(new PropagationContext(activityContext, default), carrier, Setter);
this.ContainsExactly(carrier, new Dictionary<string, string> { { B3Format.XB3Combined, $"{TraceIdBase16}-{SpanIdBase16}-1" } }); this.ContainsExactly(carrier, new Dictionary<string, string> { { B3Format.XB3Combined, $"{TraceIdBase16}-{SpanIdBase16}-1" } });
} }
@ -219,7 +219,7 @@ namespace OpenTelemetry.Context.Propagation.Tests
var carrier = new Dictionary<string, string>(); var carrier = new Dictionary<string, string>();
var activityContext = new ActivityContext(TraceId, SpanId, ActivityTraceFlags.None); var activityContext = new ActivityContext(TraceId, SpanId, ActivityTraceFlags.None);
this.output.WriteLine(activityContext.ToString()); this.output.WriteLine(activityContext.ToString());
this.b3FormatSingleHeader.Inject(new PropagationContext(activityContext, null), carrier, Setter); this.b3FormatSingleHeader.Inject(new PropagationContext(activityContext, default), carrier, Setter);
this.ContainsExactly(carrier, new Dictionary<string, string> { { B3Format.XB3Combined, $"{TraceIdBase16}-{SpanIdBase16}" } }); this.ContainsExactly(carrier, new Dictionary<string, string> { { B3Format.XB3Combined, $"{TraceIdBase16}-{SpanIdBase16}" } });
} }
@ -231,7 +231,7 @@ namespace OpenTelemetry.Context.Propagation.Tests
{ B3Format.XB3Combined, $"{TraceIdBase16}-{SpanIdBase16}" }, { B3Format.XB3Combined, $"{TraceIdBase16}-{SpanIdBase16}" },
}; };
var activityContext = new ActivityContext(TraceId, SpanId, ActivityTraceFlags.None); var activityContext = new ActivityContext(TraceId, SpanId, ActivityTraceFlags.None);
Assert.Equal(new PropagationContext(activityContext, null), this.b3FormatSingleHeader.Extract(default, headersNotSampled, Getter)); Assert.Equal(new PropagationContext(activityContext, default), this.b3FormatSingleHeader.Extract(default, headersNotSampled, Getter));
} }
[Fact] [Fact]
@ -243,7 +243,7 @@ namespace OpenTelemetry.Context.Propagation.Tests
}; };
Assert.Equal( Assert.Equal(
new PropagationContext(new ActivityContext(TraceId, SpanId, TraceOptions), null), new PropagationContext(new ActivityContext(TraceId, SpanId, TraceOptions), default),
this.b3FormatSingleHeader.Extract(default, headersSampled, Getter)); this.b3FormatSingleHeader.Extract(default, headersSampled, Getter));
} }
@ -256,7 +256,7 @@ namespace OpenTelemetry.Context.Propagation.Tests
}; };
Assert.Equal( Assert.Equal(
new PropagationContext(new ActivityContext(TraceId, SpanId, ActivityTraceFlags.None), null), new PropagationContext(new ActivityContext(TraceId, SpanId, ActivityTraceFlags.None), default),
this.b3FormatSingleHeader.Extract(default, headersNotSampled, Getter)); this.b3FormatSingleHeader.Extract(default, headersNotSampled, Getter));
} }
@ -268,7 +268,7 @@ namespace OpenTelemetry.Context.Propagation.Tests
{ B3Format.XB3Combined, $"{TraceIdBase16}-{SpanIdBase16}-1" }, { B3Format.XB3Combined, $"{TraceIdBase16}-{SpanIdBase16}-1" },
}; };
var activityContext = new ActivityContext(TraceId, SpanId, TraceOptions); var activityContext = new ActivityContext(TraceId, SpanId, TraceOptions);
Assert.Equal(new PropagationContext(activityContext, null), this.b3FormatSingleHeader.Extract(default, headersFlagSampled, Getter)); Assert.Equal(new PropagationContext(activityContext, default), this.b3FormatSingleHeader.Extract(default, headersFlagSampled, Getter));
} }
[Fact] [Fact]
@ -279,7 +279,7 @@ namespace OpenTelemetry.Context.Propagation.Tests
{ B3Format.XB3Combined, $"{TraceIdBase16}-{SpanIdBase16}-0" }, { B3Format.XB3Combined, $"{TraceIdBase16}-{SpanIdBase16}-0" },
}; };
var activityContext = new ActivityContext(TraceId, SpanId, ActivityTraceFlags.None); var activityContext = new ActivityContext(TraceId, SpanId, ActivityTraceFlags.None);
Assert.Equal(new PropagationContext(activityContext, null), this.b3FormatSingleHeader.Extract(default, headersFlagNotSampled, Getter)); Assert.Equal(new PropagationContext(activityContext, default), this.b3FormatSingleHeader.Extract(default, headersFlagNotSampled, Getter));
} }
[Fact] [Fact]
@ -290,7 +290,7 @@ namespace OpenTelemetry.Context.Propagation.Tests
{ B3Format.XB3Combined, $"{TraceIdBase16EightBytes}-{SpanIdBase16}-1" }, { B3Format.XB3Combined, $"{TraceIdBase16EightBytes}-{SpanIdBase16}-1" },
}; };
var activityContext = new ActivityContext(TraceIdEightBytes, SpanId, TraceOptions); var activityContext = new ActivityContext(TraceIdEightBytes, SpanId, TraceOptions);
Assert.Equal(new PropagationContext(activityContext, null), this.b3FormatSingleHeader.Extract(default, headersEightBytes, Getter)); Assert.Equal(new PropagationContext(activityContext, default), this.b3FormatSingleHeader.Extract(default, headersEightBytes, Getter));
} }
[Fact] [Fact]
@ -301,7 +301,7 @@ namespace OpenTelemetry.Context.Propagation.Tests
{ B3Format.XB3Combined, $"{TraceIdBase16EightBytes}-{SpanIdBase16}" }, { B3Format.XB3Combined, $"{TraceIdBase16EightBytes}-{SpanIdBase16}" },
}; };
var activityContext = new ActivityContext(TraceIdEightBytes, SpanId, ActivityTraceFlags.None); var activityContext = new ActivityContext(TraceIdEightBytes, SpanId, ActivityTraceFlags.None);
Assert.Equal(new PropagationContext(activityContext, null), this.b3FormatSingleHeader.Extract(default, headersEightBytes, Getter)); Assert.Equal(new PropagationContext(activityContext, default), this.b3FormatSingleHeader.Extract(default, headersEightBytes, Getter));
} }
[Fact] [Fact]

View File

@ -81,12 +81,12 @@ namespace OpenTelemetry.Context.Propagation.Tests
}; };
var propagationContext = this.baggage.Extract(default, carrier, Getter); var propagationContext = this.baggage.Extract(default, carrier, Getter);
Assert.False(propagationContext == default); Assert.False(propagationContext == default);
Assert.Single(propagationContext.ActivityBaggage); Assert.Single(propagationContext.Baggage.GetBaggage());
var array = propagationContext.ActivityBaggage.ToArray(); var baggage = propagationContext.Baggage.GetBaggage().FirstOrDefault();
Assert.Equal("name", array[0].Key); Assert.Equal("name", baggage.Key);
Assert.Equal("test", array[0].Value); Assert.Equal("test", baggage.Value);
} }
[Fact] [Fact]
@ -104,9 +104,9 @@ namespace OpenTelemetry.Context.Propagation.Tests
Assert.False(propagationContext == default); Assert.False(propagationContext == default);
Assert.True(propagationContext.ActivityContext == default); Assert.True(propagationContext.ActivityContext == default);
Assert.Equal(2, propagationContext.ActivityBaggage.Count()); Assert.Equal(2, propagationContext.Baggage.Count);
var array = propagationContext.ActivityBaggage.ToArray(); var array = propagationContext.Baggage.GetBaggage().ToArray();
Assert.Equal("name1", array[0].Key); Assert.Equal("name1", array[0].Key);
Assert.Equal("test1", array[0].Value); Assert.Equal("test1", array[0].Value);
@ -124,9 +124,9 @@ namespace OpenTelemetry.Context.Propagation.Tests
}; };
var propagationContext = this.baggage.Extract(default, carrier, Getter); var propagationContext = this.baggage.Extract(default, carrier, Getter);
Assert.False(propagationContext == default); Assert.False(propagationContext == default);
Assert.Single(propagationContext.ActivityBaggage); Assert.Single(propagationContext.Baggage.GetBaggage());
var array = propagationContext.ActivityBaggage.ToArray(); var array = propagationContext.Baggage.GetBaggage().ToArray();
Assert.Equal("name", array[0].Key); Assert.Equal("name", array[0].Key);
Assert.Equal(new string('x', 8186), array[0].Value); Assert.Equal(new string('x', 8186), array[0].Value);
@ -145,11 +145,13 @@ namespace OpenTelemetry.Context.Propagation.Tests
public void ValidateBaggageInjection() public void ValidateBaggageInjection()
{ {
var carrier = new Dictionary<string, string>(); var carrier = new Dictionary<string, string>();
var propagationContext = new PropagationContext(default, new Dictionary<string, string> var propagationContext = new PropagationContext(
{ default,
{ "key1", "value1" }, new Baggage(new Dictionary<string, string>
{ "key2", "value2" }, {
}); { "key1", "value1" },
{ "key2", "value2" },
}));
this.baggage.Inject(propagationContext, carrier, Setter); this.baggage.Inject(propagationContext, carrier, Setter);

View File

@ -62,7 +62,7 @@ namespace OpenTelemetry.Context.Propagation.Tests
}); });
var activityContext = new ActivityContext(this.traceId, this.spanId, ActivityTraceFlags.Recorded, traceState: null); var activityContext = new ActivityContext(this.traceId, this.spanId, ActivityTraceFlags.Recorded, traceState: null);
PropagationContext propagationContext = new PropagationContext(activityContext, null); PropagationContext propagationContext = new PropagationContext(activityContext, default);
var carrier = new Dictionary<string, string>(); var carrier = new Dictionary<string, string>();
var activity = new Activity("test"); var activity = new Activity("test");
@ -84,7 +84,7 @@ namespace OpenTelemetry.Context.Propagation.Tests
}); });
var activityContext = new ActivityContext(this.traceId, this.spanId, ActivityTraceFlags.Recorded, traceState: null); var activityContext = new ActivityContext(this.traceId, this.spanId, ActivityTraceFlags.Recorded, traceState: null);
PropagationContext propagationContext = new PropagationContext(activityContext, null); PropagationContext propagationContext = new PropagationContext(activityContext, default);
var carrier = new Dictionary<string, string>(); var carrier = new Dictionary<string, string>();
@ -115,9 +115,9 @@ namespace OpenTelemetry.Context.Propagation.Tests
var activityContext = new ActivityContext(this.traceId, this.spanId, ActivityTraceFlags.Recorded, traceState: null, isRemote: true); var activityContext = new ActivityContext(this.traceId, this.spanId, ActivityTraceFlags.Recorded, traceState: null, isRemote: true);
var baggage = new Dictionary<string, string> { ["key1"] = "value1" }; var baggage = new Dictionary<string, string> { ["key1"] = "value1" };
PropagationContext propagationContextActivityOnly = new PropagationContext(activityContext, null); PropagationContext propagationContextActivityOnly = new PropagationContext(activityContext, default);
PropagationContext propagationContextBaggageOnly = new PropagationContext(default, baggage); PropagationContext propagationContextBaggageOnly = new PropagationContext(default, new Baggage(baggage));
PropagationContext propagationContextBoth = new PropagationContext(activityContext, baggage); PropagationContext propagationContextBoth = new PropagationContext(activityContext, new Baggage(baggage));
var carrier = new Dictionary<string, string>(); var carrier = new Dictionary<string, string>();
compositePropagator.Inject(propagationContextActivityOnly, carrier, Setter); compositePropagator.Inject(propagationContextActivityOnly, carrier, Setter);

View File

@ -64,7 +64,7 @@ namespace OpenTelemetry.Context.Propagation.Tests
return new PropagationContext( return new PropagationContext(
new ActivityContext(traceId, spanId, traceoptions, tracestate), new ActivityContext(traceId, spanId, traceoptions, tracestate),
context.ActivityBaggage); context.Baggage);
} }
public void Inject<T>(PropagationContext context, T carrier, Action<T, string, string> setter) public void Inject<T>(PropagationContext context, T carrier, Action<T, string, string> setter)

View File

@ -149,7 +149,7 @@ namespace OpenTelemetry.Context.Propagation.Tests
}; };
var activityContext = new ActivityContext(traceId, spanId, ActivityTraceFlags.Recorded, traceState: null); var activityContext = new ActivityContext(traceId, spanId, ActivityTraceFlags.Recorded, traceState: null);
PropagationContext propagationContext = new PropagationContext(activityContext, null); PropagationContext propagationContext = new PropagationContext(activityContext, default);
var carrier = new Dictionary<string, string>(); var carrier = new Dictionary<string, string>();
var f = new TraceContextFormat(); var f = new TraceContextFormat();
f.Inject(propagationContext, carrier, Setter); f.Inject(propagationContext, carrier, Setter);
@ -169,7 +169,7 @@ namespace OpenTelemetry.Context.Propagation.Tests
}; };
var activityContext = new ActivityContext(traceId, spanId, ActivityTraceFlags.Recorded, expectedHeaders[TraceState]); var activityContext = new ActivityContext(traceId, spanId, ActivityTraceFlags.Recorded, expectedHeaders[TraceState]);
PropagationContext propagationContext = new PropagationContext(activityContext, null); PropagationContext propagationContext = new PropagationContext(activityContext, default);
var carrier = new Dictionary<string, string>(); var carrier = new Dictionary<string, string>();
var f = new TraceContextFormat(); var f = new TraceContextFormat();
f.Inject(propagationContext, carrier, Setter); f.Inject(propagationContext, carrier, Setter);