diff --git a/README.md b/README.md index b76184bdce1..d1d26e1d317 100644 --- a/README.md +++ b/README.md @@ -84,6 +84,7 @@ calendar](https://calendar.google.com/calendar/embed?src=google.com_b79e3e90j7bb for specific dates. Meetings take place via [Zoom video conference](https://zoom.us/j/8287234601). +The passcode is `77777`. Meeting notes are available as a public [Google doc](https://docs.google.com/document/d/1yjjD6aBcLxlRazYrawukDgrhZMObwHARJbB9glWdHj8/edit?usp=sharing). diff --git a/examples/Console/TestJaegerExporter.cs b/examples/Console/TestJaegerExporter.cs index f54273a009f..04426a00742 100644 --- a/examples/Console/TestJaegerExporter.cs +++ b/examples/Console/TestJaegerExporter.cs @@ -23,6 +23,22 @@ internal class TestJaegerExporter { internal static object Run(string host, int port) { + // Prerequisite for running this example. + // Setup Jaegar inside local docker using following command (Source: https://www.jaegertracing.io/docs/1.21/getting-started/#all-in-one): + /* + $ docker run -d --name jaeger \ + -e COLLECTOR_ZIPKIN_HTTP_PORT=9411 \ + -p 5775:5775/udp \ + -p 6831:6831/udp \ + -p 6832:6832/udp \ + -p 5778:5778 \ + -p 16686:16686 \ + -p 14268:14268 \ + -p 14250:14250 \ + -p 9411:9411 \ + jaegertracing/all-in-one:1.21 + */ + // To run this example, run the following command from // the reporoot\examples\Console\. // (eg: C:\repos\opentelemetry-dotnet\examples\Console\) diff --git a/src/OpenTelemetry.Exporter.Console/CHANGELOG.md b/src/OpenTelemetry.Exporter.Console/CHANGELOG.md index e1d44f255cf..8299c0ee5fc 100644 --- a/src/OpenTelemetry.Exporter.Console/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Console/CHANGELOG.md @@ -10,6 +10,10 @@ `ConsoleExporter` to get rid of type specific check in the class ([#1593](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1593)) +* Replaced Debug.WriteLine with Trace.WriteLine to display the logs to the Debug + window with Release configuration + ([#1719](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1719)) + ## 1.0.0-rc1.1 Released 2020-Nov-17 diff --git a/src/OpenTelemetry.Exporter.Console/ConsoleExporter.cs b/src/OpenTelemetry.Exporter.Console/ConsoleExporter.cs index 0711730b45c..edca47e2e24 100644 --- a/src/OpenTelemetry.Exporter.Console/ConsoleExporter.cs +++ b/src/OpenTelemetry.Exporter.Console/ConsoleExporter.cs @@ -14,8 +14,6 @@ // limitations under the License. // -using System.Diagnostics; - namespace OpenTelemetry.Exporter { public abstract class ConsoleExporter : BaseExporter @@ -37,7 +35,7 @@ protected void WriteLine(string message) if (this.options.Targets.HasFlag(ConsoleExporterOutputTargets.Debug)) { - Debug.WriteLine(message); + System.Diagnostics.Trace.WriteLine(message); } } } diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/net452/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/net452/PublicAPI.Unshipped.txt index 739fa9964cf..0661ab0e137 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/net452/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/net452/PublicAPI.Unshipped.txt @@ -1,5 +1,5 @@ -OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporter -OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporter.OtlpExporter(OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions options) -> void +OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpTraceExporter +OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpTraceExporter.OtlpTraceExporter(OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions options) -> void OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions.BatchExportProcessorOptions.get -> OpenTelemetry.BatchExportProcessorOptions OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions.BatchExportProcessorOptions.set -> void @@ -14,7 +14,7 @@ OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions.ExportProcessor OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions.Headers.get -> Grpc.Core.Metadata OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions.Headers.set -> void OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions.OtlpExporterOptions() -> void -OpenTelemetry.Trace.OtlpExporterHelperExtensions -override OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporter.Export(in OpenTelemetry.Batch activityBatch) -> OpenTelemetry.ExportResult -override OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporter.OnShutdown(int timeoutMilliseconds) -> bool -static OpenTelemetry.Trace.OtlpExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder +OpenTelemetry.Trace.OtlpTraceExporterHelperExtensions +override OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpTraceExporter.Export(in OpenTelemetry.Batch activityBatch) -> OpenTelemetry.ExportResult +override OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpTraceExporter.OnShutdown(int timeoutMilliseconds) -> bool +static OpenTelemetry.Trace.OtlpTraceExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/net46/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/net46/PublicAPI.Unshipped.txt index 739fa9964cf..0661ab0e137 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/net46/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/net46/PublicAPI.Unshipped.txt @@ -1,5 +1,5 @@ -OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporter -OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporter.OtlpExporter(OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions options) -> void +OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpTraceExporter +OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpTraceExporter.OtlpTraceExporter(OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions options) -> void OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions.BatchExportProcessorOptions.get -> OpenTelemetry.BatchExportProcessorOptions OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions.BatchExportProcessorOptions.set -> void @@ -14,7 +14,7 @@ OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions.ExportProcessor OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions.Headers.get -> Grpc.Core.Metadata OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions.Headers.set -> void OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions.OtlpExporterOptions() -> void -OpenTelemetry.Trace.OtlpExporterHelperExtensions -override OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporter.Export(in OpenTelemetry.Batch activityBatch) -> OpenTelemetry.ExportResult -override OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporter.OnShutdown(int timeoutMilliseconds) -> bool -static OpenTelemetry.Trace.OtlpExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder +OpenTelemetry.Trace.OtlpTraceExporterHelperExtensions +override OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpTraceExporter.Export(in OpenTelemetry.Batch activityBatch) -> OpenTelemetry.ExportResult +override OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpTraceExporter.OnShutdown(int timeoutMilliseconds) -> bool +static OpenTelemetry.Trace.OtlpTraceExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 739fa9964cf..0661ab0e137 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,5 +1,5 @@ -OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporter -OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporter.OtlpExporter(OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions options) -> void +OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpTraceExporter +OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpTraceExporter.OtlpTraceExporter(OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions options) -> void OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions.BatchExportProcessorOptions.get -> OpenTelemetry.BatchExportProcessorOptions OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions.BatchExportProcessorOptions.set -> void @@ -14,7 +14,7 @@ OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions.ExportProcessor OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions.Headers.get -> Grpc.Core.Metadata OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions.Headers.set -> void OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions.OtlpExporterOptions() -> void -OpenTelemetry.Trace.OtlpExporterHelperExtensions -override OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporter.Export(in OpenTelemetry.Batch activityBatch) -> OpenTelemetry.ExportResult -override OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporter.OnShutdown(int timeoutMilliseconds) -> bool -static OpenTelemetry.Trace.OtlpExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder +OpenTelemetry.Trace.OtlpTraceExporterHelperExtensions +override OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpTraceExporter.Export(in OpenTelemetry.Batch activityBatch) -> OpenTelemetry.ExportResult +override OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpTraceExporter.OnShutdown(int timeoutMilliseconds) -> bool +static OpenTelemetry.Trace.OtlpTraceExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt index 846802596aa..ef43c4050d7 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/netstandard2.1/PublicAPI.Unshipped.txt @@ -1,5 +1,5 @@ -OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporter -OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporter.OtlpExporter(OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions options) -> void +OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpTraceExporter +OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpTraceExporter.OtlpTraceExporter(OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions options) -> void OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions.BatchExportProcessorOptions.get -> OpenTelemetry.BatchExportProcessorOptions OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions.BatchExportProcessorOptions.set -> void @@ -12,7 +12,7 @@ OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions.ExportProcessor OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions.Headers.get -> Grpc.Core.Metadata OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions.Headers.set -> void OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporterOptions.OtlpExporterOptions() -> void -OpenTelemetry.Trace.OtlpExporterHelperExtensions -override OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporter.Export(in OpenTelemetry.Batch activityBatch) -> OpenTelemetry.ExportResult -override OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpExporter.OnShutdown(int timeoutMilliseconds) -> bool -static OpenTelemetry.Trace.OtlpExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder +OpenTelemetry.Trace.OtlpTraceExporterHelperExtensions +override OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpTraceExporter.Export(in OpenTelemetry.Batch activityBatch) -> OpenTelemetry.ExportResult +override OpenTelemetry.Exporter.OpenTelemetryProtocol.OtlpTraceExporter.OnShutdown(int timeoutMilliseconds) -> bool +static OpenTelemetry.Trace.OtlpTraceExporterHelperExtensions.AddOtlpExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md index 1b2ce181932..abed5a6d50d 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md @@ -2,7 +2,7 @@ ## Unreleased -* Changed `OltpExporter` class and constructor from internal to public. +* Changed `OltpTraceExporter` class and constructor from internal to public. ([#1612](https://github.com/open-telemetry/opentelemetry-dotnet/issues/1612)) * In `OtlpExporterOptions.cs`: Exporter options now include a switch for diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporter.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporter.cs similarity index 91% rename from src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporter.cs rename to src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporter.cs index 7352aaf8094..d21216aa266 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporter.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporter.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -35,7 +35,7 @@ namespace OpenTelemetry.Exporter.OpenTelemetryProtocol /// Exporter consuming and exporting the data using /// the OpenTelemetry protocol (OTLP). /// - public class OtlpExporter : BaseExporter + public class OtlpTraceExporter : BaseExporter { private const string DefaultServiceName = "OpenTelemetry Exporter"; @@ -49,20 +49,20 @@ public class OtlpExporter : BaseExporter private readonly Metadata headers; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// Configuration options for the exporter. - public OtlpExporter(OtlpExporterOptions options) + public OtlpTraceExporter(OtlpExporterOptions options) : this(options, null) { } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// Configuration options for the exporter. /// . - internal OtlpExporter(OtlpExporterOptions options, OtlpCollector.TraceService.ITraceServiceClient traceServiceClient = null) + internal OtlpTraceExporter(OtlpExporterOptions options, OtlpCollector.TraceService.ITraceServiceClient traceServiceClient = null) { this.options = options ?? throw new ArgumentNullException(nameof(options)); this.headers = options.Headers ?? throw new ArgumentException("Headers were not provided on options.", nameof(options)); diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterHelperExtensions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporterHelperExtensions.cs similarity index 92% rename from src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterHelperExtensions.cs rename to src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporterHelperExtensions.cs index 6bd0810a64b..ad7eb71005e 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterHelperExtensions.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpTraceExporterHelperExtensions.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -23,7 +23,7 @@ namespace OpenTelemetry.Trace /// /// Extension methods to simplify registering of the OpenTelemetry Protocol (OTLP) exporter. /// - public static class OtlpExporterHelperExtensions + public static class OtlpTraceExporterHelperExtensions { /// /// Adds OpenTelemetry Protocol (OTLP) exporter to the TracerProvider. @@ -41,7 +41,7 @@ public static TracerProviderBuilder AddOtlpExporter(this TracerProviderBuilder b var exporterOptions = new OtlpExporterOptions(); configure?.Invoke(exporterOptions); - var otlpExporter = new OtlpExporter(exporterOptions); + var otlpExporter = new OtlpTraceExporter(exporterOptions); if (exporterOptions.ExportProcessorType == ExportProcessorType.Simple) { diff --git a/src/OpenTelemetry.Exporter.Zipkin/CHANGELOG.md b/src/OpenTelemetry.Exporter.Zipkin/CHANGELOG.md index 0bad17af44c..8b6931dad03 100644 --- a/src/OpenTelemetry.Exporter.Zipkin/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Zipkin/CHANGELOG.md @@ -20,6 +20,9 @@ `True`/`False`. ([#1609](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1609)) +* Span tags will no longer be populated with Resource Attributes. + ([#1663](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1663)) + ## 1.0.0-rc1.1 Released 2020-Nov-17 diff --git a/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporter.cs b/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporter.cs index 98ea5aed566..06f70c3c9eb 100644 --- a/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporter.cs +++ b/src/OpenTelemetry.Exporter.Zipkin/ZipkinExporter.cs @@ -108,24 +108,13 @@ internal void SetLocalEndpointFromResource(Resource resource) } string serviceName = null; - Dictionary tags = null; foreach (var label in resource.Attributes) { - string key = label.Key; - - switch (key) + if (label.Key == ResourceSemanticConventions.AttributeServiceName) { - case ResourceSemanticConventions.AttributeServiceName: - serviceName = label.Value as string; - continue; + serviceName = label.Value as string; + break; } - - if (tags == null) - { - tags = new Dictionary(); - } - - tags[key] = label.Value; } if (string.IsNullOrEmpty(serviceName)) @@ -138,7 +127,7 @@ internal void SetLocalEndpointFromResource(Resource resource) ipv4, ipv6, port: null, - tags); + tags: null); } private static string ResolveHostAddress(string hostName, AddressFamily family) diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/.publicApi/net452/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.SqlClient/.publicApi/net452/PublicAPI.Unshipped.txt index 63a3249cb8c..83aa554a2e0 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/.publicApi/net452/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.SqlClient/.publicApi/net452/PublicAPI.Unshipped.txt @@ -3,8 +3,8 @@ OpenTelemetry.Instrumentation.SqlClient.SqlClientInstrumentationOptions.EnableCo OpenTelemetry.Instrumentation.SqlClient.SqlClientInstrumentationOptions.EnableConnectionLevelAttributes.set -> void OpenTelemetry.Instrumentation.SqlClient.SqlClientInstrumentationOptions.Enrich.get -> System.Action OpenTelemetry.Instrumentation.SqlClient.SqlClientInstrumentationOptions.Enrich.set -> void -OpenTelemetry.Instrumentation.SqlClient.SqlClientInstrumentationOptions.SetStatementText.get -> bool -OpenTelemetry.Instrumentation.SqlClient.SqlClientInstrumentationOptions.SetStatementText.set -> void +OpenTelemetry.Instrumentation.SqlClient.SqlClientInstrumentationOptions.SetDbStatement.get -> bool +OpenTelemetry.Instrumentation.SqlClient.SqlClientInstrumentationOptions.SetDbStatement.set -> void OpenTelemetry.Instrumentation.SqlClient.SqlClientInstrumentationOptions.SqlClientInstrumentationOptions() -> void OpenTelemetry.Trace.TracerProviderBuilderExtensions static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddSqlClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configureSqlClientInstrumentationOptions = null) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/.publicApi/net461/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.SqlClient/.publicApi/net461/PublicAPI.Unshipped.txt index 63a3249cb8c..83aa554a2e0 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/.publicApi/net461/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.SqlClient/.publicApi/net461/PublicAPI.Unshipped.txt @@ -3,8 +3,8 @@ OpenTelemetry.Instrumentation.SqlClient.SqlClientInstrumentationOptions.EnableCo OpenTelemetry.Instrumentation.SqlClient.SqlClientInstrumentationOptions.EnableConnectionLevelAttributes.set -> void OpenTelemetry.Instrumentation.SqlClient.SqlClientInstrumentationOptions.Enrich.get -> System.Action OpenTelemetry.Instrumentation.SqlClient.SqlClientInstrumentationOptions.Enrich.set -> void -OpenTelemetry.Instrumentation.SqlClient.SqlClientInstrumentationOptions.SetStatementText.get -> bool -OpenTelemetry.Instrumentation.SqlClient.SqlClientInstrumentationOptions.SetStatementText.set -> void +OpenTelemetry.Instrumentation.SqlClient.SqlClientInstrumentationOptions.SetDbStatement.get -> bool +OpenTelemetry.Instrumentation.SqlClient.SqlClientInstrumentationOptions.SetDbStatement.set -> void OpenTelemetry.Instrumentation.SqlClient.SqlClientInstrumentationOptions.SqlClientInstrumentationOptions() -> void OpenTelemetry.Trace.TracerProviderBuilderExtensions static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddSqlClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configureSqlClientInstrumentationOptions = null) -> OpenTelemetry.Trace.TracerProviderBuilder diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Instrumentation.SqlClient/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index 72b40614295..097e255db3b 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Instrumentation.SqlClient/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -5,10 +5,10 @@ OpenTelemetry.Instrumentation.SqlClient.SqlClientInstrumentationOptions.Enrich.g OpenTelemetry.Instrumentation.SqlClient.SqlClientInstrumentationOptions.Enrich.set -> void OpenTelemetry.Instrumentation.SqlClient.SqlClientInstrumentationOptions.RecordException.get -> bool OpenTelemetry.Instrumentation.SqlClient.SqlClientInstrumentationOptions.RecordException.set -> void -OpenTelemetry.Instrumentation.SqlClient.SqlClientInstrumentationOptions.SetStoredProcedureCommandName.get -> bool -OpenTelemetry.Instrumentation.SqlClient.SqlClientInstrumentationOptions.SetStoredProcedureCommandName.set -> void -OpenTelemetry.Instrumentation.SqlClient.SqlClientInstrumentationOptions.SetTextCommandContent.get -> bool -OpenTelemetry.Instrumentation.SqlClient.SqlClientInstrumentationOptions.SetTextCommandContent.set -> void +OpenTelemetry.Instrumentation.SqlClient.SqlClientInstrumentationOptions.SetDbStatementForStoredProcedure.get -> bool +OpenTelemetry.Instrumentation.SqlClient.SqlClientInstrumentationOptions.SetDbStatementForStoredProcedure.set -> void +OpenTelemetry.Instrumentation.SqlClient.SqlClientInstrumentationOptions.SetDbStatementForText.get -> bool +OpenTelemetry.Instrumentation.SqlClient.SqlClientInstrumentationOptions.SetDbStatementForText.set -> void OpenTelemetry.Instrumentation.SqlClient.SqlClientInstrumentationOptions.SqlClientInstrumentationOptions() -> void OpenTelemetry.Trace.TracerProviderBuilderExtensions static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddSqlClientInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action configureSqlClientInstrumentationOptions = null) -> OpenTelemetry.Trace.TracerProviderBuilder \ No newline at end of file diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md b/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md index a6e00b21258..eefedf9a65d 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md +++ b/src/OpenTelemetry.Instrumentation.SqlClient/CHANGELOG.md @@ -6,8 +6,10 @@ on .NET Framework. ([#1599](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1599)) * SqlClientInstrumentationOptions API changes: `SetStoredProcedureCommandName` - and `SetTextCommandContent` are now only available on .NET Core. On .NET - Framework they are replaced by a single `SetStatementText` property. + and `SetTextCommandContent` have been renamed to + `SetDbStatementForStoredProcedure` and `SetDbStatementForText`. They are now + only available on .NET Core. On .NET Framework they are replaced by a single + `SetDbStatement` property. * On .NET Framework, "db.statement_type" attribute is no longer set for activities created by the instrumentation. * New setting on SqlClientInstrumentationOptions on .NET Core: `RecordException` diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs index 9989cfba5e3..5b3502e7957 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs +++ b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlClientDiagnosticListener.cs @@ -93,7 +93,7 @@ public override void OnCustom(string name, Activity activity, object payload) { case CommandType.StoredProcedure: activity.SetTag(SpanAttributeConstants.DatabaseStatementTypeKey, nameof(CommandType.StoredProcedure)); - if (this.options.SetStoredProcedureCommandName) + if (this.options.SetDbStatementForStoredProcedure) { activity.SetTag(SemanticConventions.AttributeDbStatement, (string)commandText); } @@ -102,7 +102,7 @@ public override void OnCustom(string name, Activity activity, object payload) case CommandType.Text: activity.SetTag(SpanAttributeConstants.DatabaseStatementTypeKey, nameof(CommandType.Text)); - if (this.options.SetTextCommandContent) + if (this.options.SetDbStatementForText) { activity.SetTag(SemanticConventions.AttributeDbStatement, (string)commandText); } diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlEventSourceListener.netfx.cs b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlEventSourceListener.netfx.cs index c9bf750c827..539ea03a656 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlEventSourceListener.netfx.cs +++ b/src/OpenTelemetry.Instrumentation.SqlClient/Implementation/SqlEventSourceListener.netfx.cs @@ -144,7 +144,7 @@ private void OnBeginExecute(EventWrittenEventArgs eventData) this.options.AddConnectionLevelDetailsToActivity((string)eventData.Payload[1], activity); string commandText = (string)eventData.Payload[3]; - if (!string.IsNullOrEmpty(commandText) && this.options.SetStatementText) + if (!string.IsNullOrEmpty(commandText) && this.options.SetDbStatement) { activity.SetTag(SemanticConventions.AttributeDbStatement, commandText); } diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/README.md b/src/OpenTelemetry.Instrumentation.SqlClient/README.md index dc8f13c4daa..61ac3960f54 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/README.md +++ b/src/OpenTelemetry.Instrumentation.SqlClient/README.md @@ -60,61 +60,78 @@ For an ASP.NET application, adding instrumentation is typically done in the This instrumentation can be configured to change the default behavior by using `SqlClientInstrumentationOptions`. -### SetStoredProcedureCommandName (.NET Core) +### Capturing 'db.statement' -By default, when CommandType is CommandType.StoredProcedure this -instrumentation will set the `db.statement` attribute to the stored procedure -command name. This behavior can be disabled by setting the -`SetStoredProcedureCommandName` to false. +The `SqlClientInstrumentationOptions` class exposes several properties that can be +used to configure how the [`db.statement`](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/semantic_conventions/database.md#call-level-attributes) +attribute is captured upon execution of a query. -The following example shows how to use `SetStoredProcedureCommandName`. +#### .NET Core - SetDbStatementForStoredProcedure and SetDbStatementForText + +On .NET Core, two properties are available: `SetDbStatementForStoredProcedure` +and `SetDbStatementForText`. These properties control capturing of +`CommandType.StoredProcedure` and `CommandType.Text` respectively. + +`SetDbStatementForStoredProcedure` is _true_ by default and will set +[`db.statement`](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/semantic_conventions/database.md#call-level-attributes) +attribute to the stored procedure command name. + +`SetDbStatementForText` is _false_ by default (to prevent accidental capture of +sensitive data that might be part of the SQL statement text). When set to +`true`, the instrumentation will set [`db.statement`](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/semantic_conventions/database.md#call-level-attributes) +attribute to the text of the SQL command being executed. + +To disable capturing stored procedure commands use configuration like below. ```csharp using var tracerProvider = Sdk.CreateTracerProviderBuilder() .AddSqlClientInstrumentation( - options => options.SetStoredProcedureCommandName = false) + options => options.SetDbStatementForStoredProcedure = false) .AddConsoleExporter() .Build(); ``` -### SetTextCommandContent (.NET Core) - -By default, when CommandType is CommandType.Text, this instrumentation will not -set the `db.statement` attribute. This behavior can be enabled by setting -`SetTextCommandContent` to true. - -The following example shows how to use `SetTextCommandContent`. +To enable capturing of `sqlCommand.CommandText` for `CommandType.Text` use the +following configuration. ```csharp using var tracerProvider = Sdk.CreateTracerProviderBuilder() .AddSqlClientInstrumentation( - options => options.SetTextCommandContent = true) + options => options.SetDbStatementForText = true) .AddConsoleExporter() .Build(); ``` -## SetStatementText (.NET Framework) +#### .NET Framework - SetDbStatement -For .NET Framework, `SetTextCommandContent` and `SetStoredProcedureCommandName` -are not available. Instead, `SetStatementText` should be used to control whether -this instrumentation should set the `db.statement` attribute to the text of the -`SqlCommand` being executed. +For .NET Framework, `SetDbStatementForStoredProcedure` and +`SetDbStatementForText` are not available. Instead, a single `SetDbStatement` +property should be used to control whether this instrumentation should set the +[`db.statement`](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/semantic_conventions/database.md#call-level-attributes) +attribute to the text of the `SqlCommand` being executed. This could either be +a name of a stored procedure or a full text of a `CommandType.Text` query. -Text capturing is _disabled_ by default. If enabled, the instrumentation will -capture both `CommandType.Text` and `CommandType.StoredProcedure` when using -[`Microsoft.Data.SqlClient`](https://www.nuget.org/packages/Microsoft.Data.SqlClient/), -and only `CommandType.StoredProcedure` when using `System.Data.SqlClient`. +On .NET Framwork, unlike .NET Core, the instrumentation capabilities for both +[`Microsoft.Data.SqlClient`](https://www.nuget.org/packages/Microsoft.Data.SqlClient/) +and `System.Data.SqlClient` are limited: -To turn statement capturing on, use the options like in below example. Be -aware that `CommandType.Text` SQL might contain sensitive data. -On [`Microsoft.Data.SqlClient`](https://www.nuget.org/packages/Microsoft.Data.SqlClient/) -only set this to `true` if you are absolutely sure that you are using -exclusively stored procedures, or have no sensitive data in your `sqlCommand.CommandText`. +* [`Microsoft.Data.SqlClient`](https://www.nuget.org/packages/Microsoft.Data.SqlClient/) + always exposes both the stored procedure name and the full query text but + doesn't allow for more granular control to turn either on/off depending on + `CommandType`. +* `System.Data.SqlClient` only exposes stored procedure names and not the full + query text. + +Since `CommandType.Text` might contain sensitive data, all SQL capturing is +_disabled_ by default to protect against accidentally sending full query text +to a telemetry backend. If you are only using stored procedures or have no +sensitive data in your `sqlCommand.CommandText`, you can enable SQL capturing +using the options like below: ```csharp using var tracerProvider = Sdk.CreateTracerProviderBuilder() .AddSqlClientInstrumentation( - options => options.SetStatementText = true) + options => options.SetDbStatement = true) .AddConsoleExporter() .Build(); ``` @@ -140,7 +157,7 @@ using var tracerProvider = Sdk.CreateTracerProviderBuilder() .Build(); ``` -### Enrich +## Enrich This option, available on .NET Core only, allows one to enrich the activity with additional information from the raw `SqlCommand` object. The `Enrich` @@ -193,3 +210,5 @@ using var tracerProvider = Sdk.CreateTracerProviderBuilder() ## References * [OpenTelemetry Project](https://opentelemetry.io/) + +* [OpenTelemetry semantic conventions for database calls](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/semantic_conventions/database.md) diff --git a/src/OpenTelemetry.Instrumentation.SqlClient/SqlClientInstrumentationOptions.cs b/src/OpenTelemetry.Instrumentation.SqlClient/SqlClientInstrumentationOptions.cs index cbb9e80c416..0279739313f 100644 --- a/src/OpenTelemetry.Instrumentation.SqlClient/SqlClientInstrumentationOptions.cs +++ b/src/OpenTelemetry.Instrumentation.SqlClient/SqlClientInstrumentationOptions.cs @@ -80,17 +80,17 @@ public class SqlClientInstrumentationOptions /// When using System.Data.SqlClient, the instrumentation will only capture sqlCommand.CommandText for commands. /// /// - public bool SetStatementText { get; set; } + public bool SetDbStatement { get; set; } #else /// /// Gets or sets a value indicating whether or not the should add the names of commands as the tag. Default value: True. /// - public bool SetStoredProcedureCommandName { get; set; } = true; + public bool SetDbStatementForStoredProcedure { get; set; } = true; /// /// Gets or sets a value indicating whether or not the should add the text of commands as the tag. Default value: False. /// - public bool SetTextCommandContent { get; set; } + public bool SetDbStatementForText { get; set; } #endif /// diff --git a/src/OpenTelemetry/CHANGELOG.md b/src/OpenTelemetry/CHANGELOG.md index 43cbbee1d7b..bcc0e5b4c27 100644 --- a/src/OpenTelemetry/CHANGELOG.md +++ b/src/OpenTelemetry/CHANGELOG.md @@ -22,6 +22,10 @@ * Added check in `ActivitySourceAdapter` class for root activity if traceid is overridden by calling `SetParentId` ([#1355](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1355)) +* Resource Attributes now accept int, short, and float as values, converting + them to supported data types (long for int/short, double for float). For + invalid attributes we now throw an exception instead of logging an error. + ([#1720](https://github.com/open-telemetry/opentelemetry-dotnet/pull/1720)) ## 1.0.0-rc1.1 diff --git a/src/OpenTelemetry/Internal/SelfDiagnosticsConfigRefresher.cs b/src/OpenTelemetry/Internal/SelfDiagnosticsConfigRefresher.cs index 9858537b837..232942801bc 100644 --- a/src/OpenTelemetry/Internal/SelfDiagnosticsConfigRefresher.cs +++ b/src/OpenTelemetry/Internal/SelfDiagnosticsConfigRefresher.cs @@ -36,7 +36,7 @@ internal class SelfDiagnosticsConfigRefresher : IDisposable { private const int ConfigurationUpdatePeriodMilliSeconds = 10000; - private static readonly byte[] MessageOnNewFile = Encoding.UTF8.GetBytes("Successfully opened file."); + private static readonly byte[] MessageOnNewFile = Encoding.UTF8.GetBytes("Successfully opened file.\n"); private readonly CancellationTokenSource cancellationTokenSource; private readonly Task worker; diff --git a/src/OpenTelemetry/Internal/SelfDiagnosticsEventListener.cs b/src/OpenTelemetry/Internal/SelfDiagnosticsEventListener.cs index acf660d9e0a..b03930710cb 100644 --- a/src/OpenTelemetry/Internal/SelfDiagnosticsEventListener.cs +++ b/src/OpenTelemetry/Internal/SelfDiagnosticsEventListener.cs @@ -15,11 +15,11 @@ // using System; +using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics.Tracing; using System.Globalization; using System.IO; -using System.Linq; using System.Text; using System.Threading; @@ -34,14 +34,32 @@ internal class SelfDiagnosticsEventListener : EventListener // Buffer size of the log line. A UTF-16 encoded character in C# can take up to 4 bytes if encoded in UTF-8. private const int BUFFERSIZE = 4 * 5120; private const string EventSourceNamePrefix = "OpenTelemetry-"; + private readonly object lockObj = new object(); private readonly EventLevel logLevel; private readonly SelfDiagnosticsConfigRefresher configRefresher; private readonly ThreadLocal writeBuffer = new ThreadLocal(() => null); + private readonly List eventSourcesBeforeConstructor = new List(); public SelfDiagnosticsEventListener(EventLevel logLevel, SelfDiagnosticsConfigRefresher configRefresher) { this.logLevel = logLevel; this.configRefresher = configRefresher ?? throw new ArgumentNullException(nameof(configRefresher)); + + List eventSources; + lock (this.lockObj) + { + eventSources = this.eventSourcesBeforeConstructor; + this.eventSourcesBeforeConstructor = null; + } + + foreach (var eventSource in eventSources) + { +#if NET452 + this.EnableEvents(eventSource, this.logLevel, (EventKeywords)(-1)); +#else + this.EnableEvents(eventSource, this.logLevel, EventKeywords.All); +#endif + } } /// @@ -105,7 +123,7 @@ internal void WriteEvent(string eventMessage, ReadOnlyCollection payload var buffer = this.writeBuffer.Value; if (buffer == null) { - buffer = new byte[BUFFERSIZE]; // TODO: handle OOM + buffer = new byte[BUFFERSIZE]; this.writeBuffer.Value = buffer; } @@ -118,7 +136,7 @@ internal void WriteEvent(string eventMessage, ReadOnlyCollection payload // Not using foreach because it can cause allocations for (int i = 0; i < payload.Count; ++i) { - object obj = payload.ElementAt(i); + object obj = payload[i]; if (obj != null) { pos = EncodeInBuffer(obj.ToString(), true, buffer, pos); @@ -148,7 +166,8 @@ internal void WriteEvent(string eventMessage, ReadOnlyCollection payload } catch (Exception) { - // One concurrent condition: memory mapped file is disposed in other thread after TryGetLogStream() finishes. + // Fail to allocate memory for buffer, or + // A concurrent condition: memory mapped file is disposed in other thread after TryGetLogStream() finishes. // In this case, silently fail. } } @@ -157,6 +176,22 @@ protected override void OnEventSourceCreated(EventSource eventSource) { if (eventSource.Name.StartsWith(EventSourceNamePrefix, StringComparison.Ordinal)) { + // If there are EventSource classes already initialized as of now, this method would be called from + // the base class constructor before the first line of code in SelfDiagnosticsEventListener constructor. + // In this case logLevel is always its default value, "LogAlways". + // Thus we should save the event source and enable them later, when code runs in constructor. + if (this.eventSourcesBeforeConstructor != null) + { + lock (this.lockObj) + { + if (this.eventSourcesBeforeConstructor != null) + { + this.eventSourcesBeforeConstructor.Add(eventSource); + return; + } + } + } + #if NET452 this.EnableEvents(eventSource, this.logLevel, (EventKeywords)(-1)); #else @@ -175,7 +210,6 @@ protected override void OnEventSourceCreated(EventSource eventSource) /// Data of the EventSource event. protected override void OnEventWritten(EventWrittenEventArgs eventData) { - // TODO: retrieve the file stream object from configRefresher and write to it this.WriteEvent(eventData.Message, eventData.Payload); } } diff --git a/src/OpenTelemetry/Resources/Resource.cs b/src/OpenTelemetry/Resources/Resource.cs index a1fc7269da6..fcb73f8fc82 100644 --- a/src/OpenTelemetry/Resources/Resource.cs +++ b/src/OpenTelemetry/Resources/Resource.cs @@ -101,28 +101,33 @@ private static KeyValuePair SanitizeAttribute(KeyValuePair(sanitizedKey, sanitizedValue); } - private static bool IsValidValue(object value) + private static object SanitizeValue(object value, string keyName) { - if (value != null && (value is string || value is bool || value is long || value is double)) + if (value != null) { - return true; + if (value is string || value is bool || value is long || value is double) + { + return value; + } + + if (value is int || value is short) + { + return System.Convert.ToInt64(value); + } + + if (value is float) + { + return System.Convert.ToDouble(value, System.Globalization.CultureInfo.InvariantCulture); + } + + throw new System.ArgumentException("Attribute value type is not an accepted primitive", keyName); } - return false; + throw new System.ArgumentException("Attribute value is null", keyName); } } } diff --git a/test/Benchmarks/Exporter/OtlpExporterBenchmarks.cs b/test/Benchmarks/Exporter/OtlpExporterBenchmarks.cs index eb631707fef..d41acf1afbf 100644 --- a/test/Benchmarks/Exporter/OtlpExporterBenchmarks.cs +++ b/test/Benchmarks/Exporter/OtlpExporterBenchmarks.cs @@ -30,7 +30,7 @@ namespace Benchmarks.Exporter [MemoryDiagnoser] public class OtlpExporterBenchmarks { - private OtlpExporter exporter; + private OtlpTraceExporter exporter; private Activity activity; private CircularBuffer activityBatch; @@ -43,7 +43,7 @@ public class OtlpExporterBenchmarks [GlobalSetup] public void GlobalSetup() { - this.exporter = new OtlpExporter( + this.exporter = new OtlpTraceExporter( new OtlpExporterOptions(), new NoopTraceServiceClient()); this.activity = ActivityHelper.CreateTestActivity(); diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/IntegrationTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/IntegrationTests.cs index 1d001eeefe7..d59fd87f767 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/IntegrationTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/IntegrationTests.cs @@ -47,7 +47,7 @@ public void ExportResultIsSuccess() #endif }; - var otlpExporter = new OtlpExporter(exporterOptions); + var otlpExporter = new OtlpTraceExporter(exporterOptions); var delegatingExporter = new DelegatingTestExporter(otlpExporter); var exportActivityProcessor = new SimpleActivityExportProcessor(delegatingExporter); diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpExporterTest.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpExporterTest.cs index 6dd9d871e2a..2c1fa843ba6 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpExporterTest.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpExporterTest.cs @@ -71,7 +71,7 @@ public void ToOtlpResourceSpansTest(bool addResource) new ActivitySource("odd", "1.3.5"), }; - using var exporter = new OtlpExporter( + using var exporter = new OtlpTraceExporter( new OtlpExporterOptions(), new NoopTraceServiceClient()); diff --git a/test/OpenTelemetry.Exporter.Zipkin.Tests/ZipkinExporterTests.cs b/test/OpenTelemetry.Exporter.Zipkin.Tests/ZipkinExporterTests.cs index 6c620cb4cb4..24e5bb99f6e 100644 --- a/test/OpenTelemetry.Exporter.Zipkin.Tests/ZipkinExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Zipkin.Tests/ZipkinExporterTests.cs @@ -183,8 +183,6 @@ public void IntegrationTest( [ResourceSemanticConventions.AttributeServiceName] = serviceName, ["service.tag"] = "hello world", }).Build()); - - resoureTags = "\"service.tag\":\"hello world\","; } else { diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs index 4b8c68d2db1..70d19b35328 100644 --- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlClientTests.cs @@ -91,11 +91,11 @@ public void SuccessfulCommandTest( .AddSqlClientInstrumentation(options => { #if !NETFRAMEWORK - options.SetStoredProcedureCommandName = captureStoredProcedureCommandName; - options.SetTextCommandContent = captureTextCommandContent; + options.SetDbStatementForStoredProcedure = captureStoredProcedureCommandName; + options.SetDbStatementForText = captureTextCommandContent; options.RecordException = recordException; #else - options.SetStatementText = captureStoredProcedureCommandName; + options.SetDbStatement = captureStoredProcedureCommandName; #endif if (shouldEnrich) { @@ -165,8 +165,8 @@ public void SqlClientCallsAreCollectedSuccessfully( .AddSqlClientInstrumentation( (opt) => { - opt.SetTextCommandContent = captureTextCommandContent; - opt.SetStoredProcedureCommandName = captureStoredProcedureCommandName; + opt.SetDbStatementForText = captureTextCommandContent; + opt.SetDbStatementForStoredProcedure = captureStoredProcedureCommandName; if (shouldEnrich) { opt.Enrich = ActivityEnrichment; diff --git a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlEventSourceTests.netfx.cs b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlEventSourceTests.netfx.cs index 90d2af4ed54..66c3264cf6c 100644 --- a/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlEventSourceTests.netfx.cs +++ b/test/OpenTelemetry.Instrumentation.SqlClient.Tests/SqlEventSourceTests.netfx.cs @@ -55,7 +55,7 @@ public async Task SuccessfulCommandTest(CommandType commandType, string commandT .AddProcessor(activityProcessor.Object) .AddSqlClientInstrumentation(options => { - options.SetStatementText = captureText; + options.SetDbStatement = captureText; }) .Build(); @@ -112,7 +112,7 @@ public void EventSourceFakeTests( .AddProcessor(activityProcessor.Object) .AddSqlClientInstrumentation(options => { - options.SetStatementText = captureText; + options.SetDbStatement = captureText; options.EnableConnectionLevelAttributes = enableConnectionLevelAttributes; }) .Build(); diff --git a/test/OpenTelemetry.Tests/Internal/SelfDiagnosticsEventListenerTest.cs b/test/OpenTelemetry.Tests/Internal/SelfDiagnosticsEventListenerTest.cs index 0caf7f5eef1..eeca77e9778 100644 --- a/test/OpenTelemetry.Tests/Internal/SelfDiagnosticsEventListenerTest.cs +++ b/test/OpenTelemetry.Tests/Internal/SelfDiagnosticsEventListenerTest.cs @@ -41,10 +41,37 @@ public void SelfDiagnosticsEventListener_constructor_Invalid_Input() }); } + [Fact] + [Trait("Platform", "Any")] + public void SelfDiagnosticsEventListener_EventSourceSetup_LowerSeverity() + { + var configRefresherMock = new Mock(); + var listener = new SelfDiagnosticsEventListener(EventLevel.Error, configRefresherMock.Object); + + // Emitting a Verbose event. Or any EventSource event with lower severity than Error. + OpenTelemetrySdkEventSource.Log.ActivityStarted("Activity started", "1"); + configRefresherMock.Verify(refresher => refresher.TryGetLogStream(It.IsAny(), out It.Ref.IsAny, out It.Ref.IsAny), Times.Never()); + } + + [Fact] + [Trait("Platform", "Any")] + public void SelfDiagnosticsEventListener_EventSourceSetup_HigherSeverity() + { + var configRefresherMock = new Mock(); + configRefresherMock.Setup(configRefresher => configRefresher.TryGetLogStream(It.IsAny(), out It.Ref.IsAny, out It.Ref.IsAny)) + .Returns(true); + var listener = new SelfDiagnosticsEventListener(EventLevel.Error, configRefresherMock.Object); + + // Emitting an Error event. Or any EventSource event with higher than or equal to to Error severity. + OpenTelemetrySdkEventSource.Log.TracerProviderException("TestEvent", "Exception Details"); + configRefresherMock.Verify(refresher => refresher.TryGetLogStream(It.IsAny(), out It.Ref.IsAny, out It.Ref.IsAny)); + } + [Fact] [Trait("Platform", "Any")] public void SelfDiagnosticsEventListener_WriteEvent() { + // Arrange var configRefresherMock = new Mock(); var memoryMappedFile = MemoryMappedFile.CreateFromFile(LOGFILEPATH, FileMode.Create, null, 1024); Stream stream = memoryMappedFile.CreateViewStream(); @@ -55,13 +82,67 @@ public void SelfDiagnosticsEventListener_WriteEvent() configRefresherMock.Setup(configRefresher => configRefresher.TryGetLogStream(timestampPrefixLength + bytes.Length + 1, out stream, out availableByteCount)) .Returns(true); var listener = new SelfDiagnosticsEventListener(EventLevel.Error, configRefresherMock.Object); + + // Act: call WriteEvent method directly listener.WriteEvent(eventMessage, null); + + // Assert configRefresherMock.Verify(refresher => refresher.TryGetLogStream(timestampPrefixLength + bytes.Length + 1, out stream, out availableByteCount)); stream.Dispose(); memoryMappedFile.Dispose(); AssertFileOutput(LOGFILEPATH, eventMessage); } + [Fact] + [Trait("Platform", "Any")] + public void SelfDiagnosticsEventListener_EmitEvent_OmitAsConfigured() + { + // Arrange + var configRefresherMock = new Mock(); + var memoryMappedFile = MemoryMappedFile.CreateFromFile(LOGFILEPATH, FileMode.Create, null, 1024); + Stream stream = memoryMappedFile.CreateViewStream(); + configRefresherMock.Setup(configRefresher => configRefresher.TryGetLogStream(It.IsAny(), out stream, out It.Ref.IsAny)) + .Returns(true); + var listener = new SelfDiagnosticsEventListener(EventLevel.Error, configRefresherMock.Object); + + // Act: emit an event with severity lower than configured + OpenTelemetrySdkEventSource.Log.ActivityStarted("ActivityStart", "123"); + + // Assert + configRefresherMock.Verify(refresher => refresher.TryGetLogStream(It.IsAny(), out stream, out It.Ref.IsAny), Times.Never()); + stream.Dispose(); + memoryMappedFile.Dispose(); + + using FileStream file = File.Open(LOGFILEPATH, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete); + var buffer = new byte[256]; + file.Read(buffer, 0, buffer.Length); + Assert.Equal('\0', (char)buffer[0]); + } + + [Fact] + [Trait("Platform", "Any")] + public void SelfDiagnosticsEventListener_EmitEvent_CaptureAsConfigured() + { + // Arrange + var configRefresherMock = new Mock(); + var memoryMappedFile = MemoryMappedFile.CreateFromFile(LOGFILEPATH, FileMode.Create, null, 1024); + Stream stream = memoryMappedFile.CreateViewStream(); + configRefresherMock.Setup(configRefresher => configRefresher.TryGetLogStream(It.IsAny(), out stream, out It.Ref.IsAny)) + .Returns(true); + var listener = new SelfDiagnosticsEventListener(EventLevel.Error, configRefresherMock.Object); + + // Act: emit an event with severity equal to configured + OpenTelemetrySdkEventSource.Log.TracerProviderException("TestEvent", "Exception Details"); + + // Assert + configRefresherMock.Verify(refresher => refresher.TryGetLogStream(It.IsAny(), out stream, out It.Ref.IsAny)); + stream.Dispose(); + memoryMappedFile.Dispose(); + + var expectedLog = "Unknown error in TracerProvider '{0}': '{1}'.{TestEvent}{Exception Details}"; + AssertFileOutput(LOGFILEPATH, expectedLog); + } + [Fact] [Trait("Platform", "Any")] public void SelfDiagnosticsEventListener_EncodeInBuffer_Empty() @@ -170,11 +251,16 @@ private static void AssertFileOutput(string filePath, string eventMessage) using FileStream file = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete); var buffer = new byte[256]; file.Read(buffer, 0, buffer.Length); - string logMessage = Encoding.UTF8.GetString(buffer); + string logLine = Encoding.UTF8.GetString(buffer); + string logMessage = ParseLogMessage(logLine); + Assert.StartsWith(eventMessage, logMessage); + } + + private static string ParseLogMessage(string logLine) + { int timestampPrefixLength = "2020-08-14T20:33:24.4788109Z:".Length; - string parsedEventMessage = logMessage.Substring(timestampPrefixLength); - Assert.StartsWith(eventMessage, parsedEventMessage); - Assert.Matches(@"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{7}Z:", logMessage.Substring(0, timestampPrefixLength)); + Assert.Matches(@"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{7}Z:", logLine.Substring(0, timestampPrefixLength)); + return logLine.Substring(timestampPrefixLength); } private static void AssertBufferOutput(byte[] expected, byte[] buffer, int startPos, int endPos) diff --git a/test/OpenTelemetry.Tests/Resources/ResourceTest.cs b/test/OpenTelemetry.Tests/Resources/ResourceTest.cs index dea22152802..a9d4d61dff5 100644 --- a/test/OpenTelemetry.Tests/Resources/ResourceTest.cs +++ b/test/OpenTelemetry.Tests/Resources/ResourceTest.cs @@ -46,15 +46,8 @@ public void CreateResource_NullAttributeValue() // Arrange var attributes = new Dictionary { { "NullValue", null } }; - // Act - var resource = new Resource(attributes); - - // Assert - Assert.Single(resource.Attributes); - - var attribute = resource.Attributes.Single(); - Assert.Equal("NullValue", attribute.Key); - Assert.Empty((string)attribute.Value); + // Act and Assert + Assert.Throws(() => new Resource(attributes)); } [Fact] @@ -139,15 +132,25 @@ public void CreateResource_SupportedAttributeTypes() { "long", 1L }, { "bool", true }, { "double", 0.1d }, + + // int and float supported by conversion to long and double + { "int", 1 }, + { "short", (short)1 }, + { "float", 0.1f }, }; var resource = new Resource(attributes); - Assert.Equal(4, resource.Attributes.Count()); + Assert.Equal(7, resource.Attributes.Count()); Assert.Contains(new KeyValuePair("string", "stringValue"), resource.Attributes); Assert.Contains(new KeyValuePair("long", 1L), resource.Attributes); Assert.Contains(new KeyValuePair("bool", true), resource.Attributes); Assert.Contains(new KeyValuePair("double", 0.1d), resource.Attributes); + Assert.Contains(new KeyValuePair("int", 1L), resource.Attributes); + Assert.Contains(new KeyValuePair("short", 1L), resource.Attributes); + + double convertedFloat = Convert.ToDouble(0.1f, System.Globalization.CultureInfo.InvariantCulture); + Assert.Contains(new KeyValuePair("float", convertedFloat), resource.Attributes); } [Fact] @@ -158,16 +161,9 @@ public void CreateResource_NotSupportedAttributeTypes() { "dynamic", new { } }, { "array", new int[1] }, { "complex", this }, - { "float", 0.1f }, }; - var resource = new Resource(attributes); - - Assert.Equal(4, resource.Attributes.Count()); - Assert.Contains(new KeyValuePair("dynamic", string.Empty), resource.Attributes); - Assert.Contains(new KeyValuePair("array", string.Empty), resource.Attributes); - Assert.Contains(new KeyValuePair("complex", string.Empty), resource.Attributes); - Assert.Contains(new KeyValuePair("float", string.Empty), resource.Attributes); + Assert.Throws(() => new Resource(attributes)); } [Fact]