/// <summary> /// Initializes a new instance of the <see cref="SpanContext"/> class /// from a propagated context. <see cref="Parent"/> will be null /// since this is a root context locally. /// </summary> /// <param name="traceId">The propagated trace id.</param> /// <param name="spanId">The propagated span id.</param> /// <param name="samplingPriority">The propagated sampling priority.</param> /// <param name="serviceName">The service name to propagate to child spans.</param> /// <param name="traceState">The W3C tracestate.</param> public SpanContext(TraceId?traceId, ulong spanId, SamplingPriority?samplingPriority, string serviceName = null, string traceState = null) : this(traceId, serviceName) { SpanId = spanId; SamplingPriority = samplingPriority; TraceState = traceState; }
/// <summary> /// Initializes a new instance of the <see cref="SpanContext"/> class /// from a propagated context. <see cref="Parent"/> will be null /// since this is a root context locally. /// </summary> /// <param name="traceId">The propagated trace id.</param> /// <param name="spanId">The propagated span id.</param> /// <param name="samplingPriority">The propagated sampling priority.</param> /// <param name="serviceName">The service name to propagate to child spans.</param> /// <param name="origin">The propagated origin of the trace.</param> internal SpanContext(TraceId?traceId, ulong spanId, SamplingPriority?samplingPriority, string serviceName, string origin) : this(traceId, serviceName) { SpanId = spanId; SamplingPriority = samplingPriority; Origin = origin; }
/// <summary> /// Initializes a new instance of the <see cref="SpanContext"/> class /// from a propagated context. <see cref="Parent"/> will be null /// since this is a root context locally. /// </summary> /// <param name="traceId">The propagated trace id.</param> /// <param name="spanId">The propagated span id.</param> /// <param name="samplingPriority">The propagated sampling priority.</param> /// <param name="serviceName">The service name to propagate to child spans.</param> /// <param name="origin">The propagated origin of the trace.</param> /// <param name="rawTraceId">The raw propagated trace id</param> /// <param name="rawSpanId">The raw propagated span id</param> internal SpanContext(TraceId?traceId, ulong spanId, int?samplingPriority, string serviceName, string origin, string rawTraceId, string rawSpanId) : this(traceId, serviceName) { SpanId = spanId; SamplingPriority = samplingPriority; Origin = origin; RawTraceId = rawTraceId; RawSpanId = rawSpanId; }
public SpanContext Extract(IPropagatorMap propagatorMap) { if (propagatorMap == null) { throw new ArgumentNullException(nameof(propagatorMap)); } TraceId?traceId = null; ulong? spanId = null, parentId = null; bool sampled = false, debug = false;; foreach (var entry in propagatorMap) { if (string.Equals(entry.Key, TraceIdHeader, StringComparison.OrdinalIgnoreCase)) { if (TraceId.TryParse(entry.Value, out var _trace)) { traceId = _trace; } } else if (string.Equals(entry.Key, SpanIdHeader, StringComparison.OrdinalIgnoreCase)) { if (ulong.TryParse(entry.Value, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var _spanId)) { spanId = _spanId; } } else if (string.Equals(entry.Key, ParentIdHeader, StringComparison.OrdinalIgnoreCase)) { if (ulong.TryParse(entry.Value, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var _parent)) { parentId = _parent; } } else if (string.Equals(entry.Key, SampledHeader, StringComparison.OrdinalIgnoreCase)) { sampled = string.Equals(entry.Value, SampledTrue); } else if (string.Equals(entry.Key, DebugHeader, StringComparison.OrdinalIgnoreCase)) { debug = string.Equals(entry.Value, SampledTrue); } } if (traceId == null || spanId == null) { return(null); } return(new SpanContext(traceId.Value, spanId.Value, parentId, sampled, debug, shared: false)); }
private SpanContext(TraceId?traceId, string serviceName) { ServiceName = serviceName; if (traceId.HasValue) { TraceId = traceId.Value; return; } TraceId = TraceId.CreateRandom(); SpanId = GenerateId(); }
private SpanContext(TraceId?traceId, string serviceName) { TraceId = traceId ?? Tracer.Instance.TracerManager.TraceIdConvention.GenerateNewTraceId(); ServiceName = serviceName; // Because we have a ctor as part of the public api without accepting the origin tag, // we need to ensure new SpanContext created by this .ctor has the CI Visibility origin // tag if the CI Visibility mode is running to ensure the correct propagation // to children spans and distributed trace. if (CIVisibility.IsRunning) { Origin = Ci.Tags.TestTags.CIAppTestOriginName; } }
protected override SpanContext Extract(ITextMap carrier) { TraceId? traceId = null; SpanId? spanId = null; SpanId parentId = new SpanId(0); // Conventionally, parent id == 0 means the root span SpanContextFlags flags = SpanContextFlags.None; foreach (var entry in carrier) { if (string.Equals(entry.Key, SampledName, StringComparison.OrdinalIgnoreCase)) { string value = entry.Value; if (string.Equals(value, "1", StringComparison.Ordinal) || string.Equals(value, "true", StringComparison.OrdinalIgnoreCase)) { flags |= SpanContextFlags.Sampled; } } else if (string.Equals(entry.Key, TraceIdName, StringComparison.OrdinalIgnoreCase)) { traceId = TraceId.FromString(entry.Value); } else if (string.Equals(entry.Key, ParentSpanIdName, StringComparison.OrdinalIgnoreCase)) { parentId = SpanId.FromString(entry.Value); } else if (string.Equals(entry.Key, SpanIdName, StringComparison.OrdinalIgnoreCase)) { spanId = SpanId.FromString(entry.Value); } else if (string.Equals(entry.Key, FlagsName, StringComparison.OrdinalIgnoreCase)) { if (string.Equals(entry.Value, "1", StringComparison.OrdinalIgnoreCase)) { flags |= SpanContextFlags.Debug; } } } if (traceId != null && spanId != null) { return(new SpanContext(traceId.Value, spanId.Value, parentId, flags)); } return(null); }
private SpanContext(TraceId?traceId, string serviceName) { TraceId = traceId ?? Tracer.Instance.TraceIdConvention.GenerateNewTraceId(); ServiceName = serviceName; }
/// <summary> /// Initializes a new instance of the <see cref="SpanContext"/> class /// from a propagated context. <see cref="Parent"/> will be null /// since this is a root context locally. /// This constructor is used by W3C propagation. /// </summary> /// <param name="traceId">The propagated trace id.</param> /// <param name="spanId">The propagated span id.</param> /// <param name="traceState">The W3C tracestate.</param> public SpanContext(TraceId?traceId, ulong spanId, string traceState) : this(traceId, serviceName : null) { SpanId = spanId; TraceState = traceState; }
public SpanContext Extract(ITextMap carrier) { // try to extract the single B3 propagation value instead var single = _singleHeaderPropagator.Extract(carrier); if (single != null) { return(single); } TraceId? traceId = null; string spanId = null; string parentId = null; var debug = false; var sampled = false; const bool shared = false; foreach (var entry in carrier) { switch (entry.Key.ToLowerInvariant()) { case B3TraceId: if (!TraceId.TryParse(entry.Value, out var t)) { throw new ZipkinFormatException( $"TraceId in format [{entry.Value}] is incompatible. Please use an X16 encoded 128bit or 64bit id."); } traceId = t; break; case B3SpanId: spanId = entry.Value; break; case B3ParentId: parentId = entry.Value; break; case B3Debug: if (entry.Value.Equals("1")) { debug = true; } break; case B3Sampled: if (entry.Value.Equals("1") || entry.Value.ToLowerInvariant().Equals("true") ) // support older tracers https://github.com/petabridge/Petabridge.Tracing.Zipkin/issues/72 { sampled = true; } break; } } if (traceId != null && spanId != null) // don't care of ParentId is null or not { return(new SpanContext(traceId.Value, spanId, parentId, debug, sampled, shared)); } return(null); }
/// <summary> /// Initializes a new instance of the <see cref="SpanContext"/> class /// from a propagated context. <see cref="Parent"/> will be null /// since this is a root context locally. /// </summary> /// <param name="traceId">The propagated trace id.</param> /// <param name="spanId">The propagated span id.</param> /// <param name="samplingPriority">The propagated sampling priority.</param> /// <param name="serviceName">The service name to propagate to child spans.</param> public SpanContext(TraceId?traceId, ulong spanId, SamplingPriority?samplingPriority = null, string serviceName = null) : this(traceId, serviceName) { SpanId = spanId; SamplingPriority = (int?)samplingPriority; }
/// <summary> /// Initializes a new instance of the <see cref="SpanContext"/> class /// that is the child of the specified parent context. /// </summary> /// <param name="parent">The parent context.</param> /// <param name="traceContext">The trace context.</param> /// <param name="serviceName">The service name to propagate to child spans.</param> /// <param name="traceId">Override the trace id if there's no parent.</param> /// <param name="spanId">The propagated span id.</param> /// <param name="rawTraceId">Raw trace id value</param> /// <param name="rawSpanId">Raw span id value</param> internal SpanContext(ISpanContext parent, TraceContext traceContext, string serviceName, TraceId?traceId = null, ulong?spanId = null, string rawTraceId = null, string rawSpanId = null) : this(parent?.TraceId ?? traceId, serviceName) { SpanId = spanId ?? SpanIdGenerator.ThreadInstance.CreateNew(); Parent = parent; TraceContext = traceContext; if (parent is SpanContext spanContext) { Origin = spanContext.Origin; RawTraceId = spanContext.RawTraceId ?? rawTraceId; } else { RawTraceId = rawTraceId; } RawSpanId = rawSpanId; }
/// <summary> /// Creates a scope for outbound http requests and populates some common details. /// </summary> /// <param name="tracer">The tracer instance to use to create the new scope.</param> /// <param name="httpMethod">The HTTP method used by the request.</param> /// <param name="requestUri">The URI requested by the request.</param> /// <param name="integrationId">The id of the integration creating this scope.</param> /// <param name="tags">The tags associated to the scope</param> /// <param name="traceId">The trace id - this id will be ignored if there's already an active trace</param> /// <param name="spanId">The span id</param> /// <param name="startTime">The start time that should be applied to the span</param> /// <param name="addToTraceContext">Set to false if the span is meant to be discarded. In that case, the span won't be added to the TraceContext.</param> /// <returns>A new pre-populated scope.</returns> internal static Span CreateInactiveOutboundHttpSpan(Tracer tracer, string httpMethod, Uri requestUri, IntegrationId integrationId, out HttpTags tags, TraceId?traceId, ulong?spanId, DateTimeOffset?startTime, bool addToTraceContext) { tags = null; if (!tracer.Settings.IsIntegrationEnabled(integrationId) || PlatformHelpers.PlatformStrategy.ShouldSkipClientSpan(tracer.InternalActiveScope) || HttpBypassHelper.UriContainsAnyOf(requestUri, tracer.Settings.HttpClientExcludedUrlSubstrings)) { // integration disabled, don't create a scope, skip this trace return(null); } Span span = null; try { if (GetActiveHttpScope(tracer) != null) { // we are already instrumenting this, // don't instrument nested methods that belong to the same stacktrace // e.g. HttpClientHandler.SendAsync() -> SocketsHttpHandler.SendAsync() return(null); } string resourceUrl = requestUri != null?UriHelpers.CleanUri(requestUri, removeScheme : true, tryRemoveIds : true) : null; string httpUrl = requestUri != null?UriHelpers.CleanUri(requestUri, removeScheme : false, tryRemoveIds : false) : null; tags = new HttpTags(); // Upstream uses "http.request" for the span name but following legacy version and the // OpenTelemetry specification we use the capitalized method as the span name. string uppercaseHttpMethod = httpMethod?.ToUpperInvariant(); string serviceName = tracer.Settings.GetServiceName(tracer, ServiceName); span = tracer.StartSpan(uppercaseHttpMethod, tags, serviceName: serviceName, traceId: traceId, spanId: spanId, startTime: startTime, addToTraceContext: addToTraceContext); span.Type = SpanTypes.Http; span.ResourceName = $"{httpMethod} {resourceUrl}"; span.LogicScope = OperationName; tags.HttpMethod = uppercaseHttpMethod; tags.HttpUrl = httpUrl; tags.InstrumentationName = IntegrationRegistry.GetName(integrationId); tags.SetAnalyticsSampleRate(integrationId, tracer.Settings, enabledWithGlobalSetting: false); if (!addToTraceContext && span.Context.TraceContext.SamplingPriority == null) { // If we don't add the span to the trace context, then we need to manually call the sampler span.Context.TraceContext.SetSamplingPriority(tracer.TracerManager.Sampler?.GetSamplingPriority(span)); } } catch (Exception ex) { Log.Error(ex, "Error creating or populating span."); } // always returns the span, even if it's null because we couldn't create it, // or we couldn't populate it completely (some tags is better than no tags) return(span); }
/// <summary> /// Creates a scope for outbound http requests and populates some common details. /// </summary> /// <param name="tracer">The tracer instance to use to create the new scope.</param> /// <param name="httpMethod">The HTTP method used by the request.</param> /// <param name="requestUri">The URI requested by the request.</param> /// <param name="integrationId">The id of the integration creating this scope.</param> /// <param name="tags">The tags associated to the scope</param> /// <param name="traceId">The trace id - this id will be ignored if there's already an active trace</param> /// <param name="spanId">The span id</param> /// <param name="startTime">The start time that should be applied to the span</param> /// <returns>A new pre-populated scope.</returns> internal static Scope CreateOutboundHttpScope(Tracer tracer, string httpMethod, Uri requestUri, IntegrationId integrationId, out HttpTags tags, TraceId?traceId = null, ulong?spanId = null, DateTimeOffset?startTime = null) { var span = CreateInactiveOutboundHttpSpan(tracer, httpMethod, requestUri, integrationId, out tags, traceId, spanId, startTime, addToTraceContext: true); if (span != null) { return(tracer.ActivateSpan(span)); } return(null); }