-
-
Save cortex93/a910534ba8bd095428102a30d0ba4eb9 to your computer and use it in GitHub Desktop.
JaegerProgator for OpenTelemetry (extract only)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using OpenTelemetry; | |
using OpenTelemetry.Context.Propagation; | |
using System; | |
using System.Collections.Generic; | |
using System.Diagnostics; | |
using System.Linq; | |
namespace ProperNamespace | |
{ | |
internal class JaegerPropagator : TextMapPropagator | |
{ | |
public override ISet<string> Fields => new HashSet<string> { PROPAGATION_HEADER }; | |
private const string PROPAGATION_HEADER = "uber-trace-id"; | |
private const string PROPAGATION_HEADER_DELIMITER = ":"; | |
private const int MAX_TRACE_ID_LENGTH = 2 * 16; | |
private const int MAX_SPAN_ID_LENGTH = 2 * 8; | |
private const int MAX_FLAGS_LENGTH = 2; | |
public override PropagationContext Extract<T>(PropagationContext context, T carrier, Func<T, string, IEnumerable<string>> getter) | |
{ | |
if (context.ActivityContext.IsValid()) | |
{ | |
// If a valid context has already been extracted, perform a noop. | |
return context; | |
} | |
if (carrier == null) | |
{ | |
return context; | |
} | |
if (getter == null) | |
{ | |
return context; | |
} | |
try | |
{ | |
var traceparentCollection = getter(carrier, PROPAGATION_HEADER); | |
// There must be a single traceparent | |
if (traceparentCollection == null || traceparentCollection.Count() != 1) | |
{ | |
return context; | |
} | |
var traceparent = traceparentCollection.First(); | |
var traceparentParsed = TryExtractTraceparent(traceparent, out var traceId, out var spanId, out var traceoptions); | |
if (!traceparentParsed) | |
{ | |
return context; | |
} | |
return new PropagationContext( | |
new ActivityContext(traceId, spanId, traceoptions, null, isRemote: true), | |
context.Baggage); | |
} | |
catch (Exception ex) | |
{ | |
} | |
return context; | |
} | |
internal static bool TryExtractTraceparent(string traceparent, out ActivityTraceId traceId, out ActivitySpanId spanId, out ActivityTraceFlags traceOptions) | |
{ | |
traceId = default; | |
spanId = default; | |
traceOptions = default; | |
var parts = traceparent.Split(PROPAGATION_HEADER_DELIMITER); | |
if (parts.Length != 4) return false; | |
if (!IsTraceIdValid(parts[0])) return false; | |
traceId = ActivityTraceId.CreateFromString(parts[0].AsSpan()); | |
if (!IsSpanIdValid(parts[1])) return false; | |
spanId = ActivitySpanId.CreateFromString(parts[1].AsSpan()); | |
// parts[2] is ignored | |
if (!IsFlagsValid(parts[3]) || !int.TryParse(parts[3], out int flags)) return false; | |
traceOptions = flags == 1 ? ActivityTraceFlags.Recorded : ActivityTraceFlags.None; | |
return true; | |
} | |
private static bool IsTraceIdValid(string value) | |
{ | |
return !(string.IsNullOrWhiteSpace(value) || value.Length > MAX_TRACE_ID_LENGTH); | |
} | |
private static bool IsSpanIdValid(string value) | |
{ | |
return !(string.IsNullOrWhiteSpace(value) || value.Length > MAX_SPAN_ID_LENGTH); | |
} | |
private static bool IsFlagsValid(string value) | |
{ | |
return !(string.IsNullOrWhiteSpace(value) || value.Length > MAX_FLAGS_LENGTH); | |
} | |
public override void Inject<T>(PropagationContext context, T carrier, Action<T, string, string> setter) | |
{ | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment