public static TracerProviderBuilder AddOtlpExporter(this TracerProviderBuilder builder, Action <OtlpExporterOptions> configure = null) { if (builder == null) { throw new ArgumentNullException(nameof(builder)); } var exporterOptions = new OtlpExporterOptions(); configure?.Invoke(exporterOptions); var otlpExporter = new OtlpExporter(exporterOptions); if (exporterOptions.ExportProcessorType == ExportProcessorType.Simple) { return(builder.AddProcessor(new SimpleActivityExportProcessor(otlpExporter))); } else { return(builder.AddProcessor(new BatchActivityExportProcessor( otlpExporter, exporterOptions.BatchExportProcessorOptions.MaxQueueSize, exporterOptions.BatchExportProcessorOptions.ScheduledDelayMilliseconds, exporterOptions.BatchExportProcessorOptions.ExporterTimeoutMilliseconds, exporterOptions.BatchExportProcessorOptions.MaxExportBatchSize))); } }
public void GlobalSetup() { this.exporter = new OtlpExporter( new OtlpExporterOptions(), new NoopTraceServiceClient()); this.activity = ActivityHelper.CreateTestActivity(); this.activityBatch = new CircularBuffer <Activity>(this.NumberOfSpans); }
public static TracerProviderBuilder AddOtlpExporter(this TracerProviderBuilder builder, Action <OtlpExporterOptions> configure = null) { if (builder == null) { throw new ArgumentNullException(nameof(builder)); } var exporterOptions = new OtlpExporterOptions(); configure?.Invoke(exporterOptions); var otlpExporter = new OtlpExporter(exporterOptions); // TODO: Pick Simple vs Batching based on OtlpExporterOptions return(builder.AddProcessor(new BatchExportActivityProcessor(otlpExporter))); }
/// <summary> /// Enables the OpenTelemetry Protocol (OTLP) exporter. /// </summary> /// <param name="builder">Open Telemetry builder to use.</param> /// <param name="configure">Exporter configuration options.</param> /// <param name="processorConfigure">Activity processor configuration.</param> /// <returns>The instance of <see cref="TracerProviderBuilder"/> to chain the calls.</returns> public static TracerProviderBuilder UseOtlpExporter(this TracerProviderBuilder builder, Action <OtlpExporterOptions> configure = null, Action <ActivityProcessorPipelineBuilder> processorConfigure = null) { if (builder == null) { throw new ArgumentNullException(nameof(builder)); } return(builder.AddProcessorPipeline(pipeline => { var exporterOptions = new OtlpExporterOptions(); configure?.Invoke(exporterOptions); var activityExporter = new OtlpExporter(exporterOptions); processorConfigure?.Invoke(pipeline); pipeline.SetExporter(activityExporter); })); }
public void OtlpExporter_Batching() { using OtlpExporter exporter = new OtlpExporter( new OtlpExporterOptions(), this.client) { }; for (int i = 0; i < this.NumberOfBatches; i++) { for (int c = 0; c < this.NumberOfSpans; c++) { this.activityBatch.Add(this.activity); } exporter.Export(new Batch <Activity>(this.activityBatch, this.NumberOfSpans)); } exporter.Shutdown(); }
public void ExportResultIsSuccess() { #if NETCOREAPP3_1 // Adding the OtlpExporter creates a GrpcChannel. // This switch must be set before creating a GrpcChannel/HttpClient when calling an insecure gRPC service. // See: https://docs.microsoft.com/aspnet/core/grpc/troubleshoot#call-insecure-grpc-services-with-net-core-client AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true); #endif var exporterOptions = new OtlpExporterOptions { #if NETCOREAPP3_1 || NET5_0 Endpoint = new System.Uri($"http://{CollectorEndpoint}"), #else Endpoint = CollectorEndpoint, #endif }; var otlpExporter = new OtlpExporter(exporterOptions); var delegatingExporter = new DelegatingTestExporter <Activity>(otlpExporter); var exportActivityProcessor = new SimpleActivityExportProcessor(delegatingExporter); var activitySourceName = "otlp.collector.test"; var builder = Sdk.CreateTracerProviderBuilder() .AddSource(activitySourceName) .AddProcessor(exportActivityProcessor); using var tracerProvider = builder.Build(); var source = new ActivitySource(activitySourceName); var activity = source.StartActivity("Test Activity"); activity?.Stop(); Assert.Single(delegatingExporter.ExportResults); Assert.Equal(ExportResult.Success, delegatingExporter.ExportResults[0]); }
internal static void AddBatch( this OtlpCollector.ExportTraceServiceRequest request, OtlpExporter otlpExporter, in Batch <Activity> activityBatch)
public void ToOtlpResourceSpansTest(bool addResource, string optionsServiceName) { var evenTags = new[] { new KeyValuePair <string, object>("k0", "v0") }; var oddTags = new[] { new KeyValuePair <string, object>("k1", "v1") }; var sources = new[] { new ActivitySource("even", "2.4.6"), new ActivitySource("odd", "1.3.5"), }; using var exporter = new OtlpExporter( new OtlpExporterOptions { ServiceName = optionsServiceName, }, new NoopTraceServiceClient()); if (addResource) { exporter.SetResource( new Resources.Resource( new List <KeyValuePair <string, object> > { new KeyValuePair <string, object>(Resources.Resource.ServiceNameKey, "service-name"), new KeyValuePair <string, object>(Resources.Resource.ServiceNamespaceKey, "ns1"), })); } else { exporter.SetResource(Resources.Resource.Empty); } var builder = Sdk.CreateTracerProviderBuilder() .AddSource(sources[0].Name) .AddSource(sources[1].Name); using var openTelemetrySdk = builder.Build(); var processor = new BatchExportProcessor <Activity>(new TestExporter <Activity>(RunTest)); const int numOfSpans = 10; bool isEven; for (var i = 0; i < numOfSpans; i++) { isEven = i % 2 == 0; var source = sources[i % 2]; var activityKind = isEven ? ActivityKind.Client : ActivityKind.Server; var activityTags = isEven ? evenTags : oddTags; using Activity activity = source.StartActivity($"span-{i}", activityKind, parentContext: default, activityTags); processor.OnEnd(activity); } processor.Shutdown(); void RunTest(Batch <Activity> batch) { var request = new OtlpCollector.ExportTraceServiceRequest(); request.AddBatch(exporter.ProcessResource, batch); Assert.Single(request.ResourceSpans); var oltpResource = request.ResourceSpans.First().Resource; if (addResource) { Assert.Contains(oltpResource.Attributes, (kvp) => kvp.Key == Resources.Resource.ServiceNameKey && kvp.Value.StringValue == "service-name"); Assert.Contains(oltpResource.Attributes, (kvp) => kvp.Key == Resources.Resource.ServiceNamespaceKey && kvp.Value.StringValue == "ns1"); } else { Assert.Contains(oltpResource.Attributes, (kvp) => kvp.Key == Resources.Resource.ServiceNameKey && kvp.Value.StringValue == optionsServiceName); } foreach (var instrumentationLibrarySpans in request.ResourceSpans.First().InstrumentationLibrarySpans) { Assert.Equal(numOfSpans / 2, instrumentationLibrarySpans.Spans.Count); Assert.NotNull(instrumentationLibrarySpans.InstrumentationLibrary); var expectedSpanNames = new List <string>(); var start = instrumentationLibrarySpans.InstrumentationLibrary.Name == "even" ? 0 : 1; for (var i = start; i < numOfSpans; i += 2) { expectedSpanNames.Add($"span-{i}"); } var otlpSpans = instrumentationLibrarySpans.Spans; Assert.Equal(expectedSpanNames.Count, otlpSpans.Count); var kv0 = new OtlpCommon.KeyValue { Key = "k0", Value = new OtlpCommon.AnyValue { StringValue = "v0" } }; var kv1 = new OtlpCommon.KeyValue { Key = "k1", Value = new OtlpCommon.AnyValue { StringValue = "v1" } }; var expectedTag = instrumentationLibrarySpans.InstrumentationLibrary.Name == "even" ? kv0 : kv1; foreach (var otlpSpan in otlpSpans) { Assert.Contains(otlpSpan.Name, expectedSpanNames); Assert.Contains(expectedTag, otlpSpan.Attributes); } } } }