public async Task Handle(SpanEndedDomainEvent notification, CancellationToken cancellationToken)
 {
     if (this.exporters != null && notification?.Span != null)
     {
         // https://github.com/open-telemetry/opentelemetry-dotnet/blob/master/src/OpenTelemetry.Exporter.Zipkin/ZipkinTraceExporter.cs
         // TODO: queue some spans before exporting (threshold)
         foreach (var exporter in this.exporters)
         {
             await exporter.ExportAsync(new[] { notification.Span }, cancellationToken).AnyContext();
         }
     }
 }
Пример #2
0
        public Task Handle(SpanEndedDomainEvent notification, CancellationToken cancellationToken)
        {
            if (notification?.Span != null)
            {
                using (this.logger.BeginScope(new Dictionary <string, object>()
                {
                    // map Span to LogTrace properties
                    [LogPropertyKeys.TrackType] = LogTrackTypes.Trace,
                    [LogPropertyKeys.TrackName] = notification.Span.OperationName,
                    [LogPropertyKeys.TrackTraceId] = notification.Span.TraceId,
                    [LogPropertyKeys.TrackId] = notification.Span.SpanId,
                    [LogPropertyKeys.TrackParentId] = notification.Span.ParentSpanId,
                    [LogPropertyKeys.TrackKind] = notification.Span.Kind?.ToString(),
                    [LogPropertyKeys.TrackStatus] = notification.Span.Status?.ToString(),
                    [LogPropertyKeys.TrackStatusDescription] = notification.Span.StatusDescription,
                    [LogPropertyKeys.TrackStartTime] = notification.Span.StartTime?.ToString("o"),
                    [LogPropertyKeys.TrackEndTime] = notification.Span.EndTime?.ToString("o")
                                                     // TODO: map all TAGS/LOGS/BAG
                }))
                {
                    try
                    {
                        this.logger.Log(LogLevel.Information, $"{{LogKey:l}} {notification.Span.OperationName:l}", notification.Span.LogKey);
                    }
                    catch (AggregateException ex) // IndexOutOfRangeException
                    {
                        if (ex.InnerException is IndexOutOfRangeException)
                        {
                            this.logger.Log(LogLevel.Warning, $"{{LogKey:l}} {notification.Span.OperationName:l}");
                        }
                        else
                        {
                            throw;
                        }
                    }
                }
            }

            return(Task.CompletedTask);
        }
        public Task Handle(SpanEndedDomainEvent notification, CancellationToken cancellationToken)
        {
            if (notification?.Span != null)
            {
                var duration = TimeSpan.Zero;
                if (notification.Span.EndTime.HasValue && notification.Span.StartTime.HasValue)
                {
                    duration = notification.Span.EndTime.Value - notification.Span.StartTime.Value;
                }

                if (notification.Span.Status == SpanStatus.Failed)
                {
                    this.logger.LogError($"{{LogKey:l}} span failed: {notification.Span.OperationName} (id={notification.Span.SpanId}, parent={notification.Span.ParentSpanId}, kind={notification.Span.Kind}) {notification.Span.StatusDescription} -> took {duration.Humanize()}", LogKeys.Tracing);
                }
                else
                {
                    this.logger.LogDebug($"{{LogKey:l}} span finished: {notification.Span.OperationName} (id={notification.Span.SpanId}, parent={notification.Span.ParentSpanId}, kind={notification.Span.Kind}) {notification.Span.StatusDescription} -> took {duration.Humanize()}", LogKeys.Tracing);
                }
            }

            return(Task.CompletedTask);
        }
 public bool CanHandle(SpanEndedDomainEvent notification)
 {
     return(notification?.Span != null);
 }