public void GlobalSetup() { this.server = TestHttpServer.RunServer( (ctx) => { using (Stream receiveStream = ctx.Request.InputStream) { while (true) { if (receiveStream.Read(this.buffer, 0, this.buffer.Length) == 0) { break; } } } ctx.Response.StatusCode = 200; ctx.Response.OutputStream.Close(); }, out this.serverHost, out this.serverPort); var options = new OtlpExporterOptions { Endpoint = new Uri($"http://{this.serverHost}:{this.serverPort}"), }; this.exporter = new OtlpTraceExporter( options, new OtlpHttpTraceExportClient(options, options.HttpClientFactory())); 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 OtlpTraceExporter(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 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 { Endpoint = new System.Uri($"http://{CollectorEndpoint}"), }; var otlpExporter = new OtlpTraceExporter(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]); }
private static TracerProviderBuilder AddOtlpExporter( TracerProviderBuilder builder, OtlpExporterOptions exporterOptions, Action <OtlpExporterOptions> configure, IServiceProvider serviceProvider) { var originalEndpoint = exporterOptions.Endpoint; configure?.Invoke(exporterOptions); exporterOptions.TryEnableIHttpClientFactoryIntegration(serviceProvider, "OtlpTraceExporter"); exporterOptions.AppendExportPath(originalEndpoint, OtlpExporterOptions.TracesExportPath); var otlpExporter = new OtlpTraceExporter(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))); } }
internal static TracerProviderBuilder AddOtlpExporter( TracerProviderBuilder builder, OtlpExporterOptions exporterOptions, Action <OtlpExporterOptions> configure, IServiceProvider serviceProvider, Func <BaseExporter <Activity>, BaseExporter <Activity> > configureExporterInstance = null) { configure?.Invoke(exporterOptions); exporterOptions.TryEnableIHttpClientFactoryIntegration(serviceProvider, "OtlpTraceExporter"); BaseExporter <Activity> otlpExporter = new OtlpTraceExporter(exporterOptions); if (configureExporterInstance != null) { otlpExporter = configureExporterInstance(otlpExporter); } if (exporterOptions.ExportProcessorType == ExportProcessorType.Simple) { return(builder.AddProcessor(new SimpleActivityExportProcessor(otlpExporter))); } else { var batchOptions = exporterOptions.BatchExportProcessorOptions ?? new(); return(builder.AddProcessor(new BatchActivityExportProcessor( otlpExporter, batchOptions.MaxQueueSize, batchOptions.ScheduledDelayMilliseconds, batchOptions.ExporterTimeoutMilliseconds, batchOptions.MaxExportBatchSize))); } }
public void GlobalSetup() { this.exporter = new OtlpTraceExporter( new OtlpExporterOptions(), new NoopTraceServiceClient()); this.activity = ActivityHelper.CreateTestActivity(); this.activityBatch = new CircularBuffer <Activity>(this.NumberOfSpans); }
public void UserHttpFactoryCalled() { OtlpExporterOptions options = new OtlpExporterOptions(); var defaultFactory = options.HttpClientFactory; int invocations = 0; options.Protocol = OtlpExportProtocol.HttpProtobuf; options.HttpClientFactory = () => { invocations++; return(defaultFactory()); }; using (var exporter = new OtlpTraceExporter(options)) { Assert.Equal(1, invocations); } using (var provider = Sdk.CreateTracerProviderBuilder() .AddOtlpExporter(o => { o.Protocol = OtlpExportProtocol.HttpProtobuf; o.HttpClientFactory = options.HttpClientFactory; }) .Build()) { Assert.Equal(2, invocations); } options.HttpClientFactory = null; Assert.Throws <InvalidOperationException>(() => { using var exporter = new OtlpTraceExporter(options); }); options.HttpClientFactory = () => null; Assert.Throws <InvalidOperationException>(() => { using var exporter = new OtlpTraceExporter(options); }); }
private static TracerProviderBuilder AddOtlpExporter(TracerProviderBuilder builder, OtlpExporterOptions exporterOptions, Action <OtlpExporterOptions> configure = null) { configure?.Invoke(exporterOptions); var otlpExporter = new OtlpTraceExporter(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() { var mockClient = new Mock <OtlpCollector.TraceService.TraceServiceClient>(); mockClient .Setup(m => m.Export( It.IsAny <OtlpCollector.ExportTraceServiceRequest>(), It.IsAny <Metadata>(), It.IsAny <DateTime?>(), It.IsAny <CancellationToken>())) .Returns(new OtlpCollector.ExportTraceServiceResponse()); var options = new OtlpExporterOptions(); this.exporter = new OtlpTraceExporter( options, new OtlpGrpcTraceExportClient(options, mockClient.Object)); this.activity = ActivityHelper.CreateTestActivity(); this.activityBatch = new CircularBuffer <Activity>(this.NumberOfSpans); }
public void ToOtlpResourceSpansTest(bool addResource) { 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 OtlpTraceExporter( new OtlpExporterOptions(), new NoopTraceServiceClient()); if (addResource) { exporter.SetResource( ResourceBuilder.CreateEmpty().AddAttributes( new List <KeyValuePair <string, object> > { new KeyValuePair <string, object>(Resources.ResourceSemanticConventions.AttributeServiceName, "service-name"), new KeyValuePair <string, object>(Resources.ResourceSemanticConventions.AttributeServiceNamespace, "ns1"), }).Build()); } 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 BatchActivityExportProcessor(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.ResourceSemanticConventions.AttributeServiceName && kvp.Value.StringValue == "service-name"); Assert.Contains(oltpResource.Attributes, (kvp) => kvp.Key == Resources.ResourceSemanticConventions.AttributeServiceNamespace && kvp.Value.StringValue == "ns1"); } else { Assert.Contains(oltpResource.Attributes, (kvp) => kvp.Key == Resources.ResourceSemanticConventions.AttributeServiceName && kvp.Value.ToString().Contains("unknown_service:")); } 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); } } } }