public void ValidateTraceParentWithInvalidTraceIdLength() { const string traceParent = "00-0af7651916cd43dd8448eb211c80319ca-7ad6b7169203331-01"; //TraceId is 1 char longer than expected, and parentId is 1 char longer var res = TraceParent.TryExtractTraceparent(traceParent); res.Should().BeNull(); }
public void ValidateTraceParentWithInvalidLength() { const string traceParent = "99-af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01"; //TraceId is 1 char shorter than expected var res = TraceParent.TryExtractTraceparent(traceParent); res.Should().BeNull(); }
public void ParseTraceparentHeader() { const string traceParent = "00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01"; var res = TraceParent.TryExtractTraceparent(traceParent); Debug.WriteLine($"{res}"); }
private Transaction StartTransaction(HttpContext context) { try { Transaction transaction; var transactionName = $"{context.Request.Method} {context.Request.Path}"; if (context.Request.Headers.ContainsKey(TraceParent.TraceParentHeaderName)) { var headerValue = context.Request.Headers[TraceParent.TraceParentHeaderName].ToString(); var distributedTracingData = TraceParent.TryExtractTraceparent(headerValue); if (distributedTracingData != null) { _logger.Debug() ?.Log( "Incoming request with {TraceParentHeaderName} header. DistributedTracingData: {DistributedTracingData}. Continuing trace.", TraceParent.TraceParentHeaderName, distributedTracingData); transaction = _tracer.StartTransactionInternal( transactionName, ApiConstants.TypeRequest, distributedTracingData); } else { _logger.Debug() ?.Log( "Incoming request with invalid {TraceParentHeaderName} header (received value: {TraceParentHeaderValue}). Starting trace with new trace id.", TraceParent.TraceParentHeaderName, headerValue); transaction = _tracer.StartTransactionInternal(transactionName, ApiConstants.TypeRequest); } } else { _logger.Debug()?.Log("Incoming request. Starting Trace."); transaction = _tracer.StartTransactionInternal(transactionName, ApiConstants.TypeRequest); } if (transaction.IsSampled) { FillSampledTransactionContextRequest(context, transaction); } return(transaction); } catch (Exception ex) { _logger?.Error()?.LogException(ex, "Exception thrown while trying to start transaction"); return(null); } }
private static DistributedTracingData ExtractIncomingDistributedTracingData(HttpRequest httpRequest) { var headerValue = httpRequest.Headers.Get(TraceParent.TraceParentHeaderName); if (headerValue == null) { Logger.Debug()?.Log("Incoming request doesn't {TraceParentHeaderName} header - " + "it means request doesn't have incoming distributed tracing data", TraceParent.TraceParentHeaderName); return(null); } return(TraceParent.TryExtractTraceparent(headerValue)); }
public void ValidateTraceParentWithFutureVersion() { const string traceParent = "99-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01"; //Best attempt, even if it's a future version we still try to read the traceId and parentId var res = TraceParent.TryExtractTraceparent(traceParent); res.Should().NotBeNull(); res.TraceId.Should().Be("0af7651916cd43dd8448eb211c80319c"); res.ParentId.Should().Be("b7ad6b7169203331"); res.FlagRecorded.Should().BeTrue(); }
public void ParseValidTraceParentRecorded() { const string traceParent = "00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01"; var res = TraceParent.TryExtractTraceparent(traceParent); res.Should().NotBeNull(); res.TraceId.Should().Be("0af7651916cd43dd8448eb211c80319c"); res.ParentId.Should().Be("b7ad6b7169203331"); res.FlagRecorded.Should().BeTrue(); //try also with flag options C6 const string traceParent2 = "00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-E7"; var res2 = TraceParent.TryExtractTraceparent(traceParent2); res2.FlagRecorded.Should().BeTrue(); }
public async Task InvokeAsync(HttpContext context) { Transaction transaction; var transactionName = $"{context.Request.Method} {context.Request.Path}"; if (context.Request.Headers.ContainsKey(TraceParent.TraceParentHeaderName)) { var headerValue = context.Request.Headers[TraceParent.TraceParentHeaderName].ToString(); var distributedTracingData = TraceParent.TryExtractTraceparent(headerValue); if (distributedTracingData != null) { _logger.Debug() ?.Log( "Incoming request with {TraceParentHeaderName} header. DistributedTracingData: {DistributedTracingData}. Continuing trace.", TraceParent.TraceParentHeaderName, distributedTracingData); transaction = _tracer.StartTransactionInternal( transactionName, ApiConstants.TypeRequest, distributedTracingData); } else { _logger.Debug() ?.Log( "Incoming request with invalid {TraceParentHeaderName} header (received value: {TraceParentHeaderValue}). Starting trace with new trace id.", TraceParent.TraceParentHeaderName, headerValue); transaction = _tracer.StartTransactionInternal(transactionName, ApiConstants.TypeRequest); } } else { _logger.Debug()?.Log("Incoming request. Starting Trace."); transaction = _tracer.StartTransactionInternal(transactionName, ApiConstants.TypeRequest); } if (transaction.IsSampled) { FillSampledTransactionContextRequest(context, transaction); } try { await _next(context); } catch (Exception e) when((Helpers.ExceptionFilter.Capture(e, transaction, context, _configurationReader, _logger))) { } finally { if (!transaction.HasCustomName) { //fixup Transaction.Name - e.g. /user/profile/1 -> /user/profile/{id} var routeData = (context.Features[typeof(IRoutingFeature)] as IRoutingFeature)?.RouteData; if (routeData != null) { var name = GetNameFromRouteContext(routeData.Values); if (!string.IsNullOrWhiteSpace(name)) { transaction.Name = $"{context.Request.Method} {name}"; } } } transaction.Result = Transaction.StatusCodeToResult(GetProtocolName(context.Request.Protocol), context.Response.StatusCode); if (transaction.IsSampled) { FillSampledTransactionContextResponse(context, transaction); FillSampledTransactionContextUser(context, transaction); } transaction.End(); } }
/// <summary> /// Deserializes an instance from a string. /// This method should be used at the callee side and the deserialized instance can be passed to /// <see cref="ITracer.StartTransaction" />. /// </summary> /// <param name="serialized">should be a return value from a call to <see cref="SerializeToString" />.</param> /// <returns> /// Instance deserialized from /// <param name="serialized" /> /// . /// </returns> public static DistributedTracingData TryDeserializeFromString(string serialized) => TraceParent.TryExtractTraceparent(serialized);