public void SetTracing(WebRequest request) { if (Agent.Tracer.CurrentTransaction == null) { return; } if (!string.IsNullOrWhiteSpace(request.Headers[TraceParent.TraceParentHeaderName])) { return; } timer = new Stopwatch(); timer.Start(); transaction = Agent.Tracer.CurrentTransaction; span = transaction.StartSpan( $"{request.Method} {request.RequestUri.Host}", "proxy", ApiConstants.SubtypeHttp); if (transaction.IsSampled) { span.Context.Http = new Http { Method = request.Method, Url = request.RequestUri.ToString() }; } request.Headers.Add(TraceParent.TraceParentHeaderName, TraceParent.BuildTraceparent(span.TraceId, span.ParentId, span.IsSampled)); }
protected override async Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancel) { if (InnerHandler == null) { InnerHandler = new HttpClientHandler(); } var transaction = GetTransaction(request); if (!request.Headers.Contains(TraceParent.TraceParentHeaderName)) { //Outgoing request var traceString = TraceParent.BuildTraceparent(transaction.TraceId, transaction.ParentId, transaction.IsSampled); request.Headers.Add(TraceParent.TraceParentHeaderName, traceString); } if (transaction.IsSampled) { RecordRequest(request, transaction); } var httpResponse = await base.SendAsync(request, cancel); transaction.Result = $"HTTP {(int)httpResponse.StatusCode}"; if (transaction.IsSampled) { RecordResponse(httpResponse, transaction); } transaction.End(); return(httpResponse); }
protected override async Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancel) { if (InnerHandler == null) { InnerHandler = new HttpClientHandler(); } if (Agent.Tracer.CurrentTransaction == null) { return(await base.SendAsync(request, cancel)); } var transaction = Agent.Tracer.CurrentTransaction; var span = transaction.StartSpan( $"{request.Method.Method} {request.RequestUri.Host}", ApiConstants.TypeExternal, ApiConstants.SubtypeHttp); if (transaction.IsSampled) { span.Context.Http = new Http { Method = request.Method.Method, Url = request.RequestUri.ToString() }; } if (!request.Headers.Contains(TraceParent.TraceParentHeaderName)) { request.Headers.Add(TraceParent.TraceParentHeaderName, TraceParent.BuildTraceparent(span.TraceId, span.ParentId, span.IsSampled)); } try { var httpResponse = await base.SendAsync(request, cancel); if (transaction.IsSampled) { span.Context.Http.StatusCode = (int)httpResponse.StatusCode; } span.End(); return(httpResponse); } catch (Exception ex) { span.CaptureException(ex); throw; } }
private void ProcessStartEvent(object eventValue, TRequest request, Uri requestUrl) { _logger.Trace()?.Log("Processing start event... Request URL: {RequestUrl}", requestUrl); if (Agent.TransactionContainer.Transactions == null || Agent.TransactionContainer.Transactions.Value == null) { _logger.Debug()?.Log("No active transaction, skip creating span for outgoing HTTP request"); return; } var transaction = Agent.TransactionContainer.Transactions.Value; var span = transaction.StartSpanInternal( $"{RequestGetMethod(request)} {requestUrl.Host}", ApiConstants.TypeExternal, ApiConstants.SubtypeHttp); if (!ProcessingRequests.TryAdd(request, span)) { // Sergey_Kleyman_TODO: Implement error handling _logger.Error()?.Log("Failed to add to ProcessingRequests - ???"); return; } if (!RequestHeadersContain(request, TraceParent.TraceParentHeaderName)) { // We call TraceParent.BuildTraceparent explicitly instead of DistributedTracingData.SerializeToString because // in the future we might change DistributedTracingData.SerializeToString to use some other internal format // but here we want the string to be in W3C 'traceparent' header format. RequestHeadersAdd(request, TraceParent.TraceParentHeaderName, TraceParent.BuildTraceparent(span.OutgoingDistributedTracingData)); } if (transaction.IsSampled) { span.Context.Http = new Http { Url = requestUrl.ToString(), Method = RequestGetMethod(request) }; var frames = new StackTrace(true).GetFrames(); var stackFrames = StacktraceHelper.GenerateApmStackTrace(frames, _logger, span.Name); span.StackTrace = stackFrames; } }
private void ProcessStartEvent(TRequest request, Uri requestUrl) { Logger.Trace()?.Log("Processing start event... Request URL: {RequestUrl}", Http.Sanitize(requestUrl)); var transaction = _agent.Tracer.CurrentTransaction; if (transaction == null) { Logger.Debug()?.Log("No current transaction, skip creating span for outgoing HTTP request"); return; } var span = (Span)ExecutionSegmentCommon.GetCurrentExecutionSegment(_agent) .StartSpan( $"{RequestGetMethod(request)} {requestUrl.Host}", ApiConstants.TypeExternal, ApiConstants.SubtypeHttp); if (!ProcessingRequests.TryAdd(request, span)) { // Consider improving error reporting - see https://github.com/elastic/apm-agent-dotnet/issues/280 Logger.Error()?.Log("Failed to add to ProcessingRequests - ???"); return; } if (!RequestHeadersContain(request, TraceParent.TraceParentHeaderName)) { // We call TraceParent.BuildTraceparent explicitly instead of DistributedTracingData.SerializeToString because // in the future we might change DistributedTracingData.SerializeToString to use some other internal format // but here we want the string to be in W3C 'traceparent' header format. RequestHeadersAdd(request, TraceParent.TraceParentHeaderName, TraceParent.BuildTraceparent(span.OutgoingDistributedTracingData)); } if (!span.ShouldBeSentToApmServer) { return; } span.Context.Http = new Http { Method = RequestGetMethod(request) }; span.Context.Http.SetUrl(requestUrl); }
private void ProcessStartEvent(object eventValue, TRequest request, Uri requestUrl) { _logger.Trace()?.Log("Processing start event... Request URL: {RequestUrl}", requestUrl); if (Agent.TransactionContainer.Transactions == null || Agent.TransactionContainer.Transactions.Value == null) { _logger.Debug()?.Log("No active transaction, skip creating span for outgoing HTTP request"); return; } var transaction = Agent.TransactionContainer.Transactions.Value; var span = transaction.StartSpanInternal( $"{RequestGetMethod(request)} {requestUrl.Host}", ApiConstants.TypeExternal, ApiConstants.SubtypeHttp); if (!ProcessingRequests.TryAdd(request, span)) { // Consider improving error reporting - see https://github.com/elastic/apm-agent-dotnet/issues/280 _logger.Error()?.Log("Failed to add to ProcessingRequests - ???"); return; } if (!RequestHeadersContain(request, TraceParent.TraceParentHeaderName)) { // We call TraceParent.BuildTraceparent explicitly instead of DistributedTracingData.SerializeToString because // in the future we might change DistributedTracingData.SerializeToString to use some other internal format // but here we want the string to be in W3C 'traceparent' header format. RequestHeadersAdd(request, TraceParent.TraceParentHeaderName, TraceParent.BuildTraceparent(span.OutgoingDistributedTracingData)); } if (transaction.IsSampled) { span.Context.Http = new Http { Url = requestUrl.ToString(), Method = RequestGetMethod(request) }; } }
/// <summary> /// Serializes this instance to a string. /// This method should be used at the caller side and the return value should be passed to the (possibly remote) callee /// side. /// <see cref="TryDeserializeFromString" /> should be used to deserialize the instance at the callee side. /// </summary> /// <returns> /// String containing the instance in serialized form. /// </returns> public string SerializeToString() => TraceParent.BuildTraceparent(this);