public EndMethodDelegate BeforeWrappedMethod(TraceMethodInfo traceMethodInfo) { var request = (HttpRequestMessage)traceMethodInfo.MethodArguments[0]; var scope = _tracer.BuildSpan("http.out") .WithTag(Tags.SpanKind, Tags.SpanKindClient) .WithTag(Tags.Component, "HttpClient") .WithTag(Tags.HttpMethod, request.Method.ToString()) .WithTag(Tags.HttpUrl, request.RequestUri.ToString()) .WithTag(Tags.PeerHostname, request.RequestUri.Host) .WithTag(Tags.PeerPort, request.RequestUri.Port) .StartActive(false); _tracer.Inject(scope.Span.Context, BuiltinFormats.HttpHeaders, new HttpHeadersInjectAdapter(request.Headers)); traceMethodInfo.TraceContext = scope; return(delegate(object returnValue, Exception ex) { DelegateHelper.AsyncMethodEnd(Leave, traceMethodInfo, ex, returnValue); // for async method , at method end restore active scope, important var tempScope = (IScope)traceMethodInfo.TraceContext; tempScope.Dispose(); }); }
private string FormatString(string helloTo) { using (var scope = _tracer.BuildSpan("format-string").StartActive(true)) { var url = $"http://localhost:8081/api/format/{helloTo}"; var span = _tracer.ActiveSpan .SetTag(Tags.SpanKind, Tags.SpanKindClient) .SetTag(Tags.HttpMethod, "GET") .SetTag(Tags.HttpUrl, url); var dictionary = new Dictionary <string, string>(); _tracer.Inject(span.Context, BuiltinFormats.HttpHeaders, new TextMapInjectAdapter(dictionary)); foreach (var entry in dictionary) { _webClient.Headers.Add(entry.Key, entry.Value); } var helloString = _webClient.DownloadString(url); scope.Span.Log(new Dictionary <string, object> { [LogFields.Event] = "string.Format", ["value"] = helloString }); return(helloString); } }
public void Publish <T>(string exchangeName, string routingKey, T content) { string serializedContent = JsonConvert.SerializeObject(content, Formatting.Indented); using (IConnection con = this.GetConnection()) using (IModel model = this.GetModel(con)) { using (var scope = _tracer.BuildSpan("RabbitMQ").StartActive(finishSpanOnDispose: true)) { var span = scope.Span.SetTag(Tags.SpanKind, Tags.SpanKindClient); this._sharedTracing.CorrelationId = new Dictionary <string, string>(); _tracer.Inject(span.Context, BuiltinFormats.TextMap, new TextMapInjectAdapter(this._sharedTracing.CorrelationId)); scope.Span.Log("Enviando dado para a fila."); model.QueueDeclare(queue: this._queueName, durable: false, exclusive: false, autoDelete: false, arguments: null); IBasicProperties properties = model.CreateBasicProperties(); properties.Persistent = true; properties.Headers = new Dictionary <string, object>(); properties.Headers.Add("tracing", JsonConvert.SerializeObject(this._sharedTracing.CorrelationId)); byte[] payload = Encoding.UTF8.GetBytes(serializedContent); model.BasicPublish(exchangeName, routingKey, properties, payload); } } }
public async Task InvokeAsync(ClientActionExecutingContext context, ITracer tracer, IOptions <OpenTracingOptions> options) { if (context.ContractMethod.IsTracerIgnore) { await _next(context); return; } var injectDic = new Dictionary <string, string>(); using var scope = tracer.BuildSpan($"{context.ContractMethod.MethodInfo.Name} {ConstValue.SendStr}").StartActive(true); tracer.Inject(scope.Span.Context, BuiltinFormats.HttpHeaders, new TextMapInjectAdapter(injectDic)); foreach (var dic in injectDic) { context.Header[dic.Key] = dic.Value; } try { await _next(context); scope.Span.SetTag("Connection", context.OnceCall.ConnectionInfo.ToString()); scope.Span.SetTagReturn(context, options.Value.LogActionInfoMaxLength); scope.Span.SetTagMethodObj(context, options.Value.LogActionInfoMaxLength); } catch (Exception e) { scope.Span.SetTagMethodObj(context, 0, true); scope.Span.SetTagReturn(context, 0, true); scope.Span.SetTag(new StringTag("Exception"), e.ExceptionToString()); throw; } }
public void Publish(IntegrationEvent @event) { if (!_connection.IsConnected) { _connection.TryConnect(); } var policy = RetryPolicy.Handle <NATSException>() .WaitAndRetry(3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), (ex, time) => { _logger.LogWarning(ex, "Could not publish event: {EventId} after {Timeout}s ({ExceptionMessage})", @event.Id, $"{time.TotalSeconds:n1}", ex.Message); }); var eventName = @event.GetType().Name; using var tracingScope = _tracer.BuildSpan($"EventBus-Publish-{eventName}") .WithTag(Tags.SpanKind.Key, Tags.SpanKindServer) .WithTag(Tags.PeerHostname, Environment.MachineName) .StartActive(finishSpanOnDispose: true); var dictionary = new Dictionary <string, string>(); _tracer.Inject(tracingScope.Span.Context, BuiltinFormats.TextMap, new TextMapInjectAdapter(dictionary)); @event.TracingKeys = dictionary; var msg = JsonSerializer.Serialize(@event); var body = Encoding.UTF8.GetBytes(msg); policy.Execute(() => { _connection.NatsConnection.Publish(eventName, body); _connection.NatsConnection.Flush(); }); }
protected override async Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { var spanBuilder = _tracer.BuildSpan($"Fetch HTTP {request.Method.Method} {request.RequestUri.GetLeftPart(UriPartial.Path)}") .WithTag(Tags.SpanKind, Tags.SpanKindClient) .WithTag(Tags.HttpMethod, request.Method.ToString()) .WithTag(Tags.HttpUrl, request.RequestUri.ToString()) .WithTag(Tags.PeerHostname, request.RequestUri.Host) .WithTag(Tags.PeerPort, request.RequestUri.Port); using var scope = spanBuilder.StartActive(); _tracer.Inject(scope.Span.Context, BuiltinFormats.HttpHeaders, new HttpHeadersInjectAdapter(request.Headers)); try { var result = await base.SendAsync(request, cancellationToken); Tags.HttpStatus.Set(scope.Span, (int)result.StatusCode); if (!result.IsSuccessStatusCode) { Tags.Error.Set(scope.Span, true); } return(result); } catch (Exception ex) { Tags.Error.Set(scope.Span, true); scope.Span.SetTag("http.exception", ex.Message); throw; } }
public Task PublishAsync <T>(T message, CancellationToken cancellationToken = default, Action <MessagingEnvelope> customizer = null, string topicName = null) { void NewCustomizer(MessagingEnvelope outgoingEnvelope) { if (_tracer.ActiveSpan != null) { _tracer.Inject(_tracer.ActiveSpan.Context, BuiltinFormats.TextMap, new TextMapInjectAdapter(outgoingEnvelope.Headers)); } customizer?.Invoke(outgoingEnvelope); } var formattedTopicName = _topicRegistry.GetTopicForName(topicName) ?? _topicRegistry.GetTopicForMessageType(message.GetType()); var operationName = $"Publisher {message.GetType().GetPrettyName()}"; using (var scope = _tracer.BuildSpan(operationName) .WithTag(Tags.Component, MessagingTags.ComponentMessaging) .WithTag(Tags.SpanKind, Tags.SpanKindProducer) .WithTag(Tags.MessageBusDestination, formattedTopicName) .WithTag(MessagingTags.CorrelationId, CorrelationManager.GetCorrelationId()?.ToString()) .StartActive(true)) { try { return(_inner.PublishAsync(message, cancellationToken, NewCustomizer, topicName)); } catch (Exception exception) { scope.Span.SetException(exception); throw; } } }
public Task PublishAsync <T>(T message, MessagingPublisherOptions options = null, CancellationToken cancellationToken = default) { options ??= MessagingPublisherOptions.Default; void NewCustomizer(MessagingEnvelope outgoingEnvelope) { if (_tracer.ActiveSpan != null) { _tracer.Inject(_tracer.ActiveSpan.Context, BuiltinFormats.TextMap, new TextMapInjectAdapter(outgoingEnvelope.Headers)); } options.EnvelopeCustomizer?.Invoke(outgoingEnvelope); } var formattedTopicName = _topicRegistry.GetTopicForName(options.TopicName) ?? _topicRegistry.GetTopicForMessageType(message.GetType()); var operationName = $"Publisher {message.GetType().GetPrettyName()}"; using (var scope = _tracer.BuildSpan(operationName) .WithTag(Tags.Component, MessagingTags.ComponentMessaging) .WithTag(Tags.SpanKind, Tags.SpanKindProducer) .WithTag(Tags.MessageBusDestination, formattedTopicName) .WithTag(MessagingTags.CorrelationId, CorrelationManager.GetCorrelationId()?.ToString()) .StartActive(true)) { try { return(_inner.PublishAsync(message, options with { EnvelopeCustomizer = NewCustomizer }, cancellationToken)); }
public async Task <Guid> Handle(SubmitBatchCommand request, CancellationToken cancellationToken) { using (var scope = _tracer.BuildSpan("batch-submit-command").StartActive(true)) { var span = scope.Span.SetTag(Tags.SpanKind, Tags.SpanKindServer); var dictionary = new Dictionary <string, string>(); _tracer.Inject(span.Context, BuiltinFormats.TextMap, new TextMapInjectAdapter(dictionary)); var batchId = Guid.NewGuid(); var batchUri = _batchUriGenerator.GenerateBatchUri(request.HealthcareProviderId, batchId); using (var stream = request.BatchJsonFile.OpenReadStream()) { var batch = new Batch( batchId, batchUri, stream); await _batchRepository.AddBatchAsync(batch); } await _batchRepository.SaveChangesAsync(cancellationToken); EnqueueFeedbackGenerationBackgroundJob(batchId, dictionary); return(batchId); } }
private void SetupTraceHeaders(IScope scope, HttpContext context) { if (scope == null || context == null) { return; } scope.Span.SetTag(Tags.Component, "Tracing.Middleware.Action"); scope.Span.SetTag(Tags.HttpMethod, context.Request.Method); // Setup B3 headers var traceHeaders = new Dictionary <string, string>(); _tracer.Inject(scope.Span.Context, BuiltinFormats.HttpHeaders, new TextMapInjectAdapter(traceHeaders)); context.Items.Add("OpenTraceHeaders", traceHeaders); // Set diagnostics context for LoggingFactory _diagnosticContext.Set("TraceId", scope.Span.Context.TraceId); _diagnosticContext.Set("SpanId", scope.Span.Context.SpanId); // Set B3 Response headers prior to the _next delegate // Response will already be buffering foreach (var pair in traceHeaders) { context.Response.Headers.Add(pair.Key, pair.Value); } }
public async Task <BaseResponse <int> > CreateUserAsync(CreateUserRequest request) { BaseResponse <int> createUserResponse = new BaseResponse <int>(); try { using (var scope = _tracer.BuildSpan("create-user-async").StartActive(finishSpanOnDispose: true)) { var span = scope.Span.SetTag(Tags.SpanKind, Tags.SpanKindClient); var dictionary = new Dictionary <string, string>(); _tracer.Inject(span.Context, BuiltinFormats.TextMap, new TextMapInjectAdapter(dictionary)); //some user create business logics createUserResponse.Data = 1; // User id await _busControl.Publish(new UserRegisteredEvent { Email = request.Email, TracingKeys = dictionary }); } } catch (Exception ex) { createUserResponse.Errors.Add(ex.Message); _logger.LogError(ex, ex.Message); } return(createUserResponse); }
public IDictionary <string, string> GetTracingHeaders() { var dictionary = new Dictionary <string, string>(); _tracer.Inject(_tracer.ActiveSpan.Context, BuiltinFormats.HttpHeaders, new TextMapInjectAdapter(dictionary)); return(dictionary); }
/// <summary> /// Injects the specified tracer. /// </summary> /// <param name="message">The message.</param> /// <param name="tracer">The tracer.</param> /// <param name="context">The context.</param> /// <param name="headers">The headers.</param> public static void Inject(this IMessage message, ITracer tracer, ISpanContext context, IStandardHeaders headers) { var mapping = new DataMappingTextMap(); tracer.Inject(context, BuiltinFormats.TextMap, mapping); message.SetHeader(headers.TraceSpan, mapping); }
public static void Inject <T>(this ITracer tracer, ISpanContext spanContext, T carrier, Action <T, string, string> injector) where T : class, IEnumerable { if (tracer == null) { throw new ArgumentNullException(nameof(tracer)); } tracer.Inject(spanContext, new TextMapCarrierWriter(), new DelegatingCarrier <T>(carrier, injector)); }
public static TracingHeaders GetInjectHeaders(this ITracer tracer) { if (tracer != null && tracer.ActiveSpan != null) { var headers = new TracingHeaders(); tracer.Inject(tracer.ActiveSpan.Context, BuiltinFormats.TextMap, new BrokerHeadersInjectAdapter(headers)); return(headers); } return(null); }
private bool AddSpanContext(IActorRef receiver, IActorRef sender, ref object message) { IScope scope = _tracer.ScopeManager.Active; if (!(message is TracedMessage) && scope?.Span != null) { var tm = new TracedMessage(message, null); _tracer.Inject(scope.Span.Context, BuiltinFormats.TextMap, new TextMapInjectAdapter(tm.Context)); message = tm; return(true); } return(false); }
public void Send() { var message = new Message(); using (IScope scope = _tracer.BuildSpan("send") .WithTag(Tags.SpanKind.Key, Tags.SpanKindClient) .WithTag(Tags.Component.Key, "example-client") .StartActive(finishSpanOnDispose: true)) { _tracer.Inject(scope.Span.Context, BuiltinFormats.TextMap, new TextMapInjectAdapter(message)); _queue.Add(message); } }
public void Publish(string topicName, Event @event, Dictionary <string, string> headers) { try { var message = new Message <Null, Event> { Value = @event, Headers = new Headers() }; //add correlation headers _producer.OnError += (_, e) => { if (e.IsBrokerError || e.IsFatal) { _logger.LogError($"error on the Producer: [{e.Reason} [{e.Code}]]"); } }; if (_tracer != null) { using (var scope = _tracer.BuildSpan(SpanKindProducer).StartActive(true)) { var span = _tracer.ActiveSpan .SetTag(Tags.SpanKind, Tags.SpanKindProducer) .SetTag(Tags.MessageBusDestination, topicName); _tracer.Inject(span.Context, BuiltinFormats.HttpHeaders, new TextMapInjectAdapter(headers)); //add correlation headers SetHeaders(headers, message.Headers); //TenantContext :set current context header for tenant,facility _contextHeaders.SetContextHeaders(ContextHeader, message.Headers); _producer.ProduceAsync(topicName, message) .GetAwaiter() .GetResult(); } } else { SetHeaders(headers, message.Headers); _producer.ProduceAsync(topicName, message).GetAwaiter().GetResult(); } } catch (KafkaException e) { _logger.LogError(e, $"failed to deliver message: {e.Message} [{e.Error.Code}]"); throw; } }
private void InjectIfCallingService(IScope scope) { if (_willCallService) { var dictionary = new Dictionary <string, string>(); _tracer.Inject(scope.Span.Context, BuiltinFormats.HttpHeaders, new TextMapInjectAdapter(dictionary)); foreach (var entry in dictionary) { _httpClient.DefaultRequestHeaders.Add(entry.Key, entry.Value); } } _willCallService = false; }
/// <summary> /// (Extension method) Convenience overload of BasicPublish. /// </summary> /// <remarks> /// The publication occurs with mandatory=false /// </remarks> public static void BasicPublish(this IModel model, string exchange, string routingKey, IBasicProperties basicProperties, ReadOnlyMemory<byte> body, ITracer tracer) { var spanBuilder = SpanBuilderHelper.BuildPublisherSpan(exchange, routingKey, basicProperties, tracer); using (spanBuilder.StartActive()) { tracer.Inject( tracer.ActiveSpan.Context, BuiltinFormats.TextMap, new RabbitMqTextMapInjectAdapter(basicProperties.Headers)); model.BasicPublish(exchange, routingKey, false, basicProperties, body); } }
private static Metadata CreateInjectMetadataFromSpan(ITracer tracer, ISpan span) { var dict = new Dictionary <string, string>(); var injectAdapter = new TextMapInjectAdapter(dict); tracer.Inject(span.Context, BuiltinFormats.HttpHeaders, injectAdapter); var meta = new Metadata(); foreach (var entry in dict) { meta.Add(entry.Key, entry.Value); } return(meta); }
public static Dictionary <string, string> InjectWithTags(this ITracer tracer, string httpMethod, string httpUrl) { ISpan activeSpan = tracer.ActiveSpan; activeSpan .SetTag(Tags.SpanKind, Tags.SpanKindClient) .SetTag(Tags.HttpMethod, httpMethod) .SetTag(Tags.HttpUrl, httpUrl); var dictionary = new Dictionary <string, string>(); tracer.Inject(activeSpan.Context, BuiltinFormats.HttpHeaders, new TextMapInjectAdapter(dictionary)); return(dictionary); }
public async Task PushDocument <TMessage>(TMessage message, string key, Dictionary <string, string>?headers = null) { if (_isInitialized == false) { throw new InvalidOperationException("Initialize bus before use"); } var span = _tracer.BuildSpan(nameof(PushDocument)).Start(); var properties = new MessageProperties { ContentType = MediaTypeNames.Application.Json, DeliveryMode = 2 }; var carrier = new RabbitInjectAdapter(properties.Headers); _tracer.Inject(_tracer.ActiveSpan.Context, BuiltinFormats.HttpHeaders, carrier); properties.Headers.Add(MessageKeyHeader, key); if (headers != null) { foreach (var header in headers) { properties.Headers.Add(header.Key, header.Value); } } //TODO включить паблиш конфермс await _bus.Advanced .PublishAsync(_exchange, _settings.RoutingKey, true, new Message <TMessage>(message, properties)) .ConfigureAwait(false); span.Finish(); }
public async Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken, Action <string> addTraceIdToRepo, Func <HttpRequestMessage, CancellationToken, Task <HttpResponseMessage> > baseSendAsync) { using (IScope scope = _tracer.BuildSpan(request.RequestUri.AbsoluteUri).StartActive(finishSpanOnDispose: true)) { var span = scope.Span; span.SetTag(Tags.SpanKind, Tags.SpanKindClient) .SetTag(Tags.HttpMethod, request.Method.Method) .SetTag(Tags.HttpUrl, request.RequestUri.OriginalString); addTraceIdToRepo(span.Context.SpanId); var headers = new Dictionary <string, string>(); _tracer.Inject(span.Context, BuiltinFormats.HttpHeaders, new TextMapInjectAdapter(headers)); foreach (var item in headers) { request.Headers.Add(item.Key, item.Value); } try { var response = await baseSendAsync(request, cancellationToken); span.SetTag(Tags.HttpStatus, (int)response.StatusCode); return(response); } catch (HttpRequestException ex) { Tags.Error.Set(scope.Span, true); span.Log(new Dictionary <string, object>(3) { { LogFields.Event, Tags.Error.Key }, { LogFields.ErrorKind, ex.GetType().Name }, { LogFields.ErrorObject, ex } }); throw; } } }
public static IScope CreateAndInjectActiveConsumerScopeFrom(this ITracer tracer, IDictionary <string, string> headers) { var spanBuilder = tracer.BuildSpan("receive") .WithTag(Tags.SpanKind.Key, Tags.SpanKindConsumer); var parentSpanContext = tracer.Extract(BuiltinFormats.TextMap, new TextMapExtractAdapter(headers)); spanBuilder.AddReference(References.FollowsFrom, parentSpanContext); var scope = spanBuilder.StartActive(true); tracer.Inject(scope.Span.Context, BuiltinFormats.TextMap, new TextMapInjectAdapter(headers)); return(scope); }
public static IScope CreateAndInjectActiveProducerScopeFrom(this ITracer tracer, IDictionary <string, string> headers) { var spanBuilder = tracer.BuildSpan("send") .WithTag(Tags.SpanKind.Key, Tags.SpanKindProducer); var spanContext = tracer.Extract(BuiltinFormats.TextMap, new TextMapExtractAdapter(headers)); spanBuilder.AsChildOf(spanContext); var scope = spanBuilder.StartActive(true); tracer.Inject(scope.Span.Context, BuiltinFormats.TextMap, new TextMapInjectAdapter(headers)); return(scope); }
protected override async Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { ISpan span = _tracer.BuildSpan("HttpRequest") .WithTag(Tags.SpanKind, Tags.SpanKindClient) .WithTag(Tags.Component, "LibWebAPI.Http") .WithTag(Tags.HttpMethod, request.Method.ToString()) .WithTag(Tags.HttpUrl, request.RequestUri.ToString()) .WithTag(Tags.PeerHostname, request.RequestUri.Host) .WithTag(Tags.PeerPort, request.RequestUri.Port) .Start(); _tracer.Inject(span.Context, BuiltinFormats.HttpHeaders, new HttpHeadersInjectAdapter(request.Headers)); HttpResponseMessage? response = null; Task <HttpResponseMessage>?requestTask = null; try { requestTask = base.SendAsync(request, cancellationToken); response = await requestTask; } catch (System.Net.Http.HttpRequestException e) { span.SetException(e); throw; } finally { if (response != null) { span.SetTag(Tags.HttpStatus, (int)response.StatusCode); } if (requestTask != null) { TaskStatus?requestTaskStatus = requestTask?.Status; if (requestTaskStatus == TaskStatus.Canceled || requestTaskStatus == TaskStatus.Faulted) { span.SetTag(Tags.Error, true); } } span.Finish(); } return(response); }
/// <summary> /// (Spec method) Convenience overload of BasicPublish. /// </summary> public static void BasicPublish(this IModel model, string exchange, string routingKey, ITracer tracer, bool mandatory = false, IBasicProperties basicProperties = null, ReadOnlyMemory<byte> body = default) { var props = model.CreateBasicProperties(); props.Headers = new Dictionary<string, object>(); var spanBuilder = SpanBuilderHelper.BuildPublisherSpan(exchange, routingKey, props, tracer); using (spanBuilder.StartActive()) { tracer.Inject( tracer.ActiveSpan.Context, BuiltinFormats.TextMap, new RabbitMqTextMapInjectAdapter(props.Headers)); model.BasicPublish(exchange, routingKey, mandatory, props, body); } }
public Task Handle(BatchVettingCompletedEvent notification, CancellationToken cancellationToken) { var activeSpan = _tracer.ActiveSpan; var dictionary = new Dictionary <string, string>(); if (activeSpan != null) { _tracer.Inject(activeSpan.Context, BuiltinFormats.TextMap, new TextMapInjectAdapter(dictionary)); } _logger.LogInformation( "Batch vetting completed for batch {BatchId}, {BatchUri} - report URI: {VettingReportUri}", notification.BatchId, notification.BatchUri, notification.VettingReportUri); return(Task.CompletedTask); }
public static IScope StartParentSpan( this ITracer tracer, [CallerMemberName] string?callerMethodName = default, [CallerFilePath] string?callerFilePath = default) { var operationName = GetOperationName(callerMethodName, callerFilePath); var scope = tracer .BuildSpan(operationName) .StartActive(); tracer.Inject( scope.Span.Context, format: BuiltinFormats.TextMap, carrier: new TextMapInjectAdapter(_textMap)); return(scope); }