Cleaning Jaeger Exporter (#832)
Updating tests removing JaegerConversionExtensions renaming methods Fixed up Jaeger unit tests and status code helper. removing unused references
This commit is contained in:
parent
b91b2bc9f5
commit
595f8c2379
|
|
@ -24,6 +24,7 @@ using System.Threading.Tasks;
|
|||
using BenchmarkDotNet.Attributes;
|
||||
using OpenTelemetry.Exporter.Jaeger;
|
||||
using OpenTelemetry.Exporter.Jaeger.Implementation;
|
||||
using OpenTelemetry.Trace;
|
||||
using Thrift.Transport;
|
||||
|
||||
namespace Benchmarks.Exporter
|
||||
|
|
@ -149,23 +150,22 @@ namespace Benchmarks.Exporter
|
|||
|
||||
private Activity CreateTestActivity()
|
||||
{
|
||||
var startTimestamp = DateTime.UtcNow;
|
||||
var startTimestamp = new DateTimeOffset(2019, 1, 1, 0, 0, 0, TimeSpan.Zero);
|
||||
var endTimestamp = startTimestamp.AddSeconds(60);
|
||||
var eventTimestamp = DateTime.UtcNow;
|
||||
var eventTimestamp = new DateTimeOffset(2019, 1, 1, 0, 0, 0, TimeSpan.Zero);
|
||||
|
||||
var traceId = ActivityTraceId.CreateFromString("e8ea7e9ac72de94e91fabc613f9686b2".AsSpan());
|
||||
|
||||
var spanId = ActivitySpanId.CreateFromString("6a69db47429ea340".AsSpan());
|
||||
var parentSpanId = ActivitySpanId.CreateFromBytes(new byte[] { 12, 23, 34, 45, 56, 67, 78, 89 });
|
||||
|
||||
var attributes = new Dictionary<string, object>
|
||||
{
|
||||
{ "stringKey", "value" },
|
||||
{ "longKey", 1L },
|
||||
{ "longKey2", 1L },
|
||||
{ "doubleKey", 1D },
|
||||
{ "doubleKey2", 1F },
|
||||
{ "boolKey", true },
|
||||
{ "stringKey", "value"},
|
||||
{ "longKey", 1L},
|
||||
{ "longKey2", 1 },
|
||||
{ "doubleKey", 1D},
|
||||
{ "doubleKey2", 1F},
|
||||
{ "boolKey", true},
|
||||
};
|
||||
|
||||
var events = new List<ActivityEvent>
|
||||
{
|
||||
new ActivityEvent(
|
||||
|
|
@ -174,14 +174,16 @@ namespace Benchmarks.Exporter
|
|||
new Dictionary<string, object>
|
||||
{
|
||||
{ "key", "value" },
|
||||
}),
|
||||
}
|
||||
),
|
||||
new ActivityEvent(
|
||||
"Event2",
|
||||
eventTimestamp,
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
{ "key", "value" },
|
||||
}),
|
||||
}
|
||||
),
|
||||
};
|
||||
|
||||
var linkedSpanId = ActivitySpanId.CreateFromString("888915b6286b9c41".AsSpan());
|
||||
|
|
@ -189,31 +191,21 @@ namespace Benchmarks.Exporter
|
|||
var activitySource = new ActivitySource(nameof(CreateTestActivity));
|
||||
|
||||
var tags = attributes.Select(kvp => new KeyValuePair<string, string>(kvp.Key, kvp.Value.ToString()));
|
||||
var links = new[]
|
||||
{
|
||||
new ActivityLink(new ActivityContext(
|
||||
traceId,
|
||||
linkedSpanId,
|
||||
ActivityTraceFlags.Recorded)),
|
||||
};
|
||||
|
||||
var activity = activitySource.StartActivity(
|
||||
var links = new[] {
|
||||
new ActivityLink(new ActivityContext(
|
||||
traceId,
|
||||
linkedSpanId,
|
||||
ActivityTraceFlags.Recorded)),
|
||||
};
|
||||
|
||||
return activitySource.StartActivity(
|
||||
"Name",
|
||||
ActivityKind.Client,
|
||||
parentContext: new ActivityContext(traceId, parentSpanId, ActivityTraceFlags.Recorded),
|
||||
tags,
|
||||
links,
|
||||
startTime: startTimestamp);
|
||||
|
||||
foreach (var evnt in events)
|
||||
{
|
||||
activity.AddEvent(evnt);
|
||||
}
|
||||
|
||||
activity.SetEndTime(endTimestamp);
|
||||
activity.Stop();
|
||||
|
||||
return activity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,10 @@ namespace OpenTelemetry.Trace
|
|||
}
|
||||
|
||||
activity.AddTag(SpanAttributeConstants.StatusCodeKey, SpanHelper.GetCachedCanonicalCodeString(status.CanonicalCode));
|
||||
activity.AddTag(SpanAttributeConstants.StatusDescriptionKey, status.Description);
|
||||
if (!string.IsNullOrEmpty(status.Description))
|
||||
{
|
||||
activity.AddTag(SpanAttributeConstants.StatusDescriptionKey, status.Description);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -62,7 +65,13 @@ namespace OpenTelemetry.Trace
|
|||
var statusDescription = activity.Tags.FirstOrDefault(d => d.Key == SpanAttributeConstants.StatusDescriptionKey).Value;
|
||||
|
||||
var status = SpanHelper.ResolveCanonicalCodeToStatus(statusCanonicalCode);
|
||||
return status.IsValid ? status.WithDescription(statusDescription) : status;
|
||||
|
||||
if (status.IsValid && !string.IsNullOrEmpty(statusDescription))
|
||||
{
|
||||
return status.WithDescription(statusDescription);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,24 @@ namespace OpenTelemetry.Exporter.Jaeger.Implementation
|
|||
{
|
||||
internal static class JaegerActivityExtensions
|
||||
{
|
||||
private const int DaysPerYear = 365;
|
||||
|
||||
// Number of days in 4 years
|
||||
private const int DaysPer4Years = (DaysPerYear * 4) + 1; // 1461
|
||||
|
||||
// Number of days in 100 years
|
||||
private const int DaysPer100Years = (DaysPer4Years * 25) - 1; // 36524
|
||||
|
||||
// Number of days in 400 years
|
||||
private const int DaysPer400Years = (DaysPer100Years * 4) + 1; // 146097
|
||||
|
||||
// Number of days from 1/1/0001 to 12/31/1969
|
||||
private const int DaysTo1970 = (DaysPer400Years * 4) + (DaysPer100Years * 3) + (DaysPer4Years * 17) + DaysPerYear; // 719,162
|
||||
|
||||
private const long UnixEpochTicks = DaysTo1970 * TimeSpan.TicksPerDay;
|
||||
private const long TicksPerMicrosecond = TimeSpan.TicksPerMillisecond / 1000;
|
||||
private const long UnixEpochMicroseconds = UnixEpochTicks / TicksPerMicrosecond; // 62,135,596,800,000,000
|
||||
|
||||
private static readonly Dictionary<string, int> PeerServiceKeyResolutionDictionary = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
[SemanticConventions.AttributePeerService] = 0, // priority 0 (highest).
|
||||
|
|
@ -194,6 +212,27 @@ namespace OpenTelemetry.Exporter.Jaeger.Implementation
|
|||
return new JaegerSpanRef(JaegerSpanRefType.CHILD_OF, traceId.Low, traceId.High, spanId.Low);
|
||||
}
|
||||
|
||||
public static JaegerTag ToJaegerTag(this KeyValuePair<string, object> attribute)
|
||||
{
|
||||
switch (attribute.Value)
|
||||
{
|
||||
case string s:
|
||||
return new JaegerTag(attribute.Key, JaegerTagType.STRING, vStr: s);
|
||||
case int i:
|
||||
return new JaegerTag(attribute.Key, JaegerTagType.LONG, vLong: Convert.ToInt64(i));
|
||||
case long l:
|
||||
return new JaegerTag(attribute.Key, JaegerTagType.LONG, vLong: l);
|
||||
case float f:
|
||||
return new JaegerTag(attribute.Key, JaegerTagType.DOUBLE, vDouble: Convert.ToDouble(f));
|
||||
case double d:
|
||||
return new JaegerTag(attribute.Key, JaegerTagType.DOUBLE, vDouble: d);
|
||||
case bool b:
|
||||
return new JaegerTag(attribute.Key, JaegerTagType.BOOL, vBool: b);
|
||||
}
|
||||
|
||||
return new JaegerTag(attribute.Key, JaegerTagType.STRING, vStr: attribute.Value.ToString());
|
||||
}
|
||||
|
||||
public static long ToEpochMicroseconds(this DateTime utcDateTime)
|
||||
{
|
||||
const long TicksPerMicrosecond = TimeSpan.TicksPerMillisecond / 1000;
|
||||
|
|
@ -206,6 +245,14 @@ namespace OpenTelemetry.Exporter.Jaeger.Implementation
|
|||
return microseconds - UnixEpochMicroseconds;
|
||||
}
|
||||
|
||||
public static long ToEpochMicroseconds(this DateTimeOffset timestamp)
|
||||
{
|
||||
// Truncate sub-microsecond precision before offsetting by the Unix Epoch to avoid
|
||||
// the last digit being off by one for dates that result in negative Unix times
|
||||
long microseconds = timestamp.UtcDateTime.Ticks / TicksPerMicrosecond;
|
||||
return microseconds - UnixEpochMicroseconds;
|
||||
}
|
||||
|
||||
private static bool ProcessActivityTag(ref TagState state, KeyValuePair<string, string> activityTag)
|
||||
{
|
||||
var jaegerTag = new JaegerTag(activityTag.Key, JaegerTagType.STRING, activityTag.Value);
|
||||
|
|
|
|||
|
|
@ -1,336 +0,0 @@
|
|||
// <copyright file="JaegerConversionExtensions.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 OpenTelemetry.Internal;
|
||||
using OpenTelemetry.Resources;
|
||||
using OpenTelemetry.Trace;
|
||||
using OpenTelemetry.Trace.Export;
|
||||
|
||||
namespace OpenTelemetry.Exporter.Jaeger.Implementation
|
||||
{
|
||||
internal static class JaegerConversionExtensions
|
||||
{
|
||||
private const int DaysPerYear = 365;
|
||||
|
||||
// Number of days in 4 years
|
||||
private const int DaysPer4Years = (DaysPerYear * 4) + 1; // 1461
|
||||
|
||||
// Number of days in 100 years
|
||||
private const int DaysPer100Years = (DaysPer4Years * 25) - 1; // 36524
|
||||
|
||||
// Number of days in 400 years
|
||||
private const int DaysPer400Years = (DaysPer100Years * 4) + 1; // 146097
|
||||
|
||||
// Number of days from 1/1/0001 to 12/31/1969
|
||||
private const int DaysTo1970 = (DaysPer400Years * 4) + (DaysPer100Years * 3) + (DaysPer4Years * 17) + DaysPerYear; // 719,162
|
||||
|
||||
private const long UnixEpochTicks = DaysTo1970 * TimeSpan.TicksPerDay;
|
||||
private const long TicksPerMicrosecond = TimeSpan.TicksPerMillisecond / 1000;
|
||||
private const long UnixEpochMicroseconds = UnixEpochTicks / TicksPerMicrosecond; // 62,135,596,800,000,000
|
||||
|
||||
private static readonly Dictionary<string, int> PeerServiceKeyResolutionDictionary = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
[SemanticConventions.AttributePeerService] = 0, // priority 0 (highest).
|
||||
[SemanticConventions.AttributeNetPeerName] = 1,
|
||||
[SemanticConventions.AttributeNetPeerIP] = 2,
|
||||
["peer.hostname"] = 2,
|
||||
["peer.address"] = 2,
|
||||
["http.host"] = 3, // peer.service for Http.
|
||||
["db.instance"] = 3, // peer.service for Redis.
|
||||
};
|
||||
|
||||
private static readonly DictionaryEnumerator<string, object, TagState>.ForEachDelegate ProcessAttributeRef = ProcessAttribute;
|
||||
private static readonly DictionaryEnumerator<string, object, TagState>.ForEachDelegate ProcessLibraryAttributeRef = ProcessLibraryAttribute;
|
||||
private static readonly ListEnumerator<Link, PooledListState<JaegerSpanRef>>.ForEachDelegate ProcessLinkRef = ProcessLink;
|
||||
private static readonly ListEnumerator<Event, PooledListState<JaegerLog>>.ForEachDelegate ProcessEventRef = ProcessEvent;
|
||||
private static readonly DictionaryEnumerator<string, object, PooledListState<JaegerTag>>.ForEachDelegate ProcessTagRef = ProcessTag;
|
||||
|
||||
public static JaegerSpan ToJaegerSpan(this SpanData span)
|
||||
{
|
||||
var jaegerTags = new TagState
|
||||
{
|
||||
Tags = PooledList<JaegerTag>.Create(),
|
||||
};
|
||||
|
||||
DictionaryEnumerator<string, object, TagState>.AllocationFreeForEach(
|
||||
span.Attributes,
|
||||
ref jaegerTags,
|
||||
ProcessAttributeRef);
|
||||
|
||||
string peerServiceName = null;
|
||||
if ((span.Kind == SpanKind.Client || span.Kind == SpanKind.Producer) && jaegerTags.PeerService != null)
|
||||
{
|
||||
// Send peer.service for remote calls.
|
||||
peerServiceName = jaegerTags.PeerService;
|
||||
|
||||
// If priority = 0 that means peer.service was already included in tags.
|
||||
if (jaegerTags.PeerServicePriority > 0)
|
||||
{
|
||||
PooledList<JaegerTag>.Add(ref jaegerTags.Tags, new JaegerTag(SemanticConventions.AttributePeerService, JaegerTagType.STRING, vStr: peerServiceName));
|
||||
}
|
||||
}
|
||||
|
||||
// The Span.Kind must translate into a tag.
|
||||
// See https://opentracing.io/specification/conventions/
|
||||
if (span.Kind.HasValue)
|
||||
{
|
||||
string spanKind = null;
|
||||
|
||||
if (span.Kind.Value == SpanKind.Server)
|
||||
{
|
||||
spanKind = "server";
|
||||
}
|
||||
else if (span.Kind.Value == SpanKind.Client)
|
||||
{
|
||||
spanKind = "client";
|
||||
}
|
||||
else if (span.Kind.Value == SpanKind.Consumer)
|
||||
{
|
||||
spanKind = "consumer";
|
||||
}
|
||||
else if (span.Kind.Value == SpanKind.Producer)
|
||||
{
|
||||
spanKind = "producer";
|
||||
}
|
||||
|
||||
if (spanKind != null)
|
||||
{
|
||||
PooledList<JaegerTag>.Add(ref jaegerTags.Tags, new JaegerTag("span.kind", JaegerTagType.STRING, vStr: spanKind));
|
||||
}
|
||||
}
|
||||
|
||||
DictionaryEnumerator<string, object, TagState>.AllocationFreeForEach(
|
||||
span.LibraryResource?.Attributes ?? Array.Empty<KeyValuePair<string, object>>(),
|
||||
ref jaegerTags,
|
||||
ProcessLibraryAttributeRef);
|
||||
|
||||
var status = span.Status;
|
||||
|
||||
if (status.IsValid)
|
||||
{
|
||||
PooledList<JaegerTag>.Add(ref jaegerTags.Tags, new JaegerTag(SpanAttributeConstants.StatusCodeKey, JaegerTagType.STRING, vStr: SpanHelper.GetCachedCanonicalCodeString(status.CanonicalCode)));
|
||||
|
||||
if (status.Description != null)
|
||||
{
|
||||
PooledList<JaegerTag>.Add(ref jaegerTags.Tags, new JaegerTag(SpanAttributeConstants.StatusDescriptionKey, JaegerTagType.STRING, vStr: status.Description));
|
||||
}
|
||||
}
|
||||
|
||||
var traceId = Int128.Empty;
|
||||
var spanId = Int128.Empty;
|
||||
var parentSpanId = Int128.Empty;
|
||||
|
||||
if (span.Context.IsValid)
|
||||
{
|
||||
traceId = new Int128(span.Context.TraceId);
|
||||
spanId = new Int128(span.Context.SpanId);
|
||||
parentSpanId = new Int128(span.ParentSpanId);
|
||||
}
|
||||
|
||||
return new JaegerSpan(
|
||||
peerServiceName: peerServiceName,
|
||||
traceIdLow: traceId.Low,
|
||||
traceIdHigh: traceId.High,
|
||||
spanId: spanId.Low,
|
||||
parentSpanId: parentSpanId.Low,
|
||||
operationName: span.Name,
|
||||
flags: (span.Context.TraceFlags & ActivityTraceFlags.Recorded) > 0 ? 0x1 : 0,
|
||||
startTime: ToEpochMicroseconds(span.StartTimestamp),
|
||||
duration: ToEpochMicroseconds(span.EndTimestamp) - ToEpochMicroseconds(span.StartTimestamp),
|
||||
references: span.Links.ToJaegerSpanRefs(),
|
||||
tags: jaegerTags.Tags,
|
||||
logs: span.Events.ToJaegerLogs());
|
||||
}
|
||||
|
||||
public static PooledList<JaegerSpanRef> ToJaegerSpanRefs(this IEnumerable<Link> links)
|
||||
{
|
||||
PooledListState<JaegerSpanRef> references = default;
|
||||
|
||||
if (links == null)
|
||||
{
|
||||
return references.List;
|
||||
}
|
||||
|
||||
ListEnumerator<Link, PooledListState<JaegerSpanRef>>.AllocationFreeForEach(
|
||||
links,
|
||||
ref references,
|
||||
ProcessLinkRef);
|
||||
|
||||
return references.List;
|
||||
}
|
||||
|
||||
public static PooledList<JaegerLog> ToJaegerLogs(this IEnumerable<Event> events)
|
||||
{
|
||||
PooledListState<JaegerLog> logs = default;
|
||||
|
||||
if (events == null)
|
||||
{
|
||||
return logs.List;
|
||||
}
|
||||
|
||||
ListEnumerator<Event, PooledListState<JaegerLog>>.AllocationFreeForEach(
|
||||
events,
|
||||
ref logs,
|
||||
ProcessEventRef);
|
||||
|
||||
return logs.List;
|
||||
}
|
||||
|
||||
public static JaegerTag ToJaegerTag(this KeyValuePair<string, object> attribute)
|
||||
{
|
||||
switch (attribute.Value)
|
||||
{
|
||||
case string s:
|
||||
return new JaegerTag(attribute.Key, JaegerTagType.STRING, vStr: s);
|
||||
case int i:
|
||||
return new JaegerTag(attribute.Key, JaegerTagType.LONG, vLong: Convert.ToInt64(i));
|
||||
case long l:
|
||||
return new JaegerTag(attribute.Key, JaegerTagType.LONG, vLong: l);
|
||||
case float f:
|
||||
return new JaegerTag(attribute.Key, JaegerTagType.DOUBLE, vDouble: Convert.ToDouble(f));
|
||||
case double d:
|
||||
return new JaegerTag(attribute.Key, JaegerTagType.DOUBLE, vDouble: d);
|
||||
case bool b:
|
||||
return new JaegerTag(attribute.Key, JaegerTagType.BOOL, vBool: b);
|
||||
}
|
||||
|
||||
return new JaegerTag(attribute.Key, JaegerTagType.STRING, vStr: attribute.Value.ToString());
|
||||
}
|
||||
|
||||
public static JaegerLog ToJaegerLog(this Event timedEvent)
|
||||
{
|
||||
var tags = new PooledListState<JaegerTag>
|
||||
{
|
||||
Created = true,
|
||||
List = PooledList<JaegerTag>.Create(),
|
||||
};
|
||||
|
||||
DictionaryEnumerator<string, object, PooledListState<JaegerTag>>.AllocationFreeForEach(
|
||||
timedEvent.Attributes,
|
||||
ref tags,
|
||||
ProcessTagRef);
|
||||
|
||||
// Matches what OpenTracing and OpenTelemetry defines as the event name.
|
||||
// https://github.com/opentracing/specification/blob/master/semantic_conventions.md#log-fields-table
|
||||
// https://github.com/open-telemetry/opentelemetry-specification/pull/397/files
|
||||
PooledList<JaegerTag>.Add(ref tags.List, new JaegerTag("message", JaegerTagType.STRING, vStr: timedEvent.Name));
|
||||
|
||||
return new JaegerLog(timedEvent.Timestamp.ToEpochMicroseconds(), tags.List);
|
||||
}
|
||||
|
||||
public static JaegerSpanRef ToJaegerSpanRef(this in Link link)
|
||||
{
|
||||
var traceId = new Int128(link.Context.TraceId);
|
||||
var spanId = new Int128(link.Context.SpanId);
|
||||
|
||||
return new JaegerSpanRef(JaegerSpanRefType.CHILD_OF, traceId.Low, traceId.High, spanId.Low);
|
||||
}
|
||||
|
||||
public static long ToEpochMicroseconds(this DateTimeOffset timestamp)
|
||||
{
|
||||
// Truncate sub-microsecond precision before offsetting by the Unix Epoch to avoid
|
||||
// the last digit being off by one for dates that result in negative Unix times
|
||||
long microseconds = timestamp.UtcDateTime.Ticks / TicksPerMicrosecond;
|
||||
return microseconds - UnixEpochMicroseconds;
|
||||
}
|
||||
|
||||
private static bool ProcessAttribute(ref TagState state, KeyValuePair<string, object> label)
|
||||
{
|
||||
var tag = label.ToJaegerTag();
|
||||
|
||||
if (tag.VStr != null
|
||||
&& PeerServiceKeyResolutionDictionary.TryGetValue(label.Key, out int priority)
|
||||
&& (state.PeerService == null || priority < state.PeerServicePriority))
|
||||
{
|
||||
state.PeerService = tag.VStr;
|
||||
state.PeerServicePriority = priority;
|
||||
}
|
||||
|
||||
PooledList<JaegerTag>.Add(ref state.Tags, tag);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool ProcessLibraryAttribute(ref TagState state, KeyValuePair<string, object> label)
|
||||
{
|
||||
switch (label.Key)
|
||||
{
|
||||
case Resource.LibraryNameKey:
|
||||
PooledList<JaegerTag>.Add(ref state.Tags, label.ToJaegerTag());
|
||||
break;
|
||||
case Resource.LibraryVersionKey:
|
||||
PooledList<JaegerTag>.Add(ref state.Tags, label.ToJaegerTag());
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool ProcessLink(ref PooledListState<JaegerSpanRef> state, Link link)
|
||||
{
|
||||
if (!state.Created)
|
||||
{
|
||||
state.List = PooledList<JaegerSpanRef>.Create();
|
||||
state.Created = true;
|
||||
}
|
||||
|
||||
PooledList<JaegerSpanRef>.Add(ref state.List, link.ToJaegerSpanRef());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool ProcessEvent(ref PooledListState<JaegerLog> state, Event e)
|
||||
{
|
||||
if (e == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!state.Created)
|
||||
{
|
||||
state.List = PooledList<JaegerLog>.Create();
|
||||
state.Created = true;
|
||||
}
|
||||
|
||||
PooledList<JaegerLog>.Add(ref state.List, e.ToJaegerLog());
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool ProcessTag(ref PooledListState<JaegerTag> state, KeyValuePair<string, object> attribute)
|
||||
{
|
||||
PooledList<JaegerTag>.Add(ref state.List, attribute.ToJaegerTag());
|
||||
return true;
|
||||
}
|
||||
|
||||
private struct TagState
|
||||
{
|
||||
public PooledList<JaegerTag> Tags;
|
||||
|
||||
public string PeerService;
|
||||
|
||||
public int PeerServicePriority;
|
||||
}
|
||||
|
||||
private struct PooledListState<T>
|
||||
{
|
||||
public bool Created;
|
||||
|
||||
public PooledList<T> List;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -17,8 +17,10 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
|
||||
using OpenTelemetry.Exporter.Jaeger.Implementation;
|
||||
using OpenTelemetry.Resources;
|
||||
|
||||
using Xunit;
|
||||
|
||||
namespace OpenTelemetry.Exporter.Jaeger.Tests.Implementation
|
||||
|
|
@ -123,7 +125,7 @@ namespace OpenTelemetry.Exporter.Jaeger.Tests.Implementation
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public void JaegerSpanConverterTest_ConvertSpanToJaegerSpan_NoAttributes()
|
||||
public void JaegerActivityConverterTest_ConvertActivityToJaegerSpan_NoAttributes()
|
||||
{
|
||||
var activity = CreateTestActivity(setAttributes: false);
|
||||
var traceIdAsInt = new Int128(activity.Context.TraceId);
|
||||
|
|
@ -182,7 +184,7 @@ namespace OpenTelemetry.Exporter.Jaeger.Tests.Implementation
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public void JaegerSpanConverterTest_ConvertSpanToJaegerSpan_NoEvents()
|
||||
public void JaegerActivityConverterTest_ConvertActivityToJaegerSpan_NoEvents()
|
||||
{
|
||||
var activity = CreateTestActivity(addEvents: false);
|
||||
var traceIdAsInt = new Int128(activity.Context.TraceId);
|
||||
|
|
@ -240,7 +242,7 @@ namespace OpenTelemetry.Exporter.Jaeger.Tests.Implementation
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public void JaegerSpanConverterTest_ConvertSpanToJaegerSpan_NoLinks()
|
||||
public void JaegerActivityConverterTest_ConvertActivityToJaegerSpan_NoLinks()
|
||||
{
|
||||
var activity = CreateTestActivity(addLinks: false);
|
||||
var traceIdAsInt = new Int128(activity.Context.TraceId);
|
||||
|
|
@ -326,7 +328,7 @@ namespace OpenTelemetry.Exporter.Jaeger.Tests.Implementation
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public void JaegerSpanConverterTest_GenerateSpan_RemoteEndpointOmittedByDefault()
|
||||
public void JaegerActivityConverterTest_GenerateJaegerSpan_RemoteEndpointOmittedByDefault()
|
||||
{
|
||||
// Arrange
|
||||
var span = CreateTestActivity();
|
||||
|
|
@ -339,7 +341,7 @@ namespace OpenTelemetry.Exporter.Jaeger.Tests.Implementation
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public void JaegerSpanConverterTest_GenerateSpan_RemoteEndpointResolution()
|
||||
public void JaegerActivityConverterTest_GenerateJaegerSpan_RemoteEndpointResolution()
|
||||
{
|
||||
// Arrange
|
||||
var span = CreateTestActivity(
|
||||
|
|
@ -357,7 +359,7 @@ namespace OpenTelemetry.Exporter.Jaeger.Tests.Implementation
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public void JaegerSpanConverterTest_GenerateSpan_PeerServiceNameIgnoredForServerSpan()
|
||||
public void JaegerActivityConverterTest_GenerateJaegerSpan_PeerServiceNameIgnoredForServerSpan()
|
||||
{
|
||||
// Arrange
|
||||
var span = CreateTestActivity(
|
||||
|
|
@ -376,7 +378,7 @@ namespace OpenTelemetry.Exporter.Jaeger.Tests.Implementation
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public void JaegerSpanConverterTest_GenerateSpan_RemoteEndpointResolutionPriority()
|
||||
public void JaegerActivityConverterTest_GenerateJaegerSpan_RemoteEndpointResolutionPriority()
|
||||
{
|
||||
// Arrange
|
||||
var span = CreateTestActivity(
|
||||
|
|
|
|||
|
|
@ -1,485 +0,0 @@
|
|||
// <copyright file="JaegerSpanConverterTest.cs" company="OpenTelemetry Authors">
|
||||
// Copyright The OpenTelemetry Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// </copyright>
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using OpenTelemetry.Exporter.Jaeger.Implementation;
|
||||
using OpenTelemetry.Resources;
|
||||
using OpenTelemetry.Trace;
|
||||
using OpenTelemetry.Trace.Export;
|
||||
using Xunit;
|
||||
|
||||
namespace OpenTelemetry.Exporter.Jaeger.Tests.Implementation
|
||||
{
|
||||
public class JaegerSpanConverterTest
|
||||
{
|
||||
[Fact]
|
||||
public void JaegerSpanConverterTest_ConvertSpanToJaegerSpan_AllPropertiesSet()
|
||||
{
|
||||
var span = CreateTestSpan();
|
||||
var traceIdAsInt = new Int128(span.Context.TraceId);
|
||||
var spanIdAsInt = new Int128(span.Context.SpanId);
|
||||
var linkTraceIdAsInt = new Int128(span.Links.Single().Context.TraceId);
|
||||
var linkSpanIdAsInt = new Int128(span.Links.Single().Context.SpanId);
|
||||
|
||||
var jaegerSpan = span.ToJaegerSpan();
|
||||
|
||||
Assert.Equal("Name", jaegerSpan.OperationName);
|
||||
Assert.Equal(2, jaegerSpan.Logs.Count);
|
||||
|
||||
Assert.Equal(traceIdAsInt.High, jaegerSpan.TraceIdHigh);
|
||||
Assert.Equal(traceIdAsInt.Low, jaegerSpan.TraceIdLow);
|
||||
Assert.Equal(spanIdAsInt.Low, jaegerSpan.SpanId);
|
||||
Assert.Equal(new Int128(span.ParentSpanId).Low, jaegerSpan.ParentSpanId);
|
||||
|
||||
Assert.Equal(span.Links.Count(), jaegerSpan.References.Count);
|
||||
var references = jaegerSpan.References.ToArray();
|
||||
var jaegerRef = references[0];
|
||||
Assert.Equal(linkTraceIdAsInt.High, jaegerRef.TraceIdHigh);
|
||||
Assert.Equal(linkTraceIdAsInt.Low, jaegerRef.TraceIdLow);
|
||||
Assert.Equal(linkSpanIdAsInt.Low, jaegerRef.SpanId);
|
||||
|
||||
Assert.Equal(0x1, jaegerSpan.Flags);
|
||||
|
||||
Assert.Equal(span.StartTimestamp.ToEpochMicroseconds(), jaegerSpan.StartTime);
|
||||
Assert.Equal((long)((span.EndTimestamp - span.StartTimestamp).TotalMilliseconds * 1000), jaegerSpan.Duration);
|
||||
|
||||
var tags = jaegerSpan.Tags.ToArray();
|
||||
var tag = tags[0];
|
||||
Assert.Equal(JaegerTagType.STRING, tag.VType);
|
||||
Assert.Equal("stringKey", tag.Key);
|
||||
Assert.Equal("value", tag.VStr);
|
||||
tag = tags[1];
|
||||
Assert.Equal(JaegerTagType.LONG, tag.VType);
|
||||
Assert.Equal("longKey", tag.Key);
|
||||
Assert.Equal(1, tag.VLong);
|
||||
tag = tags[2];
|
||||
Assert.Equal(JaegerTagType.LONG, tag.VType);
|
||||
Assert.Equal("longKey2", tag.Key);
|
||||
Assert.Equal(1, tag.VLong);
|
||||
tag = tags[3];
|
||||
Assert.Equal(JaegerTagType.DOUBLE, tag.VType);
|
||||
Assert.Equal("doubleKey", tag.Key);
|
||||
Assert.Equal(1, tag.VDouble);
|
||||
tag = tags[4];
|
||||
Assert.Equal(JaegerTagType.DOUBLE, tag.VType);
|
||||
Assert.Equal("doubleKey2", tag.Key);
|
||||
Assert.Equal(1, tag.VDouble);
|
||||
tag = tags[5];
|
||||
Assert.Equal(JaegerTagType.BOOL, tag.VType);
|
||||
Assert.Equal("boolKey", tag.Key);
|
||||
Assert.Equal(true, tag.VBool);
|
||||
|
||||
var logs = jaegerSpan.Logs.ToArray();
|
||||
var jaegerLog = logs[0];
|
||||
Assert.Equal(span.Events.First().Timestamp.ToEpochMicroseconds(), jaegerLog.Timestamp);
|
||||
Assert.Equal(2, jaegerLog.Fields.Count());
|
||||
var eventFields = jaegerLog.Fields.ToArray();
|
||||
var eventField = eventFields[0];
|
||||
Assert.Equal("key", eventField.Key);
|
||||
Assert.Equal("value", eventField.VStr);
|
||||
eventField = eventFields[1];
|
||||
Assert.Equal("message", eventField.Key);
|
||||
Assert.Equal("Event1", eventField.VStr);
|
||||
|
||||
Assert.Equal(span.Events.First().Timestamp.ToEpochMicroseconds(), jaegerLog.Timestamp);
|
||||
|
||||
jaegerLog = logs[1];
|
||||
Assert.Equal(2, jaegerLog.Fields.Count());
|
||||
eventFields = jaegerLog.Fields.ToArray();
|
||||
eventField = eventFields[0];
|
||||
Assert.Equal("key", eventField.Key);
|
||||
Assert.Equal("value", eventField.VStr);
|
||||
eventField = eventFields[1];
|
||||
Assert.Equal("message", eventField.Key);
|
||||
Assert.Equal("Event2", eventField.VStr);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void JaegerSpanConverterTest_ConvertSpanToJaegerSpan_NoAttributes()
|
||||
{
|
||||
var span = CreateTestSpan(setAttributes: false);
|
||||
var traceIdAsInt = new Int128(span.Context.TraceId);
|
||||
var spanIdAsInt = new Int128(span.Context.SpanId);
|
||||
var linkTraceIdAsInt = new Int128(span.Links.Single().Context.TraceId);
|
||||
var linkSpanIdAsInt = new Int128(span.Links.Single().Context.SpanId);
|
||||
|
||||
var jaegerSpan = span.ToJaegerSpan();
|
||||
|
||||
Assert.Equal("Name", jaegerSpan.OperationName);
|
||||
Assert.Equal(2, jaegerSpan.Logs.Count);
|
||||
|
||||
Assert.Equal(traceIdAsInt.High, jaegerSpan.TraceIdHigh);
|
||||
Assert.Equal(traceIdAsInt.Low, jaegerSpan.TraceIdLow);
|
||||
Assert.Equal(spanIdAsInt.Low, jaegerSpan.SpanId);
|
||||
Assert.Equal(new Int128(span.ParentSpanId).Low, jaegerSpan.ParentSpanId);
|
||||
|
||||
Assert.Equal(span.Links.Count(), jaegerSpan.References.Count);
|
||||
var references = jaegerSpan.References.ToArray();
|
||||
var jaegerRef = references[0];
|
||||
Assert.Equal(linkTraceIdAsInt.High, jaegerRef.TraceIdHigh);
|
||||
Assert.Equal(linkTraceIdAsInt.Low, jaegerRef.TraceIdLow);
|
||||
Assert.Equal(linkSpanIdAsInt.Low, jaegerRef.SpanId);
|
||||
|
||||
Assert.Equal(0x1, jaegerSpan.Flags);
|
||||
|
||||
Assert.Equal(span.StartTimestamp.ToEpochMicroseconds(), jaegerSpan.StartTime);
|
||||
Assert.Equal((long)((span.EndTimestamp - span.StartTimestamp).TotalMilliseconds * 1000), jaegerSpan.Duration);
|
||||
|
||||
// 2 tags: span.kind & ot.status_code.
|
||||
Assert.Equal(2, jaegerSpan.Tags.Count);
|
||||
|
||||
var logs = jaegerSpan.Logs.ToArray();
|
||||
var jaegerLog = logs[0];
|
||||
Assert.Equal(span.Events.First().Timestamp.ToEpochMicroseconds(), jaegerLog.Timestamp);
|
||||
Assert.Equal(2, jaegerLog.Fields.Count());
|
||||
var eventFields = jaegerLog.Fields.ToArray();
|
||||
var eventField = eventFields[0];
|
||||
Assert.Equal("key", eventField.Key);
|
||||
Assert.Equal("value", eventField.VStr);
|
||||
eventField = eventFields[1];
|
||||
Assert.Equal("message", eventField.Key);
|
||||
Assert.Equal("Event1", eventField.VStr);
|
||||
|
||||
Assert.Equal(span.Events.First().Timestamp.ToEpochMicroseconds(), jaegerLog.Timestamp);
|
||||
|
||||
jaegerLog = logs[1];
|
||||
Assert.Equal(2, jaegerLog.Fields.Count());
|
||||
eventFields = jaegerLog.Fields.ToArray();
|
||||
eventField = eventFields[0];
|
||||
Assert.Equal("key", eventField.Key);
|
||||
Assert.Equal("value", eventField.VStr);
|
||||
eventField = eventFields[1];
|
||||
Assert.Equal("message", eventField.Key);
|
||||
Assert.Equal("Event2", eventField.VStr);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void JaegerSpanConverterTest_ConvertSpanToJaegerSpan_NoEvents()
|
||||
{
|
||||
var span = CreateTestSpan(addEvents: false);
|
||||
var traceIdAsInt = new Int128(span.Context.TraceId);
|
||||
var spanIdAsInt = new Int128(span.Context.SpanId);
|
||||
var linkTraceIdAsInt = new Int128(span.Links.Single().Context.TraceId);
|
||||
var linkSpanIdAsInt = new Int128(span.Links.Single().Context.SpanId);
|
||||
|
||||
var jaegerSpan = span.ToJaegerSpan();
|
||||
|
||||
Assert.Equal("Name", jaegerSpan.OperationName);
|
||||
Assert.Empty(jaegerSpan.Logs);
|
||||
|
||||
Assert.Equal(traceIdAsInt.High, jaegerSpan.TraceIdHigh);
|
||||
Assert.Equal(traceIdAsInt.Low, jaegerSpan.TraceIdLow);
|
||||
Assert.Equal(spanIdAsInt.Low, jaegerSpan.SpanId);
|
||||
Assert.Equal(new Int128(span.ParentSpanId).Low, jaegerSpan.ParentSpanId);
|
||||
|
||||
Assert.Equal(span.Links.Count(), jaegerSpan.References.Count);
|
||||
var references = jaegerSpan.References.ToArray();
|
||||
var jaegerRef = references[0];
|
||||
Assert.Equal(linkTraceIdAsInt.High, jaegerRef.TraceIdHigh);
|
||||
Assert.Equal(linkTraceIdAsInt.Low, jaegerRef.TraceIdLow);
|
||||
Assert.Equal(linkSpanIdAsInt.Low, jaegerRef.SpanId);
|
||||
|
||||
Assert.Equal(0x1, jaegerSpan.Flags);
|
||||
|
||||
Assert.Equal(span.StartTimestamp.ToEpochMicroseconds(), jaegerSpan.StartTime);
|
||||
Assert.Equal(
|
||||
span.EndTimestamp.ToEpochMicroseconds()
|
||||
- span.StartTimestamp.ToEpochMicroseconds(), jaegerSpan.Duration);
|
||||
|
||||
var tags = jaegerSpan.Tags.ToArray();
|
||||
var tag = tags[0];
|
||||
Assert.Equal(JaegerTagType.STRING, tag.VType);
|
||||
Assert.Equal("stringKey", tag.Key);
|
||||
Assert.Equal("value", tag.VStr);
|
||||
tag = tags[1];
|
||||
Assert.Equal(JaegerTagType.LONG, tag.VType);
|
||||
Assert.Equal("longKey", tag.Key);
|
||||
Assert.Equal(1, tag.VLong);
|
||||
tag = tags[2];
|
||||
Assert.Equal(JaegerTagType.LONG, tag.VType);
|
||||
Assert.Equal("longKey2", tag.Key);
|
||||
Assert.Equal(1, tag.VLong);
|
||||
tag = tags[3];
|
||||
Assert.Equal(JaegerTagType.DOUBLE, tag.VType);
|
||||
Assert.Equal("doubleKey", tag.Key);
|
||||
Assert.Equal(1, tag.VDouble);
|
||||
tag = tags[4];
|
||||
Assert.Equal(JaegerTagType.DOUBLE, tag.VType);
|
||||
Assert.Equal("doubleKey2", tag.Key);
|
||||
Assert.Equal(1, tag.VDouble);
|
||||
tag = tags[5];
|
||||
Assert.Equal(JaegerTagType.BOOL, tag.VType);
|
||||
Assert.Equal("boolKey", tag.Key);
|
||||
Assert.Equal(true, tag.VBool);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void JaegerSpanConverterTest_ConvertSpanToJaegerSpan_NoLinks()
|
||||
{
|
||||
var span = CreateTestSpan(addLinks: false);
|
||||
var traceIdAsInt = new Int128(span.Context.TraceId);
|
||||
var spanIdAsInt = new Int128(span.Context.SpanId);
|
||||
|
||||
var jaegerSpan = span.ToJaegerSpan();
|
||||
|
||||
Assert.Equal("Name", jaegerSpan.OperationName);
|
||||
Assert.Equal(2, jaegerSpan.Logs.Count);
|
||||
|
||||
Assert.Equal(traceIdAsInt.High, jaegerSpan.TraceIdHigh);
|
||||
Assert.Equal(traceIdAsInt.Low, jaegerSpan.TraceIdLow);
|
||||
Assert.Equal(spanIdAsInt.Low, jaegerSpan.SpanId);
|
||||
Assert.Equal(new Int128(span.ParentSpanId).Low, jaegerSpan.ParentSpanId);
|
||||
|
||||
Assert.Empty(jaegerSpan.References);
|
||||
|
||||
Assert.Equal(0x1, jaegerSpan.Flags);
|
||||
|
||||
Assert.Equal(span.StartTimestamp.ToEpochMicroseconds(), jaegerSpan.StartTime);
|
||||
Assert.Equal(
|
||||
span.EndTimestamp.ToEpochMicroseconds()
|
||||
- span.StartTimestamp.ToEpochMicroseconds(), jaegerSpan.Duration);
|
||||
|
||||
var tags = jaegerSpan.Tags.ToArray();
|
||||
var tag = tags[0];
|
||||
Assert.Equal(JaegerTagType.STRING, tag.VType);
|
||||
Assert.Equal("stringKey", tag.Key);
|
||||
Assert.Equal("value", tag.VStr);
|
||||
tag = tags[1];
|
||||
Assert.Equal(JaegerTagType.LONG, tag.VType);
|
||||
Assert.Equal("longKey", tag.Key);
|
||||
Assert.Equal(1, tag.VLong);
|
||||
tag = tags[2];
|
||||
Assert.Equal(JaegerTagType.LONG, tag.VType);
|
||||
Assert.Equal("longKey2", tag.Key);
|
||||
Assert.Equal(1, tag.VLong);
|
||||
tag = tags[3];
|
||||
Assert.Equal(JaegerTagType.DOUBLE, tag.VType);
|
||||
Assert.Equal("doubleKey", tag.Key);
|
||||
Assert.Equal(1, tag.VDouble);
|
||||
tag = tags[4];
|
||||
Assert.Equal(JaegerTagType.DOUBLE, tag.VType);
|
||||
Assert.Equal("doubleKey2", tag.Key);
|
||||
Assert.Equal(1, tag.VDouble);
|
||||
tag = tags[5];
|
||||
Assert.Equal(JaegerTagType.BOOL, tag.VType);
|
||||
Assert.Equal("boolKey", tag.Key);
|
||||
Assert.Equal(true, tag.VBool);
|
||||
|
||||
// The second to last tag should be span.kind in this case
|
||||
tag = tags[tags.Length - 2];
|
||||
Assert.Equal(JaegerTagType.STRING, tag.VType);
|
||||
Assert.Equal("span.kind", tag.Key);
|
||||
Assert.Equal("client", tag.VStr);
|
||||
|
||||
// The last tag should be ot.status_code in this case
|
||||
tag = tags[tags.Length - 1];
|
||||
Assert.Equal(JaegerTagType.STRING, tag.VType);
|
||||
Assert.Equal(SpanAttributeConstants.StatusCodeKey, tag.Key);
|
||||
Assert.Equal("Ok", tag.VStr);
|
||||
|
||||
var logs = jaegerSpan.Logs.ToArray();
|
||||
var jaegerLog = logs[0];
|
||||
Assert.Equal(span.Events.First().Timestamp.ToEpochMicroseconds(), jaegerLog.Timestamp);
|
||||
Assert.Equal(2, jaegerLog.Fields.Count());
|
||||
var eventFields = jaegerLog.Fields.ToArray();
|
||||
var eventField = eventFields[0];
|
||||
Assert.Equal("key", eventField.Key);
|
||||
Assert.Equal("value", eventField.VStr);
|
||||
eventField = eventFields[1];
|
||||
Assert.Equal("message", eventField.Key);
|
||||
Assert.Equal("Event1", eventField.VStr);
|
||||
Assert.Equal(span.Events.First().Timestamp.ToEpochMicroseconds(), jaegerLog.Timestamp);
|
||||
|
||||
jaegerLog = logs[1];
|
||||
Assert.Equal(2, jaegerLog.Fields.Count());
|
||||
eventFields = jaegerLog.Fields.ToArray();
|
||||
eventField = eventFields[0];
|
||||
Assert.Equal("key", eventField.Key);
|
||||
Assert.Equal("value", eventField.VStr);
|
||||
eventField = eventFields[1];
|
||||
Assert.Equal("message", eventField.Key);
|
||||
Assert.Equal("Event2", eventField.VStr);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void JaegerSpanConverterTest_GenerateSpan_RemoteEndpointOmittedByDefault()
|
||||
{
|
||||
// Arrange
|
||||
var span = CreateTestSpan();
|
||||
|
||||
// Act
|
||||
var jaegerSpan = span.ToJaegerSpan();
|
||||
|
||||
// Assert
|
||||
Assert.DoesNotContain(jaegerSpan.Tags, t => t.Key == "peer.service");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void JaegerSpanConverterTest_GenerateSpan_RemoteEndpointResolution()
|
||||
{
|
||||
// Arrange
|
||||
var span = CreateTestSpan(
|
||||
additionalAttributes: new Dictionary<string, object>
|
||||
{
|
||||
["net.peer.name"] = "RemoteServiceName",
|
||||
});
|
||||
|
||||
// Act
|
||||
var jaegerSpan = span.ToJaegerSpan();
|
||||
|
||||
// Assert
|
||||
Assert.Contains(jaegerSpan.Tags, t => t.Key == "peer.service");
|
||||
Assert.Equal("RemoteServiceName", jaegerSpan.Tags.First(t => t.Key == "peer.service").VStr);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void JaegerSpanConverterTest_GenerateSpan_PeerServiceNameIgnoredForServerSpan()
|
||||
{
|
||||
// Arrange
|
||||
var span = CreateTestSpan(
|
||||
additionalAttributes: new Dictionary<string, object>
|
||||
{
|
||||
["http.host"] = "DiscardedRemoteServiceName",
|
||||
},
|
||||
kind: SpanKind.Server);
|
||||
|
||||
// Act
|
||||
var jaegerSpan = span.ToJaegerSpan();
|
||||
|
||||
// Assert
|
||||
Assert.Null(jaegerSpan.PeerServiceName);
|
||||
Assert.Empty(jaegerSpan.Tags.Where(t => t.Key == "peer.service"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void JaegerSpanConverterTest_GenerateSpan_RemoteEndpointResolutionPriority()
|
||||
{
|
||||
// Arrange
|
||||
var span = CreateTestSpan(
|
||||
additionalAttributes: new Dictionary<string, object>
|
||||
{
|
||||
["http.host"] = "DiscardedRemoteServiceName",
|
||||
["peer.service"] = "RemoteServiceName",
|
||||
["peer.hostname"] = "DiscardedRemoteServiceName",
|
||||
});
|
||||
|
||||
// Act
|
||||
var jaegerSpan = span.ToJaegerSpan();
|
||||
|
||||
// Assert
|
||||
var tags = jaegerSpan.Tags.Where(t => t.Key == "peer.service");
|
||||
Assert.Single(tags);
|
||||
var tag = tags.First();
|
||||
Assert.Equal("RemoteServiceName", tag.VStr);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void JaegerSpanConverterTest_ConvertSpanToJaegerSpan_LibraryResources()
|
||||
{
|
||||
var span = CreateTestSpan(resource: new Resource(new Dictionary<string, object>
|
||||
{
|
||||
[Resource.LibraryNameKey] = "libname",
|
||||
[Resource.LibraryVersionKey] = "libversion",
|
||||
[Resource.ServiceNameKey] = "MyService",
|
||||
}));
|
||||
|
||||
var jaegerSpan = span.ToJaegerSpan();
|
||||
|
||||
Assert.Contains(jaegerSpan.Tags, t => t.Key == Resource.LibraryNameKey && t.VStr == "libname");
|
||||
Assert.Contains(jaegerSpan.Tags, t => t.Key == Resource.LibraryVersionKey && t.VStr == "libversion");
|
||||
Assert.DoesNotContain(jaegerSpan.Tags, t => t.Key == Resource.ServiceNameKey && t.VStr == "MyService");
|
||||
}
|
||||
|
||||
internal static SpanData CreateTestSpan(
|
||||
bool setAttributes = true,
|
||||
Dictionary<string, object> additionalAttributes = null,
|
||||
bool addEvents = true,
|
||||
bool addLinks = true,
|
||||
Resource resource = null,
|
||||
SpanKind kind = SpanKind.Client)
|
||||
{
|
||||
var startTimestamp = DateTime.UtcNow;
|
||||
var endTimestamp = startTimestamp.AddSeconds(60);
|
||||
var eventTimestamp = DateTime.UtcNow;
|
||||
var traceId = ActivityTraceId.CreateFromString("e8ea7e9ac72de94e91fabc613f9686b2".AsSpan());
|
||||
|
||||
var spanId = ActivitySpanId.CreateRandom();
|
||||
var parentSpanId = ActivitySpanId.CreateFromBytes(new byte[] { 12, 23, 34, 45, 56, 67, 78, 89 });
|
||||
|
||||
var attributes = new Dictionary<string, object>
|
||||
{
|
||||
{ "stringKey", "value" },
|
||||
{ "longKey", 1L },
|
||||
{ "longKey2", 1 },
|
||||
{ "doubleKey", 1D },
|
||||
{ "doubleKey2", 1F },
|
||||
{ "boolKey", true },
|
||||
};
|
||||
if (additionalAttributes != null)
|
||||
{
|
||||
foreach (var attribute in additionalAttributes)
|
||||
{
|
||||
attributes.Add(attribute.Key, attribute.Value);
|
||||
}
|
||||
}
|
||||
|
||||
var events = new List<Event>
|
||||
{
|
||||
new Event(
|
||||
"Event1",
|
||||
eventTimestamp,
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
{ "key", "value" },
|
||||
}),
|
||||
new Event(
|
||||
"Event2",
|
||||
eventTimestamp,
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
{ "key", "value" },
|
||||
}),
|
||||
};
|
||||
|
||||
var linkedSpanId = ActivitySpanId.CreateFromString("888915b6286b9c41".AsSpan());
|
||||
var links = addLinks
|
||||
? new[]
|
||||
{
|
||||
new Link(new SpanContext(
|
||||
traceId,
|
||||
linkedSpanId,
|
||||
ActivityTraceFlags.Recorded)),
|
||||
}
|
||||
: null;
|
||||
|
||||
return new SpanData(
|
||||
"Name",
|
||||
new SpanContext(traceId, spanId, ActivityTraceFlags.Recorded),
|
||||
parentSpanId,
|
||||
kind,
|
||||
startTimestamp,
|
||||
setAttributes ? attributes : null,
|
||||
addEvents ? events : null,
|
||||
links,
|
||||
resource,
|
||||
Status.Ok,
|
||||
endTimestamp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -17,19 +17,36 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using OpenTelemetry.Exporter.Jaeger.Implementation;
|
||||
using OpenTelemetry.Resources;
|
||||
using OpenTelemetry.Trace;
|
||||
using OpenTelemetry.Trace.Export;
|
||||
|
||||
using Xunit;
|
||||
|
||||
namespace OpenTelemetry.Exporter.Jaeger.Tests.Implementation
|
||||
{
|
||||
public class JaegerUdpBatcherTests
|
||||
{
|
||||
public const string TestPayloadBase64 = "goEBCWVtaXRCYXRjaBwcGAx0ZXN0IHByb2Nlc3MZHBgQdGVzdF9wcm9jZXNzX3RhZxUAGAp0ZXN0X3ZhbHVlAAAZHBab5cuG2OehhdwBFuPakI2n2cCVLhaAjfWp6NHt6dQBFrK5moSni5GXGBgETmFtZRkcFQAWm+XLhtjnoYXcARbj2pCNp9nAlS4W/Y6j+bqS9fbuAQAVAhaAgLPexpa/BRaAnJw5GYwYCXN0cmluZ0tleRUAGAV2YWx1ZQAYB2xvbmdLZXkVBkYCABgIbG9uZ0tleTIVBkYCABgJZG91YmxlS2V5FQInAAAAAAAA8D8AGApkb3VibGVLZXkyFQInAAAAAAAA8D8AGAdib29sS2V5FQQxABgJc3Bhbi5raW5kFQAYBmNsaWVudAAYDm90LnN0YXR1c19jb2RlFQAYAk9rABksFoCAs97Glr8FGSwYA2tleRUAGAV2YWx1ZQAYB21lc3NhZ2UVABgGRXZlbnQxAAAWgICz3saWvwUZLBgDa2V5FQAYBXZhbHVlABgHbWVzc2FnZRUAGAZFdmVudDIAAAAAAA==";
|
||||
public const string TestPayloadBase64 = "goEBCWVtaXRCYXRjaBwcGAx0ZXN0IHByb2Nlc3MZHBgQdGVzdF9wcm9jZXNzX3RhZxUAGAp0ZXN0X3ZhbHVlAAAZHBab5cuG2OehhdwBFuPakI2n2cCVLhaAjfWp6NHt6dQBFrK5moSni5GXGBgETmFtZRkcFQAWm+XLhtjnoYXcARbj2pCNp9nAlS4W/Y6j+bqS9fbuAQAVABaAgLPexpa/BRYAGZwYCXN0cmluZ0tleRUAGAV2YWx1ZQAYB2xvbmdLZXkVABgBMQAYCGxvbmdLZXkyFQAYATEAGAlkb3VibGVLZXkVABgBMQAYCmRvdWJsZUtleTIVABgBMQAYB2Jvb2xLZXkVABgEVHJ1ZQAYDm90LnN0YXR1c19jb2RlFQAYAk9rABgJc3Bhbi5raW5kFQAYBmNsaWVudAAYDGxpYnJhcnkubmFtZRUAGBtDcmVhdGVUZXN0UGF5bG9hZEphZWdlclNwYW4AGSwWgICz3saWvwUZLBgDa2V5FQAYBXZhbHVlABgHbWVzc2FnZRUAGAZFdmVudDEAABaAgLPexpa/BRksGANrZXkVABgFdmFsdWUAGAdtZXNzYWdlFQAYBkV2ZW50MgAAAAAA";
|
||||
|
||||
static JaegerUdpBatcherTests()
|
||||
{
|
||||
Activity.DefaultIdFormat = ActivityIdFormat.W3C;
|
||||
Activity.ForceDefaultIdFormat = true;
|
||||
|
||||
var listener = new ActivityListener
|
||||
{
|
||||
ShouldListenTo = _ => true,
|
||||
GetRequestedDataUsingParentId = (ref ActivityCreationOptions<string> options) => ActivityDataRequest.AllData,
|
||||
GetRequestedDataUsingContext = (ref ActivityCreationOptions<ActivityContext> options) => ActivityDataRequest.AllData,
|
||||
};
|
||||
|
||||
ActivitySource.AddActivityListener(listener);
|
||||
}
|
||||
|
||||
internal static Process TestProcess { get; } = new Process("test process", new Dictionary<string, object> { { "test_process_tag", "test_value" } });
|
||||
|
||||
|
|
@ -157,16 +174,16 @@ namespace OpenTelemetry.Exporter.Jaeger.Tests.Implementation
|
|||
{ "doubleKey2", 1F },
|
||||
{ "boolKey", true },
|
||||
};
|
||||
var events = new List<Event>
|
||||
var events = new List<ActivityEvent>
|
||||
{
|
||||
new Event(
|
||||
new ActivityEvent(
|
||||
"Event1",
|
||||
eventTimestamp,
|
||||
new Dictionary<string, object>
|
||||
{
|
||||
{ "key", "value" },
|
||||
}),
|
||||
new Event(
|
||||
new ActivityEvent(
|
||||
"Event2",
|
||||
eventTimestamp,
|
||||
new Dictionary<string, object>
|
||||
|
|
@ -177,23 +194,38 @@ namespace OpenTelemetry.Exporter.Jaeger.Tests.Implementation
|
|||
|
||||
var linkedSpanId = ActivitySpanId.CreateFromString("888915b6286b9c41".AsSpan());
|
||||
|
||||
var link = new Link(new SpanContext(
|
||||
var activitySource = new ActivitySource(nameof(CreateTestPayloadJaegerSpan));
|
||||
|
||||
var tags = attributes.Select(kvp => new KeyValuePair<string, string>(kvp.Key, kvp.Value.ToString()));
|
||||
|
||||
var links = new[]
|
||||
{
|
||||
new ActivityLink(new ActivityContext(
|
||||
traceId,
|
||||
linkedSpanId,
|
||||
ActivityTraceFlags.Recorded));
|
||||
ActivityTraceFlags.Recorded)),
|
||||
};
|
||||
|
||||
return new SpanData(
|
||||
Activity activity = activitySource.StartActivity(
|
||||
"Name",
|
||||
new SpanContext(traceId, spanId, ActivityTraceFlags.Recorded),
|
||||
parentSpanId,
|
||||
SpanKind.Client,
|
||||
startTimestamp,
|
||||
attributes,
|
||||
events,
|
||||
new[] { link, },
|
||||
null,
|
||||
Status.Ok,
|
||||
endTimestamp).ToJaegerSpan();
|
||||
ActivityKind.Client,
|
||||
parentContext: default,
|
||||
tags,
|
||||
links,
|
||||
startTime: startTimestamp);
|
||||
|
||||
typeof(Activity).GetField("_traceId", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(activity, traceId.ToHexString());
|
||||
typeof(Activity).GetField("_spanId", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(activity, spanId.ToHexString());
|
||||
typeof(Activity).GetField("_parentSpanId", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(activity, parentSpanId.ToHexString());
|
||||
|
||||
foreach (var @event in events)
|
||||
{
|
||||
activity.AddEvent(@event);
|
||||
}
|
||||
|
||||
activity.SetStatus(Status.Ok);
|
||||
|
||||
return activity.ToJaegerSpan();
|
||||
}
|
||||
|
||||
internal static JaegerSpan CreateTestJaegerSpan(
|
||||
|
|
@ -202,9 +234,9 @@ namespace OpenTelemetry.Exporter.Jaeger.Tests.Implementation
|
|||
bool addEvents = true,
|
||||
bool addLinks = true,
|
||||
Resource resource = null,
|
||||
SpanKind kind = SpanKind.Client)
|
||||
ActivityKind kind = ActivityKind.Client)
|
||||
{
|
||||
return JaegerSpanConverterTest.CreateTestSpan(
|
||||
return JaegerActivityConversionTest.CreateTestActivity(
|
||||
setAttributes, additionalAttributes, addEvents, addLinks, resource, kind).ToJaegerSpan();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
|
||||
using OpenTelemetry.Exporter.Jaeger.Implementation;
|
||||
using OpenTelemetry.Resources;
|
||||
using OpenTelemetry.Trace.Configuration;
|
||||
|
|
|
|||
Loading…
Reference in New Issue