diff --git a/examples/kafka/ProduceConsumeHostedService.cs b/examples/kafka/ProduceConsumeHostedService.cs index 04d14dd893..ae8754c23a 100644 --- a/examples/kafka/ProduceConsumeHostedService.cs +++ b/examples/kafka/ProduceConsumeHostedService.cs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: Apache-2.0 using Confluent.Kafka; -using OpenTelemetry.Instrumentation.ConfluentKafka; namespace Examples.ConfluentKafka; diff --git a/examples/kafka/Program.cs b/examples/kafka/Program.cs index fe9c6dbcdd..afd1a99a85 100644 --- a/examples/kafka/Program.cs +++ b/examples/kafka/Program.cs @@ -3,7 +3,6 @@ using Confluent.Kafka; using Examples.ConfluentKafka; -using OpenTelemetry.Instrumentation.ConfluentKafka; using OpenTelemetry.Metrics; using OpenTelemetry.Trace; diff --git a/src/OpenTelemetry.Exporter.Geneva/.publicApi/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.Geneva/.publicApi/PublicAPI.Shipped.txt index b07b736be2..c503b19aa8 100644 --- a/src/OpenTelemetry.Exporter.Geneva/.publicApi/PublicAPI.Shipped.txt +++ b/src/OpenTelemetry.Exporter.Geneva/.publicApi/PublicAPI.Shipped.txt @@ -46,13 +46,13 @@ override OpenTelemetry.Exporter.Geneva.GenevaTraceExporter.Dispose(bool disposin ~override OpenTelemetry.Exporter.Geneva.GenevaLogExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult ~override OpenTelemetry.Exporter.Geneva.GenevaMetricExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult ~override OpenTelemetry.Exporter.Geneva.GenevaTraceExporter.Export(in OpenTelemetry.Batch batch) -> OpenTelemetry.ExportResult -~static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.LoggerProviderBuilder builder) -> OpenTelemetry.Logs.LoggerProviderBuilder -~static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.LoggerProviderBuilder builder, string name, System.Action configureExporter) -> OpenTelemetry.Logs.LoggerProviderBuilder -~static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.LoggerProviderBuilder builder, System.Action configureExporter) -> OpenTelemetry.Logs.LoggerProviderBuilder -~static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions options, System.Action configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions -~static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder -~static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder -~static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure) -> OpenTelemetry.Trace.TracerProviderBuilder -~static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, string name, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder -~static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure) -> OpenTelemetry.Metrics.MeterProviderBuilder +static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! builder) -> OpenTelemetry.Logs.LoggerProviderBuilder! +static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! builder, string? name, System.Action? configureExporter) -> OpenTelemetry.Logs.LoggerProviderBuilder! +static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.LoggerProviderBuilder! builder, System.Action! configureExporter) -> OpenTelemetry.Logs.LoggerProviderBuilder! +static Microsoft.Extensions.Logging.GenevaLoggingExtensions.AddGenevaLogExporter(this OpenTelemetry.Logs.OpenTelemetryLoggerOptions! options, System.Action? configure) -> OpenTelemetry.Logs.OpenTelemetryLoggerOptions! +static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder! builder, string? name, System.Action? configure) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Exporter.Geneva.GenevaExporterHelperExtensions.AddGenevaTraceExporter(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action! configure) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder! builder) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, string? name, System.Action? configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Exporter.Geneva.GenevaMetricExporterExtensions.AddGenevaMetricExporter(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, System.Action! configure) -> OpenTelemetry.Metrics.MeterProviderBuilder! diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs index 7e8c570484..fda33995c1 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaExporterHelperExtensions.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using System.Diagnostics; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; @@ -26,7 +28,7 @@ public static TracerProviderBuilder AddGenevaTraceExporter(this TracerProviderBu /// Adds to the . /// /// builder to use. - /// Exporter configuration options. + /// Callback action for configuring . /// The instance of to chain the calls. public static TracerProviderBuilder AddGenevaTraceExporter(this TracerProviderBuilder builder, Action configure) => AddGenevaTraceExporter(builder, name: null, configure); @@ -35,10 +37,13 @@ public static TracerProviderBuilder AddGenevaTraceExporter(this TracerProviderBu /// Adds to the . /// /// builder to use. - /// /// Name which is used when retrieving options. - /// Exporter configuration options. + /// Optional name which is used when retrieving options. + /// Optional callback action for configuring . /// The instance of to chain the calls. - public static TracerProviderBuilder AddGenevaTraceExporter(this TracerProviderBuilder builder, string name, Action configure) + public static TracerProviderBuilder AddGenevaTraceExporter( + this TracerProviderBuilder builder, + string? name, + Action? configure) { Guard.ThrowIfNull(builder); @@ -89,7 +94,9 @@ public static TracerProviderBuilder AddGenevaTraceExporter(this TracerProviderBu }); } - private static BaseProcessor BuildGenevaTraceExporter(GenevaExporterOptions options, BatchExportActivityProcessorOptions batchActivityExportProcessor) + private static BaseProcessor BuildGenevaTraceExporter( + GenevaExporterOptions options, + BatchExportActivityProcessorOptions batchActivityExportProcessor) { #pragma warning disable CA2000 // Dispose objects before losing scope var exporter = new GenevaTraceExporter(options); diff --git a/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs index 17530b7516..853e96bf00 100644 --- a/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/GenevaLoggingExtensions.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using System.Diagnostics; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; @@ -20,11 +22,11 @@ public static class GenevaLoggingExtensions /// Adds to the . /// /// . - /// Callback action for configuring . + /// Optional callback action for configuring . /// The instance of to chain the calls. public static OpenTelemetryLoggerOptions AddGenevaLogExporter( this OpenTelemetryLoggerOptions options, - Action configure) + Action? configure) { Guard.ThrowIfNull(options); @@ -71,8 +73,8 @@ public static LoggerProviderBuilder AddGenevaLogExporter(this LoggerProviderBuil /// The instance of to chain the calls. public static LoggerProviderBuilder AddGenevaLogExporter( this LoggerProviderBuilder builder, - string name, - Action configureExporter) + string? name, + Action? configureExporter) { var finalOptionsName = name ?? Options.Options.DefaultName; diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterExtensions.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterExtensions.cs index 1d25e7c374..9f876453d4 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterExtensions.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporterExtensions.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#nullable enable + using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using OpenTelemetry.Internal; @@ -25,7 +27,7 @@ public static MeterProviderBuilder AddGenevaMetricExporter(this MeterProviderBui /// Adds to the . /// /// builder to use. - /// Exporter configuration options. + /// Callback action for configuring . /// The instance of to chain the calls. public static MeterProviderBuilder AddGenevaMetricExporter(this MeterProviderBuilder builder, Action configure) => AddGenevaMetricExporter(builder, name: null, configure); @@ -34,10 +36,13 @@ public static MeterProviderBuilder AddGenevaMetricExporter(this MeterProviderBui /// Adds to the . /// /// builder to use. - /// /// Name which is used when retrieving options. - /// Exporter configuration options. + /// Optional name which is used when retrieving options. + /// Optional callback action for configuring . /// The instance of to chain the calls. - public static MeterProviderBuilder AddGenevaMetricExporter(this MeterProviderBuilder builder, string name, Action configure) + public static MeterProviderBuilder AddGenevaMetricExporter( + this MeterProviderBuilder builder, + string? name, + Action? configure) { Guard.ThrowIfNull(builder); @@ -56,7 +61,9 @@ public static MeterProviderBuilder AddGenevaMetricExporter(this MeterProviderBui }); } - private static PeriodicExportingMetricReader BuildGenevaMetricExporter(GenevaMetricExporterOptions options, Action configure = null) + private static PeriodicExportingMetricReader BuildGenevaMetricExporter( + GenevaMetricExporterOptions options, + Action? configure = null) { configure?.Invoke(options); diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/.publicApi/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.ConfluentKafka/.publicApi/PublicAPI.Unshipped.txt index f0c6ffc9b1..a577dafdcd 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/.publicApi/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/.publicApi/PublicAPI.Unshipped.txt @@ -1,26 +1,30 @@ +Confluent.Kafka.InstrumentedConsumerBuilder +Confluent.Kafka.InstrumentedConsumerBuilder.InstrumentedConsumerBuilder(System.Collections.Generic.IEnumerable>! config) -> void +Confluent.Kafka.InstrumentedProducerBuilder +Confluent.Kafka.InstrumentedProducerBuilder.InstrumentedProducerBuilder(System.Collections.Generic.IEnumerable>! config) -> void Confluent.Kafka.OpenTelemetryConsumeAndProcessMessageHandler +Confluent.Kafka.OpenTelemetryConsumerBuilderExtensions Confluent.Kafka.OpenTelemetryConsumeResultExtensions -OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedConsumerBuilder -OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedConsumerBuilder.InstrumentedConsumerBuilder(System.Collections.Generic.IEnumerable>! config) -> void -OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedProducerBuilder -OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedProducerBuilder.InstrumentedProducerBuilder(System.Collections.Generic.IEnumerable>! config) -> void +Confluent.Kafka.OpenTelemetryProducerBuilderExtensions OpenTelemetry.Metrics.MeterProviderBuilderExtensions OpenTelemetry.Trace.TracerProviderBuilderExtensions -override OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedConsumerBuilder.Build() -> Confluent.Kafka.IConsumer! -override OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedProducerBuilder.Build() -> Confluent.Kafka.IProducer! +override Confluent.Kafka.InstrumentedConsumerBuilder.Build() -> Confluent.Kafka.IConsumer! +override Confluent.Kafka.InstrumentedProducerBuilder.Build() -> Confluent.Kafka.IProducer! +static Confluent.Kafka.OpenTelemetryConsumerBuilderExtensions.AsInstrumentedConsumerBuilder(this Confluent.Kafka.ConsumerBuilder! consumerBuilder) -> Confluent.Kafka.InstrumentedConsumerBuilder! static Confluent.Kafka.OpenTelemetryConsumeResultExtensions.ConsumeAndProcessMessageAsync(this Confluent.Kafka.IConsumer! consumer, Confluent.Kafka.OpenTelemetryConsumeAndProcessMessageHandler! handler) -> System.Threading.Tasks.ValueTask?> static Confluent.Kafka.OpenTelemetryConsumeResultExtensions.ConsumeAndProcessMessageAsync(this Confluent.Kafka.IConsumer! consumer, Confluent.Kafka.OpenTelemetryConsumeAndProcessMessageHandler! handler, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.ValueTask?> static Confluent.Kafka.OpenTelemetryConsumeResultExtensions.TryExtractPropagationContext(this Confluent.Kafka.ConsumeResult! consumeResult, out OpenTelemetry.Context.Propagation.PropagationContext propagationContext) -> bool +static Confluent.Kafka.OpenTelemetryProducerBuilderExtensions.AsInstrumentedProducerBuilder(this Confluent.Kafka.ProducerBuilder! producerBuilder) -> Confluent.Kafka.InstrumentedProducerBuilder! static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddKafkaConsumerInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder) -> OpenTelemetry.Metrics.MeterProviderBuilder! -static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddKafkaConsumerInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedConsumerBuilder! consumerBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! -static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddKafkaConsumerInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, string? name, OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedConsumerBuilder? consumerBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddKafkaConsumerInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, Confluent.Kafka.InstrumentedConsumerBuilder! consumerBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddKafkaConsumerInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, string? name, Confluent.Kafka.InstrumentedConsumerBuilder? consumerBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddKafkaProducerInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder) -> OpenTelemetry.Metrics.MeterProviderBuilder! -static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddKafkaProducerInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedProducerBuilder! producerBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! -static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddKafkaProducerInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, string? name, OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedProducerBuilder? producerBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddKafkaProducerInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, Confluent.Kafka.InstrumentedProducerBuilder! producerBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! +static OpenTelemetry.Metrics.MeterProviderBuilderExtensions.AddKafkaProducerInstrumentation(this OpenTelemetry.Metrics.MeterProviderBuilder! builder, string? name, Confluent.Kafka.InstrumentedProducerBuilder? producerBuilder) -> OpenTelemetry.Metrics.MeterProviderBuilder! static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddKafkaConsumerInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddKafkaConsumerInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedConsumerBuilder! consumerBuilder) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddKafkaConsumerInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, string? name, OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedConsumerBuilder? consumerBuilder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddKafkaConsumerInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, Confluent.Kafka.InstrumentedConsumerBuilder! consumerBuilder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddKafkaConsumerInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, string? name, Confluent.Kafka.InstrumentedConsumerBuilder? consumerBuilder) -> OpenTelemetry.Trace.TracerProviderBuilder! static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddKafkaProducerInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddKafkaProducerInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedProducerBuilder! producerBuilder) -> OpenTelemetry.Trace.TracerProviderBuilder! -static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddKafkaProducerInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, string? name, OpenTelemetry.Instrumentation.ConfluentKafka.InstrumentedProducerBuilder? producerBuilder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddKafkaProducerInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, Confluent.Kafka.InstrumentedProducerBuilder! producerBuilder) -> OpenTelemetry.Trace.TracerProviderBuilder! +static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddKafkaProducerInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, string? name, Confluent.Kafka.InstrumentedProducerBuilder? producerBuilder) -> OpenTelemetry.Trace.TracerProviderBuilder! virtual Confluent.Kafka.OpenTelemetryConsumeAndProcessMessageHandler.Invoke(Confluent.Kafka.ConsumeResult! consumeResult, System.Diagnostics.Activity? activity, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.ValueTask diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/ConfluentKafkaConsumerInstrumentation.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/ConfluentKafkaConsumerInstrumentation.cs index 573b78d56b..71e8d2baea 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/ConfluentKafkaConsumerInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/ConfluentKafkaConsumerInstrumentation.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +using Confluent.Kafka; + namespace OpenTelemetry.Instrumentation.ConfluentKafka; internal class ConfluentKafkaConsumerInstrumentation; diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/ConfluentKafkaProducerInstrumentation.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/ConfluentKafkaProducerInstrumentation.cs index 13f71b1905..4f9a720510 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/ConfluentKafkaProducerInstrumentation.cs +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/ConfluentKafkaProducerInstrumentation.cs @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +using Confluent.Kafka; + namespace OpenTelemetry.Instrumentation.ConfluentKafka; internal abstract class ConfluentKafkaProducerInstrumentation; diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedConsumerBuilder.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedConsumerBuilder.cs index 8352c874e3..edc70f9085 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedConsumerBuilder.cs +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedConsumerBuilder.cs @@ -2,9 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; -using Confluent.Kafka; +using OpenTelemetry.Instrumentation.ConfluentKafka; -namespace OpenTelemetry.Instrumentation.ConfluentKafka; +namespace Confluent.Kafka; /// /// A builder of with support for instrumentation. diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedProducerBuilder.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedProducerBuilder.cs index 5dca3f77a3..eaefacdc19 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedProducerBuilder.cs +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/InstrumentedProducerBuilder.cs @@ -2,9 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 using System.Diagnostics; -using Confluent.Kafka; +using OpenTelemetry.Instrumentation.ConfluentKafka; -namespace OpenTelemetry.Instrumentation.ConfluentKafka; +namespace Confluent.Kafka; /// /// A builder of with support for instrumentation. diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/MeterProviderBuilderExtensions.Consumer.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/MeterProviderBuilderExtensions.Consumer.cs index 0cc6b91997..c2bb25f490 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/MeterProviderBuilderExtensions.Consumer.cs +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/MeterProviderBuilderExtensions.Consumer.cs @@ -1,6 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +using Confluent.Kafka; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using OpenTelemetry.Instrumentation.ConfluentKafka; @@ -30,7 +31,7 @@ public static MeterProviderBuilder AddKafkaConsumerInstrumentation /// The type of the key. /// The type of the value. /// being configured. - /// to instrument. + /// to instrument. /// The instance of to chain the calls. public static MeterProviderBuilder AddKafkaConsumerInstrumentation( this MeterProviderBuilder builder, diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/MeterProviderBuilderExtensions.Producer.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/MeterProviderBuilderExtensions.Producer.cs index 3e4c4021db..e5fb587066 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/MeterProviderBuilderExtensions.Producer.cs +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/MeterProviderBuilderExtensions.Producer.cs @@ -1,6 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +using Confluent.Kafka; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using OpenTelemetry.Instrumentation.ConfluentKafka; @@ -30,7 +31,7 @@ public static MeterProviderBuilder AddKafkaProducerInstrumentation /// The type of the key. /// The type of the value. /// being configured. - /// to instrument. + /// to instrument. /// The instance of to chain the calls. public static MeterProviderBuilder AddKafkaProducerInstrumentation( this MeterProviderBuilder builder, diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryConsumerBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryConsumerBuilderExtensions.cs new file mode 100644 index 0000000000..c139ba1956 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryConsumerBuilderExtensions.cs @@ -0,0 +1,108 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using OpenTelemetry.Instrumentation.ConfluentKafka; + +namespace Confluent.Kafka; + +/// +/// Extensions for . +/// +public static class OpenTelemetryConsumerBuilderExtensions +{ + /// + /// Converts a to an . + /// + /// Type of the key. + /// Type of the value. + /// The instance. + /// An instance. +#if !NETFRAMEWORK + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Use 'InstrumentedConsumerBuilder' constructor to avoid reflection.")] +#endif + public static InstrumentedConsumerBuilder AsInstrumentedConsumerBuilder(this ConsumerBuilder consumerBuilder) + { + InstrumentedConsumerBuilder result = new InstrumentedConsumerBuilder(consumerBuilder.GetInternalConfig() ?? Enumerable.Empty>()); + result.SetInternalErrorHandler(consumerBuilder.GetInternalErrorHandler()); + result.SetInternalLogHandler(consumerBuilder.GetInternalLogHandler()); + result.SetInternalStatisticsHandler(consumerBuilder.GetInternalStatisticsHandler()); + result.SetInternalOAuthBearerTokenRefreshHandler(consumerBuilder.GetInternalOAuthBearerTokenRefreshHandler()); + result.SetInternalOffsetsCommittedHandler(consumerBuilder.GetInternalOffsetsCommittedHandler()); + result.SetInternalPartitionsAssignedHandler(consumerBuilder.GetInternalPartitionsAssignedHandler()); + result.SetInternalPartitionsRevokedHandler(consumerBuilder.GetInternalPartitionsRevokedHandler()); + result.SetInternalPartitionsLostHandler(consumerBuilder.GetInternalPartitionsLostHandler()); + result.SetInternalRevokedOrLostHandlerIsFunc(consumerBuilder.GetInternalRevokedOrLostHandlerIsFunc() ?? false); + result.SetInternalKeyDeserializer(consumerBuilder.GetInternalKeyDeserializer()); + result.SetInternalValueDeserializer(consumerBuilder.GetInternalValueDeserializer()); + return result; + } + + internal static IEnumerable>? GetInternalConfig(this ConsumerBuilder consumerBuilder) + => ReflectionHelpers.GetProperty(consumerBuilder, "Config") as IEnumerable>; + + internal static Action, Error>? GetInternalErrorHandler(this ConsumerBuilder consumerBuilder) + => ReflectionHelpers.GetProperty(consumerBuilder, "ErrorHandler") as Action, Error>; + + internal static Action, LogMessage>? GetInternalLogHandler(this ConsumerBuilder consumerBuilder) + => ReflectionHelpers.GetProperty(consumerBuilder, "LogHandler") as Action, LogMessage>; + + internal static Action, string>? GetInternalStatisticsHandler(this ConsumerBuilder consumerBuilder) + => ReflectionHelpers.GetProperty(consumerBuilder, "StatisticsHandler") as Action, string>; + + internal static Action, string>? GetInternalOAuthBearerTokenRefreshHandler(this ConsumerBuilder consumerBuilder) + => ReflectionHelpers.GetProperty(consumerBuilder, "OAuthBearerTokenRefreshHandler") as Action, string>; + + internal static Action, CommittedOffsets>? GetInternalOffsetsCommittedHandler(this ConsumerBuilder consumerBuilder) + => ReflectionHelpers.GetProperty(consumerBuilder, "OffsetsCommittedHandler") as Action, CommittedOffsets>; + + internal static Func, List, IEnumerable>? GetInternalPartitionsAssignedHandler(this ConsumerBuilder consumerBuilder) + => ReflectionHelpers.GetProperty(consumerBuilder, "PartitionsAssignedHandler") as Func, List, IEnumerable>; + + internal static Func, List, IEnumerable>? GetInternalPartitionsRevokedHandler(this ConsumerBuilder consumerBuilder) + => ReflectionHelpers.GetProperty(consumerBuilder, "PartitionsRevokedHandler") as Func, List, IEnumerable>; + + internal static Func, List, IEnumerable>? GetInternalPartitionsLostHandler(this ConsumerBuilder consumerBuilder) + => ReflectionHelpers.GetProperty(consumerBuilder, "PartitionsLostHandler") as Func, List, IEnumerable>; + + internal static IDeserializer? GetInternalKeyDeserializer(this ConsumerBuilder consumerBuilder) + => ReflectionHelpers.GetProperty(consumerBuilder, "KeyDeserializer") as IDeserializer; + + internal static IDeserializer? GetInternalValueDeserializer(this ConsumerBuilder consumerBuilder) + => ReflectionHelpers.GetProperty(consumerBuilder, "ValueDeserializer") as IDeserializer; + + internal static bool? GetInternalRevokedOrLostHandlerIsFunc(this ConsumerBuilder consumerBuilder) + => ReflectionHelpers.GetField(consumerBuilder, "RevokedOrLostHandlerIsFunc") as bool?; + + internal static void SetInternalErrorHandler(this ConsumerBuilder consumerBuilder, Action, Error>? value) + => ReflectionHelpers.SetProperty(consumerBuilder, "ErrorHandler", value); + + internal static void SetInternalLogHandler(this ConsumerBuilder consumerBuilder, Action, LogMessage>? value) + => ReflectionHelpers.SetProperty(consumerBuilder, "LogHandler", value); + + internal static void SetInternalStatisticsHandler(this ConsumerBuilder consumerBuilder, Action, string>? value) + => ReflectionHelpers.SetProperty(consumerBuilder, "StatisticsHandler", value); + + internal static void SetInternalOAuthBearerTokenRefreshHandler(this ConsumerBuilder consumerBuilder, Action, string>? value) + => ReflectionHelpers.SetProperty(consumerBuilder, "OAuthBearerTokenRefreshHandler", value); + + internal static void SetInternalOffsetsCommittedHandler(this ConsumerBuilder consumerBuilder, Action, CommittedOffsets>? value) + => ReflectionHelpers.SetProperty(consumerBuilder, "OffsetsCommittedHandler", value); + + internal static void SetInternalPartitionsAssignedHandler(this ConsumerBuilder consumerBuilder, Func, List, IEnumerable>? value) + => ReflectionHelpers.SetProperty(consumerBuilder, "PartitionsAssignedHandler", value); + + internal static void SetInternalPartitionsRevokedHandler(this ConsumerBuilder consumerBuilder, Func, List, IEnumerable>? value) + => ReflectionHelpers.SetProperty(consumerBuilder, "PartitionsRevokedHandler", value); + + internal static void SetInternalPartitionsLostHandler(this ConsumerBuilder consumerBuilder, Func, List, IEnumerable>? value) + => ReflectionHelpers.SetProperty(consumerBuilder, "PartitionsLostHandler", value); + + internal static void SetInternalKeyDeserializer(this ConsumerBuilder consumerBuilder, IDeserializer? value) + => ReflectionHelpers.SetProperty(consumerBuilder, "KeyDeserializer", value); + + internal static void SetInternalValueDeserializer(this ConsumerBuilder consumerBuilder, IDeserializer? value) + => ReflectionHelpers.SetProperty(consumerBuilder, "ValueDeserializer", value); + + internal static void SetInternalRevokedOrLostHandlerIsFunc(this ConsumerBuilder consumerBuilder, bool? value) + => ReflectionHelpers.SetField(consumerBuilder, "RevokedOrLostHandlerIsFunc", value); +} diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryProducerBuilderExtensions.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryProducerBuilderExtensions.cs new file mode 100644 index 0000000000..3eb243af70 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/OpenTelemetryProducerBuilderExtensions.cs @@ -0,0 +1,104 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using OpenTelemetry.Instrumentation.ConfluentKafka; + +namespace Confluent.Kafka; + +/// +/// Extensions for . +/// +public static class OpenTelemetryProducerBuilderExtensions +{ + /// + /// Converts to . + /// + /// Type of the key. + /// Type of the value. + /// The instance. + /// An instance. +#if !NETFRAMEWORK + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Use 'InstrumentedProducerBuilder' constructor to avoid reflection.")] +#endif + public static InstrumentedProducerBuilder AsInstrumentedProducerBuilder(this ProducerBuilder producerBuilder) + { + InstrumentedProducerBuilder instrumentedProducerBuilder = new InstrumentedProducerBuilder(producerBuilder.GetInternalConfig() ?? Enumerable.Empty>()); + instrumentedProducerBuilder.SetInternalLogHandler(producerBuilder.GetInternalLogHandler()); + instrumentedProducerBuilder.SetInternalErrorHandler(producerBuilder.GetInternalErrorHandler()); + instrumentedProducerBuilder.SetInternalStatisticsHandler(producerBuilder.GetInternalStatisticsHandler()); + instrumentedProducerBuilder.SetInternalOAuthBearerTokenRefreshHandler(producerBuilder.GetInternalOAuthBearerTokenRefreshHandler()); + instrumentedProducerBuilder.SetInternalPartitioners(producerBuilder.GetInternalPartitioners()); + instrumentedProducerBuilder.SetInternalDefaultPartitioner(producerBuilder.GetInternalDefaultPartitioner()); + instrumentedProducerBuilder.SetInternalKeySerializer(producerBuilder.GetInternalKeySerializer()); + instrumentedProducerBuilder.SetInternalValueSerializer(producerBuilder.GetInternalValueSerializer()); + instrumentedProducerBuilder.SetInternalAsyncKeySerializer(producerBuilder.GetInternalAsyncKeySerializer()); + instrumentedProducerBuilder.SetInternalAsyncValueSerializer(producerBuilder.GetInternalAsyncValueSerializer()); + return instrumentedProducerBuilder; + } + + internal static IEnumerable>? GetInternalConfig(this ProducerBuilder producerBuilder) + => ReflectionHelpers.GetProperty(producerBuilder, "Config") as IEnumerable>; + + internal static Action, Error>? GetInternalErrorHandler(this ProducerBuilder producerBuilder) + => ReflectionHelpers.GetProperty(producerBuilder, "ErrorHandler") as Action, Error>; + + internal static Action, LogMessage>? GetInternalLogHandler(this ProducerBuilder producerBuilder) + => ReflectionHelpers.GetProperty(producerBuilder, "LogHandler") as Action, LogMessage>; + + internal static Action, string>? GetInternalStatisticsHandler(this ProducerBuilder producerBuilder) + => ReflectionHelpers.GetProperty(producerBuilder, "StatisticsHandler") as Action, string>; + + internal static Action, string>? GetInternalOAuthBearerTokenRefreshHandler(this ProducerBuilder producerBuilder) + => ReflectionHelpers.GetProperty(producerBuilder, "OAuthBearerTokenRefreshHandler") as Action, string>; + + internal static Dictionary? GetInternalPartitioners(this ProducerBuilder producerBuilder) + => ReflectionHelpers.GetProperty(producerBuilder, "Partitioners") as Dictionary; + + internal static PartitionerDelegate? GetInternalDefaultPartitioner(this ProducerBuilder producerBuilder) + => ReflectionHelpers.GetProperty(producerBuilder, "DefaultPartitioner") as PartitionerDelegate; + + internal static ISerializer? GetInternalKeySerializer(this ProducerBuilder producerBuilder) + => ReflectionHelpers.GetProperty(producerBuilder, "KeySerializer") as ISerializer; + + internal static ISerializer? GetInternalValueSerializer(this ProducerBuilder producerBuilder) + => ReflectionHelpers.GetProperty(producerBuilder, "ValueSerializer") as ISerializer; + + internal static IAsyncSerializer? GetInternalAsyncKeySerializer(this ProducerBuilder producerBuilder) + => ReflectionHelpers.GetProperty(producerBuilder, "AsyncKeySerializer") as IAsyncSerializer; + + internal static IAsyncSerializer? GetInternalAsyncValueSerializer(this ProducerBuilder producerBuilder) + => ReflectionHelpers.GetProperty(producerBuilder, "AsyncValueSerializer") as IAsyncSerializer; + + internal static void SetInternalConfig(this ProducerBuilder producerBuilder, IEnumerable>? value) + => ReflectionHelpers.SetProperty(producerBuilder, "Config", value); + + internal static void SetInternalErrorHandler(this ProducerBuilder producerBuilder, Action, Error>? value) + => ReflectionHelpers.SetProperty(producerBuilder, "ErrorHandler", value); + + internal static void SetInternalLogHandler(this ProducerBuilder producerBuilder, Action, LogMessage>? value) + => ReflectionHelpers.SetProperty(producerBuilder, "LogHandler", value); + + internal static void SetInternalStatisticsHandler(this ProducerBuilder producerBuilder, Action, string>? value) + => ReflectionHelpers.SetProperty(producerBuilder, "StatisticsHandler", value); + + internal static void SetInternalOAuthBearerTokenRefreshHandler(this ProducerBuilder producerBuilder, Action, string>? value) + => ReflectionHelpers.SetProperty(producerBuilder, "OAuthBearerTokenRefreshHandler", value); + + internal static void SetInternalPartitioners(this ProducerBuilder producerBuilder, Dictionary? value) + => ReflectionHelpers.SetProperty(producerBuilder, "Partitioners", value); + + internal static void SetInternalDefaultPartitioner(this ProducerBuilder producerBuilder, PartitionerDelegate? value) + => ReflectionHelpers.SetProperty(producerBuilder, "DefaultPartitioner", value); + + internal static void SetInternalKeySerializer(this ProducerBuilder producerBuilder, ISerializer? value) + => ReflectionHelpers.SetProperty(producerBuilder, "KeySerializer", value); + + internal static void SetInternalValueSerializer(this ProducerBuilder producerBuilder, ISerializer? value) + => ReflectionHelpers.SetProperty(producerBuilder, "ValueSerializer", value); + + internal static void SetInternalAsyncKeySerializer(this ProducerBuilder producerBuilder, IAsyncSerializer? value) + => ReflectionHelpers.SetProperty(producerBuilder, "AsyncKeySerializer", value); + + internal static void SetInternalAsyncValueSerializer(this ProducerBuilder producerBuilder, IAsyncSerializer? value) + => ReflectionHelpers.SetProperty(producerBuilder, "AsyncValueSerializer", value); +} diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/README.md b/src/OpenTelemetry.Instrumentation.ConfluentKafka/README.md index b05ff16525..09ed24368c 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/README.md +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/README.md @@ -9,8 +9,124 @@ [![NuGet download count badge](https://img.shields.io/nuget/dt/OpenTelemetry.Instrumentation.ConfluentKafka)](https://www.nuget.org/packages/OpenTelemetry.Instrumentation.ConfluentKafka) [![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib/branch/main/graphs/badge.svg?flag=unittests-Instrumentation.ConfluentKafka)](https://app.codecov.io/gh/open-telemetry/opentelemetry-dotnet-contrib?flags[0]=unittests-Instrumentation.ConfluentKafka) -Download the `OpenTelemetry.Instrumentation.ConfluentKafka` package: +## Usage -```shell -dotnet add package OpenTelemetry.Instrumentation.ConfluentKafka --prerelease +To use the `OpenTelemetry.Instrumentation.ConfluentKafka` package, follow these steps: + +1. **Install the package**: + + ```shell + dotnet add package OpenTelemetry.Instrumentation.ConfluentKafka --prerelease + ``` + +2. **Configure OpenTelemetry in your application**: + + ```csharp + using Confluent.Kafka; + using OpenTelemetry.Metrics; + using OpenTelemetry.Trace; + + var builder = Host.CreateApplicationBuilder(args); + + const string bootstrapServers = "localhost:9092"; + + builder.Services.AddSingleton(_ => + { + ProducerConfig producerConfig = new() { BootstrapServers = bootstrapServers }; + return new InstrumentedProducerBuilder(producerConfig); + }); + builder.Services.AddSingleton(_ => + { + ConsumerConfig consumerConfigA = new() + { + BootstrapServers = bootstrapServers, + GroupId = "group-a", + AutoOffsetReset = AutoOffsetReset.Earliest, + EnablePartitionEof = true, + }; + return new InstrumentedConsumerBuilder(consumerConfigA); + }); + + builder.Services.AddOpenTelemetry() + .WithTracing(tracing => + { + tracing.AddConsoleExporter() + .AddOtlpExporter() + .AddKafkaProducerInstrumentation() + .AddKafkaConsumerInstrumentation(); + }) + .WithMetrics(metering => + { + metering.AddConsoleExporter() + .AddOtlpExporter() + .AddKafkaProducerInstrumentation() + .AddKafkaConsumerInstrumentation(); + }); + + builder.Services.AddHostedService(); + + var app = builder.Build(); + await app.RunAsync(); + ``` + +This will set up OpenTelemetry instrumentation for Confluent.Kafka producers +and consumers, allowing you to collect and export telemetry data. + +## Extending `ConsumerBuilder` or `ProducerBuilder` instances + +To extend an already built `ConsumerBuilder` +or `ProducerBuilder` +instance with OpenTelemetry instrumentation, you can use the `AsInstrumentedConsumerBuilder` +and `AsInstrumentedProducerBuilder` extension methods. + +### Example for `ConsumerBuilder` + +```csharp +using Confluent.Kafka; +using OpenTelemetry.Instrumentation.ConfluentKafka; + +var consumerConfig = new ConsumerConfig +{ + BootstrapServers = "localhost:9092", + GroupId = "my-group", + AutoOffsetReset = AutoOffsetReset.Earliest +}; + +var consumerBuilder = new ConsumerBuilder(consumerConfig); + +// Set various handlers and properties +consumerBuilder.SetErrorHandler((consumer, error) => Console.WriteLine($"Error: {error.Reason}")); +consumerBuilder.SetLogHandler((consumer, logMessage) => Console.WriteLine($"Log: {logMessage.Message}")); +consumerBuilder.SetStatisticsHandler((consumer, statistics) => Console.WriteLine($"Statistics: {statistics}")); + +// Convert to InstrumentedConsumerBuilder +var instrumentedConsumerBuilder = consumerBuilder.AsInstrumentedConsumerBuilder(); + +// Build the consumer +var consumer = instrumentedConsumerBuilder.Build(); +``` + +### Example for `ProducerBuilder` + +```csharp +using Confluent.Kafka; +using OpenTelemetry.Instrumentation.ConfluentKafka; + +var producerConfig = new ProducerConfig +{ + BootstrapServers = "localhost:9092" +}; + +var producerBuilder = new ProducerBuilder(producerConfig); + +// Set various handlers and properties +producerBuilder.SetErrorHandler((producer, error) => Console.WriteLine($"Error: {error.Reason}")); +producerBuilder.SetLogHandler((producer, logMessage) => Console.WriteLine($"Log: {logMessage.Message}")); +producerBuilder.SetStatisticsHandler((producer, statistics) => Console.WriteLine($"Statistics: {statistics}")); + +// Convert to InstrumentedProducerBuilder +var instrumentedProducerBuilder = producerBuilder.AsInstrumentedProducerBuilder(); + +// Build the producer +var producer = instrumentedProducerBuilder.Build(); ``` diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/ReflectionHelpers.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/ReflectionHelpers.cs new file mode 100644 index 0000000000..e48695bbe3 --- /dev/null +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/ReflectionHelpers.cs @@ -0,0 +1,51 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +namespace OpenTelemetry.Instrumentation.ConfluentKafka; + +internal static class ReflectionHelpers +{ + public static void SetProperty(T instance, string fieldName, object? value) + { + var property = typeof(T).GetProperty(fieldName, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); + if (property == null) + { + throw new InvalidOperationException($"Could not find property '{fieldName}' on type '{typeof(T).FullName}'."); + } + + property.SetValue(instance, value); + } + + public static object? GetProperty(T instance, string fieldName) + { + var property = typeof(T).GetProperty(fieldName, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); + if (property == null) + { + throw new InvalidOperationException($"Could not find property '{fieldName}' on type '{typeof(T).FullName}'."); + } + + return property.GetValue(instance); + } + + public static void SetField(T instance, string fieldName, object? value) + { + var field = typeof(T).GetField(fieldName, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); + if (field == null) + { + throw new InvalidOperationException($"Could not find field '{fieldName}' on type '{typeof(T).FullName}'."); + } + + field.SetValue(instance, value); + } + + public static object? GetField(T instance, string fieldName) + { + var field = typeof(T).GetField(fieldName, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); + if (field == null) + { + throw new InvalidOperationException($"Could not find field '{fieldName}' on type '{typeof(T).FullName}'."); + } + + return field.GetValue(instance); + } +} diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/TracerProviderBuilderExtensions.Consumer.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/TracerProviderBuilderExtensions.Consumer.cs index d9eada36e1..ee6025f885 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/TracerProviderBuilderExtensions.Consumer.cs +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/TracerProviderBuilderExtensions.Consumer.cs @@ -1,6 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +using Confluent.Kafka; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using OpenTelemetry.Instrumentation.ConfluentKafka; @@ -30,7 +31,7 @@ public static TracerProviderBuilder AddKafkaConsumerInstrumentationThe type of the key. /// The type of the value. /// being configured. - /// to instrument. + /// to instrument. /// The instance of to chain the calls. public static TracerProviderBuilder AddKafkaConsumerInstrumentation( this TracerProviderBuilder builder, diff --git a/src/OpenTelemetry.Instrumentation.ConfluentKafka/TracerProviderBuilderExtensions.Producer.cs b/src/OpenTelemetry.Instrumentation.ConfluentKafka/TracerProviderBuilderExtensions.Producer.cs index db977c72ae..5f8adbfb84 100644 --- a/src/OpenTelemetry.Instrumentation.ConfluentKafka/TracerProviderBuilderExtensions.Producer.cs +++ b/src/OpenTelemetry.Instrumentation.ConfluentKafka/TracerProviderBuilderExtensions.Producer.cs @@ -1,6 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +using Confluent.Kafka; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using OpenTelemetry.Instrumentation.ConfluentKafka; @@ -30,7 +31,7 @@ public static TracerProviderBuilder AddKafkaProducerInstrumentationThe type of the key. /// The type of the value. /// being configured. - /// to instrument. + /// to instrument. /// The instance of to chain the calls. public static TracerProviderBuilder AddKafkaProducerInstrumentation( this TracerProviderBuilder builder, diff --git a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md index 61ce939c32..e775f6e7b8 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.Owin/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +* Updated activity tags to use new + [semantic conventions](https://github.com/open-telemetry/semantic-conventions/tree/v1.27.0/docs/http/http-spans.md) + attribute schema. + ([#2028](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/2028)) + * Updated OpenTelemetry core component version(s) to `1.9.0`. ([#1888](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1888)) diff --git a/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs b/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs index 65b44f7519..cf029720c0 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs +++ b/src/OpenTelemetry.Instrumentation.Owin/Implementation/DiagnosticsMiddleware.cs @@ -20,6 +20,8 @@ internal sealed class DiagnosticsMiddleware : OwinMiddleware private static readonly Func> OwinRequestHeaderValuesGetter = (request, name) => request.Headers.GetValues(name); + private static readonly RequestDataHelper RequestDataHelper = new(configureByHttpKnownMethodsEnvironmentalVariable: false); + /// /// Initializes a new instance of the class. /// @@ -84,39 +86,26 @@ private static void BeginRequest(IOwinContext owinContext) { var request = owinContext.Request; - /* - * Note: Display name is intentionally set to a low cardinality - * value because OWIN does not expose any kind of - * route/template. See: - * https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/http.md#name - */ - activity.DisplayName = request.Method switch - { - "GET" => "HTTP GET", - "POST" => "HTTP POST", - "PUT" => "HTTP PUT", - "DELETE" => "HTTP DELETE", - _ => $"HTTP {request.Method}", - }; + // Note: Display name is intentionally set to a low cardinality + // value because OWIN does not expose any kind of + // route/template. See: + // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/http.md#name + RequestDataHelper.SetActivityDisplayName(activity, request.Method); if (activity.IsAllDataRequested) { - if (request.Uri.Port == 80 || request.Uri.Port == 443) - { - activity.SetTag(SemanticConventions.AttributeHttpHost, request.Uri.Host); - } - else - { - activity.SetTag(SemanticConventions.AttributeHttpHost, request.Uri.Host + ":" + request.Uri.Port); - } + RequestDataHelper.SetHttpMethodTag(activity, request.Method); + activity.SetTag(SemanticConventions.AttributeServerAddress, request.Uri.Host); + activity.SetTag(SemanticConventions.AttributeServerPort, request.Uri.Port); + activity.SetTag(SemanticConventions.AttributeNetworkProtocolVersion, request.Protocol); - activity.SetTag(SemanticConventions.AttributeHttpMethod, request.Method); - activity.SetTag(SemanticConventions.AttributeHttpTarget, request.Uri.AbsolutePath); - activity.SetTag(SemanticConventions.AttributeHttpUrl, GetUriTagValueFromRequestUri(request.Uri, OwinInstrumentationActivitySource.Options.DisableUrlQueryRedaction)); + activity.SetTag(SemanticConventions.AttributeUrlPath, request.Uri.AbsolutePath); + activity.SetTag(SemanticConventions.AttributeUrlQuery, request.Query); + activity.SetTag(SemanticConventions.AttributeUrlScheme, owinContext.Request.Scheme); if (request.Headers.TryGetValue("User-Agent", out string[] userAgent) && userAgent.Length > 0) { - activity.SetTag(SemanticConventions.AttributeHttpUserAgent, userAgent[0]); + activity.SetTag(SemanticConventions.AttributeUserAgentOriginal, userAgent[0]); } try @@ -163,7 +152,7 @@ private static void RequestEnd(IOwinContext owinContext, Exception? exception, l { activity.SetStatus(Status.Error); - if (OwinInstrumentationActivitySource.Options != null && OwinInstrumentationActivitySource.Options.RecordException) + if (OwinInstrumentationActivitySource.Options?.RecordException == true) { activity.RecordException(exception); } @@ -173,7 +162,7 @@ private static void RequestEnd(IOwinContext owinContext, Exception? exception, l activity.SetStatus(SpanHelper.ResolveActivityStatusForHttpStatusCode(activity.Kind, response.StatusCode)); } - activity.SetTag(SemanticConventions.AttributeHttpStatusCode, response.StatusCode); + activity.SetTag(SemanticConventions.AttributeHttpResponseStatusCode, response.StatusCode); try { diff --git a/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj b/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj index a72d0b2a7c..184409a304 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj +++ b/src/OpenTelemetry.Instrumentation.Owin/OpenTelemetry.Instrumentation.Owin.csproj @@ -20,6 +20,7 @@ + diff --git a/src/OpenTelemetry.Instrumentation.Owin/README.md b/src/OpenTelemetry.Instrumentation.Owin/README.md index b92d521fd9..f2553161b3 100644 --- a/src/OpenTelemetry.Instrumentation.Owin/README.md +++ b/src/OpenTelemetry.Instrumentation.Owin/README.md @@ -59,6 +59,25 @@ OpenTelemetry instrumentation which listens to the OWIN diagnostic events. .Build(); ``` +Following list of attributes are added by default on activity. See +[http-spans](https://github.com/open-telemetry/semantic-conventions/tree/v1.27.0/docs/http/http-spans.md) +for more details about each individual attribute: + +* `http.request.method` +* `http.request.method_original` +* `http.response.status_code` +* `network.protocol.version` +* `user_agent.original` +* `server.address` +* `server.port` +* `url.path` +* `url.query` - By default, the values in the query component are replaced with + the text `Redacted`. For example, `?key1=value1&key2=value2` becomes + `?key1=Redacted&key2=Redacted`. You can disable this redaction by setting the + environment variable + `OTEL_DOTNET_EXPERIMENTAL_OWIN_DISABLE_URL_QUERY_REDACTION` to `true`. +* `url.scheme` + #### Configure OpenTelemetry MeterProvider Call the `AddOwinInstrumentation` `MeterProviderBuilder` extension to register diff --git a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetryConsumerBuilderExtensionsTests.cs b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetryConsumerBuilderExtensionsTests.cs new file mode 100644 index 0000000000..1af7aefd27 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetryConsumerBuilderExtensionsTests.cs @@ -0,0 +1,145 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Confluent.Kafka; +using Xunit; + +namespace OpenTelemetry.Instrumentation.ConfluentKafka.Tests; + +public class OpenTelemetryConsumerBuilderExtensionsTests +{ + [Fact] + public void ShouldConvertConsumerBuilderToInstrumentedConsumerBuilder() + { + // Arrange + var config = new List> + { + new("bootstrap.servers", "localhost:9092"), + }; + + var consumerBuilder = new ConsumerBuilder(config); + + IDeserializer keyDeserializer = Deserializers.Utf8; + IDeserializer valueDeserializer = Deserializers.Utf8; + + consumerBuilder.SetErrorHandler(ErrorHandler); + consumerBuilder.SetLogHandler(LogHandler); + consumerBuilder.SetStatisticsHandler(StatisticsHandler); + consumerBuilder.SetOAuthBearerTokenRefreshHandler(OAuthBearerTokenRefreshHandler); + consumerBuilder.SetOffsetsCommittedHandler(OffsetsCommittedHandler); + consumerBuilder.SetPartitionsAssignedHandler(PartitionsAssignedHandler); + consumerBuilder.SetPartitionsRevokedHandler(PartitionsRevokedHandler); + consumerBuilder.SetPartitionsLostHandler(PartitionsLostHandler); + consumerBuilder.SetKeyDeserializer(keyDeserializer); + consumerBuilder.SetValueDeserializer(valueDeserializer); + + // Act + var instrumentedConsumerBuilder = consumerBuilder.AsInstrumentedConsumerBuilder(); + + // Assert + Assert.Equal(ErrorHandler, instrumentedConsumerBuilder.GetInternalErrorHandler()); + Assert.Equal(LogHandler, instrumentedConsumerBuilder.GetInternalLogHandler()); + Assert.Equal(StatisticsHandler, instrumentedConsumerBuilder.GetInternalStatisticsHandler()); + Assert.Equal(OAuthBearerTokenRefreshHandler, instrumentedConsumerBuilder.GetInternalOAuthBearerTokenRefreshHandler()); + Assert.Equal(OffsetsCommittedHandler, instrumentedConsumerBuilder.GetInternalOffsetsCommittedHandler()); + Assert.Equal(PartitionsAssignedHandler, instrumentedConsumerBuilder.GetInternalPartitionsAssignedHandler()); + Assert.Equal(PartitionsRevokedHandler, instrumentedConsumerBuilder.GetInternalPartitionsRevokedHandler()); + Assert.Equal(PartitionsLostHandler, instrumentedConsumerBuilder.GetInternalPartitionsLostHandler()); + Assert.Equal(keyDeserializer, instrumentedConsumerBuilder.GetInternalKeyDeserializer()); + Assert.Equal(valueDeserializer, instrumentedConsumerBuilder.GetInternalValueDeserializer()); + return; + + void ErrorHandler(IConsumer consumer, Error error) + { + } + + void LogHandler(IConsumer consumer, LogMessage logMessage) + { + } + + void StatisticsHandler(IConsumer consumer, string statistics) + { + } + + void OAuthBearerTokenRefreshHandler(IConsumer consumer, string oauthBearerToken) + { + } + + void OffsetsCommittedHandler(IConsumer consumer, CommittedOffsets offsets) + { + } + + IEnumerable PartitionsAssignedHandler(IConsumer consumer, List partitions) => new List(); + IEnumerable PartitionsRevokedHandler(IConsumer consumer, List partitions) => new List(); + IEnumerable PartitionsLostHandler(IConsumer consumer, List partitions) => new List(); + } + + [Fact] + public void ShouldConvertUserDefinedConsumerBuilderToInstrumentedConsumerBuilder() + { + // Arrange + var config = new List> + { + new("bootstrap.servers", "localhost:9092"), + }; + + var consumerBuilder = new CustomConsumerBuilder(config); + + IDeserializer keyDeserializer = Deserializers.Utf8; + IDeserializer valueDeserializer = Deserializers.Utf8; + + consumerBuilder.SetErrorHandler(ErrorHandler); + consumerBuilder.SetLogHandler(LogHandler); + consumerBuilder.SetStatisticsHandler(StatisticsHandler); + consumerBuilder.SetOAuthBearerTokenRefreshHandler(OAuthBearerTokenRefreshHandler); + consumerBuilder.SetOffsetsCommittedHandler(OffsetsCommittedHandler); + consumerBuilder.SetPartitionsAssignedHandler(PartitionsAssignedHandler); + consumerBuilder.SetPartitionsRevokedHandler(PartitionsRevokedHandler); + consumerBuilder.SetPartitionsLostHandler(PartitionsLostHandler); + consumerBuilder.SetKeyDeserializer(keyDeserializer); + consumerBuilder.SetValueDeserializer(valueDeserializer); + + // Act + var instrumentedConsumerBuilder = consumerBuilder.AsInstrumentedConsumerBuilder(); + + // Assert + Assert.Equal(ErrorHandler, instrumentedConsumerBuilder.GetInternalErrorHandler()); + Assert.Equal(LogHandler, instrumentedConsumerBuilder.GetInternalLogHandler()); + Assert.Equal(StatisticsHandler, instrumentedConsumerBuilder.GetInternalStatisticsHandler()); + Assert.Equal(OAuthBearerTokenRefreshHandler, instrumentedConsumerBuilder.GetInternalOAuthBearerTokenRefreshHandler()); + Assert.Equal(OffsetsCommittedHandler, instrumentedConsumerBuilder.GetInternalOffsetsCommittedHandler()); + Assert.Equal(PartitionsAssignedHandler, instrumentedConsumerBuilder.GetInternalPartitionsAssignedHandler()); + Assert.Equal(PartitionsRevokedHandler, instrumentedConsumerBuilder.GetInternalPartitionsRevokedHandler()); + Assert.Equal(PartitionsLostHandler, instrumentedConsumerBuilder.GetInternalPartitionsLostHandler()); + Assert.Equal(keyDeserializer, instrumentedConsumerBuilder.GetInternalKeyDeserializer()); + Assert.Equal(valueDeserializer, instrumentedConsumerBuilder.GetInternalValueDeserializer()); + return; + + void ErrorHandler(IConsumer consumer, Error error) + { + } + + void LogHandler(IConsumer consumer, LogMessage logMessage) + { + } + + void StatisticsHandler(IConsumer consumer, string statistics) + { + } + + void OAuthBearerTokenRefreshHandler(IConsumer consumer, string oauthBearerToken) + { + } + + void OffsetsCommittedHandler(IConsumer consumer, CommittedOffsets offsets) + { + } + + IEnumerable PartitionsAssignedHandler(IConsumer consumer, List partitions) => new List(); + IEnumerable PartitionsRevokedHandler(IConsumer consumer, List partitions) => new List(); + IEnumerable PartitionsLostHandler(IConsumer consumer, List partitions) => new List(); + } + + private class CustomConsumerBuilder(IEnumerable> config) + : ConsumerBuilder(config); +} diff --git a/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetryProducerBuilderExtensionsTests.cs b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetryProducerBuilderExtensionsTests.cs new file mode 100644 index 0000000000..83025fe323 --- /dev/null +++ b/test/OpenTelemetry.Instrumentation.ConfluentKafka.Tests/OpenTelemetryProducerBuilderExtensionsTests.cs @@ -0,0 +1,113 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +using Confluent.Kafka; +using Xunit; + +namespace OpenTelemetry.Instrumentation.ConfluentKafka.Tests; + +public class OpenTelemetryProducerBuilderExtensionsTests +{ + [Fact] + public void ShouldConvertToInstrumentedProducerBuilder() + { + // Arrange + var config = new List> + { + new("bootstrap.servers", "localhost:9092"), + }; + + var producerBuilder = new ProducerBuilder(config); + + ISerializer keySerializer = Serializers.Utf8; + ISerializer valueSerializer = Serializers.Utf8; + + producerBuilder.SetErrorHandler(ErrorHandler); + producerBuilder.SetLogHandler(LogHandler); + producerBuilder.SetStatisticsHandler(StatisticsHandler); + producerBuilder.SetOAuthBearerTokenRefreshHandler(OAuthBearerTokenRefreshHandler); + producerBuilder.SetKeySerializer(keySerializer); + producerBuilder.SetValueSerializer(valueSerializer); + + // Act + var instrumentedProducerBuilder = producerBuilder.AsInstrumentedProducerBuilder(); + + // Assert + Assert.Equal(ErrorHandler, instrumentedProducerBuilder.GetInternalErrorHandler()); + Assert.Equal(LogHandler, instrumentedProducerBuilder.GetInternalLogHandler()); + Assert.Equal(StatisticsHandler, instrumentedProducerBuilder.GetInternalStatisticsHandler()); + Assert.Equal(OAuthBearerTokenRefreshHandler, instrumentedProducerBuilder.GetInternalOAuthBearerTokenRefreshHandler()); + Assert.Equal(keySerializer, instrumentedProducerBuilder.GetInternalKeySerializer()); + Assert.Equal(valueSerializer, instrumentedProducerBuilder.GetInternalValueSerializer()); + return; + + void ErrorHandler(IProducer producer, Error error) + { + } + + void LogHandler(IProducer producer, LogMessage logMessage) + { + } + + void StatisticsHandler(IProducer producer, string statistics) + { + } + + void OAuthBearerTokenRefreshHandler(IProducer producer, string oauthBearerToken) + { + } + } + + [Fact] + public void ShouldConvertUserDefinedProducerBuilderToInstrumentedProducerBuilder() + { + // Arrange + var config = new List> + { + new("bootstrap.servers", "localhost:9092"), + }; + + var producerBuilder = new CustomProducerBuilder(config); + + ISerializer keySerializer = Serializers.Utf8; + ISerializer valueSerializer = Serializers.Utf8; + + producerBuilder.SetErrorHandler(ErrorHandler); + producerBuilder.SetLogHandler(LogHandler); + producerBuilder.SetStatisticsHandler(StatisticsHandler); + producerBuilder.SetOAuthBearerTokenRefreshHandler(OAuthBearerTokenRefreshHandler); + producerBuilder.SetKeySerializer(keySerializer); + producerBuilder.SetValueSerializer(valueSerializer); + + // Act + var instrumentedProducerBuilder = producerBuilder.AsInstrumentedProducerBuilder(); + + // Assert + Assert.Equal(ErrorHandler, instrumentedProducerBuilder.GetInternalErrorHandler()); + Assert.Equal(LogHandler, instrumentedProducerBuilder.GetInternalLogHandler()); + Assert.Equal(StatisticsHandler, instrumentedProducerBuilder.GetInternalStatisticsHandler()); + Assert.Equal(OAuthBearerTokenRefreshHandler, instrumentedProducerBuilder.GetInternalOAuthBearerTokenRefreshHandler()); + Assert.Equal(keySerializer, instrumentedProducerBuilder.GetInternalKeySerializer()); + Assert.Equal(valueSerializer, instrumentedProducerBuilder.GetInternalValueSerializer()); + return; + + void ErrorHandler(IProducer producer, Error error) + { + } + + void LogHandler(IProducer producer, LogMessage logMessage) + { + } + + void StatisticsHandler(IProducer producer, string statistics) + { + } + + void OAuthBearerTokenRefreshHandler(IProducer producer, string oauthBearerToken) + { + } + } + + private class CustomProducerBuilder(IEnumerable> config) + : ProducerBuilder(config); +} diff --git a/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs b/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs index 2222fecfc7..445818e461 100644 --- a/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs +++ b/test/OpenTelemetry.Instrumentation.Owin.Tests/DiagnosticsMiddlewareTests.cs @@ -195,12 +195,12 @@ Owin has finished to inspect the activity status. */ Activity activity = stoppedActivities[0]; Assert.Equal(OwinInstrumentationActivitySource.IncomingRequestActivityName, activity.OperationName); - Assert.Equal(requestUri.Host + ":" + requestUri.Port, activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeHttpHost).Value); - Assert.Equal("GET", activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeHttpMethod).Value); - Assert.Equal(requestUri.AbsolutePath, activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeHttpTarget).Value); - Assert.Equal(requestUri.ToString(), activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeHttpUrl).Value); + Assert.Equal(requestUri.Host, activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeServerAddress).Value); + Assert.Equal(requestUri.Port, activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeServerPort).Value); + Assert.Equal("GET", activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeHttpRequestMethod).Value); + Assert.Equal(requestUri.AbsolutePath, activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeUrlPath).Value); + Assert.Equal(generateRemoteException ? 500 : 200, activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeHttpResponseStatusCode).Value); - Assert.Equal(generateRemoteException ? 500 : 200, activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeHttpStatusCode).Value); if (generateRemoteException) { Assert.Equal(Status.Error, activity.GetStatus()); @@ -248,13 +248,13 @@ Owin has finished to inspect the activity status. */ { switch (tag.Key) { - case SemanticConventions.AttributeHttpMethod: + case SemanticConventions.AttributeHttpRequestMethod: Assert.Equal("GET", tag.Value); break; case SemanticConventions.AttributeHttpScheme: Assert.Equal(requestUri.Scheme, tag.Value); break; - case SemanticConventions.AttributeHttpStatusCode: + case SemanticConventions.AttributeHttpResponseStatusCode: Assert.Equal(generateRemoteException ? 500 : 200, tag.Value); break; } @@ -343,10 +343,10 @@ Owin has finished to inspect the activity status. */ Activity activity = stoppedActivities[0]; Assert.Equal(OwinInstrumentationActivitySource.IncomingRequestActivityName, activity.OperationName); - Assert.Equal(requestUri.Host + ":" + requestUri.Port, activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeHttpHost).Value); - Assert.Equal("GET", activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeHttpMethod).Value); - Assert.Equal(requestUri.AbsolutePath, activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeHttpTarget).Value); - Assert.Equal(expectedRequestUri.ToString(), activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeHttpUrl).Value); + Assert.Equal(requestUri.Host, activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeServerAddress).Value); + Assert.Equal(requestUri.Port, activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeServerPort).Value); + Assert.Equal("GET", activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeHttpRequestMethod).Value); + Assert.Equal(requestUri.AbsolutePath, activity.TagObjects.FirstOrDefault(t => t.Key == SemanticConventions.AttributeUrlPath).Value); } finally {