private void RabbitMqConsumer_Received(object sender, BasicDeliverEventArgs e) { // ExtractActivity creates the Activity setting the parent based on the RabbitMQ "traceparent" header var activity = e.ExtractActivity("Process single RabbitMQ message"); TelemetrySpan span = null; if (tracer != null) { // OpenTelemetry seems to require the Activity to have started, unlike AI SDK activity.Start(); tracer.StartActiveSpanFromActivity(activity.OperationName, activity, SpanKind.Consumer, out span); span.SetAttribute(Telemetry.Constants.RoutingKeyTagName, e.RoutingKey); } try { string message = DeserializeMessage(e.Body, e.RoutingKey); string fullTypeName = e.BasicProperties.GetCustomProperty <string>(TypeNameHeader); OnMessagedReceived(new MessageReceivedEventArgs(message, fullTypeName)); } catch (Exception ex) { logger.LogError(ex, "Unable to proccess message. Routing key: {RoutingKey}", e.RoutingKey); } finally { span?.End(); } }
internal static object Run() { var zpagesOptions = new ZPagesExporterOptions() { Url = "http://localhost:7284/rpcz/" }; var zpagesExporter = new ZPagesExporter(zpagesOptions); var spanProcessor = new ZPagesSpanProcessor(zpagesExporter); ZPagesSpans.RetentionTime = 3600000; var httpServer = new ZPagesExporterStatsHttpServer(zpagesExporter, spanProcessor); // Start the server httpServer.Start(); // Configure exporter using (var tracerFactory = TracerFactory.Create(builder => builder .AddProcessorPipeline(b => b .SetExporter(zpagesExporter) .SetExportingProcessor(e => spanProcessor)))) { var tracer = tracerFactory.GetTracer("zpages-test"); while (true) { // Create a scoped span. TelemetrySpan telemetrySpan = tracer.StartSpan("Main"); telemetrySpan.Status = Status.Unavailable; using (tracer.WithSpan(telemetrySpan)) { Console.WriteLine("Starting Span"); } Thread.Sleep(3000); telemetrySpan.End(); // Create a scoped span. TelemetrySpan telemetrySpan2 = tracer.StartSpan("TestSpan"); telemetrySpan2.Status = Status.Ok; using (tracer.WithSpan(telemetrySpan2)) { Console.WriteLine("Starting Span2"); } Thread.Sleep(5000); telemetrySpan2.End(); } } }
/// <inheritdoc /> public IKafkaMessage <TKey, TValue> Consume(CancellationToken cancellationToken = default) { TelemetrySpan span = null; Activity consumingActivity = null; try { var consumeResult = _consumer.Consume(cancellationToken); consumingActivity = new Activity(Constants.ConsumeActivityName); consumingActivity.Start(); var kafkaMessage = (KafkaMessage <TKey, TValue>)consumeResult; if (kafkaMessage.Headers?.Any() ?? false) { kafkaMessage.Headers.TryGetValue(AbstractionConstants.CorrelationIdHeaderName, out var parentActivityId); if (!string.IsNullOrEmpty(parentActivityId)) { consumingActivity.SetParentId(parentActivityId); } foreach (var baggageItem in kafkaMessage.Headers) { if (baggageItem.Key != AbstractionConstants.CorrelationIdHeaderName) { consumingActivity.AddBaggage(baggageItem.Key, baggageItem.Value); } } } span = _tracer?.StartSpanFromActivity(Constants.SpanConsumeOperationNamePrefix, consumingActivity, SpanKind.Consumer); _logger.LogDebug("Consumed message 'key {key} ' at: '{partitionOffset}'.", consumeResult.Key, consumeResult.TopicPartitionOffset); return(kafkaMessage); } catch (ConsumeException e) { _logger.LogError(e, "ConsumeException occurred: {reason}", e.Error.Reason); throw; } catch (KafkaException e) { _logger.LogError(e, "KafkaException occurred: {reason}", e.Error.Reason); throw; } finally { consumingActivity?.Stop(); span?.End(); } }
/// <inheritdoc /> public void Dispose() { Logger.Log("Scope.Dispose"); var current = AsyncLocalContext.Value; AsyncLocalContext.Value = origContext; if (current != origContext) { Logger.Log("Scope.Dispose: current != this.origContext"); } if (endSpan) { span.End(); } }
public void ToOtlpResourceSpansTest() { var spanProcessor = new Mock <SpanProcessor>(); var evenResource = new Resource(new [] { new KeyValuePair <string, object>("k0", "v0") }); var oddResource = new Resource(new [] { new KeyValuePair <string, object>("k1", "v1") }); var tracers = new[] { TracerFactory.Create(b => b.SetResource(evenResource) .AddProcessorPipeline(p => p.AddProcessor(_ => spanProcessor.Object))) .GetTracer("even", "2.4.6"), TracerFactory.Create(b => b.SetResource(oddResource) .AddProcessorPipeline(p => p.AddProcessor(_ => spanProcessor.Object))) .GetTracer("odd", "1.3.5"), }; TelemetrySpan span = null; const int numOfSpans = 10; for (var i = 0; i < numOfSpans; i++) { var isEven = i % 2 == 0; var tracer = tracers[i % 2]; var spanKind = isEven ? SpanKind.Client : SpanKind.Server; if (span == null) { span = tracer.StartRootSpan("span-0", spanKind, null); } else { span = tracer.StartSpan($"span-{i}", span.Context, spanKind, null); } span.End(); } var spanDataList = new List <SpanData>(); var invocations = spanProcessor.Invocations; for (var i = 0; i < invocations.Count; i += 2) // Just want one of the OnStart/OnEnd pair. { spanDataList.Add((SpanData)invocations[i].Arguments[0]); } spanDataList.Reverse(); var otlpResourceSpans = spanDataList.ToOtlpResourceSpans(); Assert.Equal(2, otlpResourceSpans.Count()); var evenAttribKeyValue = new OtlpCommon.AttributeKeyValue { Key = "k0" }; evenAttribKeyValue.StringValue = "v0"; foreach (var resourceSpans in otlpResourceSpans) { Assert.Single(resourceSpans.InstrumentationLibrarySpans); Assert.Equal(numOfSpans / 2, resourceSpans.InstrumentationLibrarySpans[0].Spans.Count); Assert.NotNull(resourceSpans.Resource); var expectedSpanNames = new List <string>(); var start = resourceSpans.Resource.Attributes.Contains(evenAttribKeyValue) ? 0 : 1; for (var i = start; i < numOfSpans; i += 2) { expectedSpanNames.Add($"span-{i}"); } var otlpSpans = resourceSpans.InstrumentationLibrarySpans[0].Spans; Assert.Equal(expectedSpanNames.Count, otlpSpans.Count); foreach (var otlpSpan in otlpSpans) { Assert.Contains(otlpSpan.Name, expectedSpanNames); } } }
public void Finish() { _span.End(); }