From a9fed4252b2149a184e2a5fb855089fd11a39007 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Paj=C4=85k?= Date: Thu, 15 Jul 2021 05:46:02 +0200 Subject: [PATCH] Add support for OTEL_EXPORTER_JAEGER_AGENT_HOST and OTEL_EXPORTER_JAEGER_AGENT_PORT (#2123) --- .../CHANGELOG.md | 6 ++ .../JaegerExporterEventSource.cs | 22 +++++ .../JaegerExporterOptions.cs | 37 ++++++++ src/OpenTelemetry.Exporter.Jaeger/README.md | 27 ++++-- .../JaegerExporterOptionsTests.cs | 93 +++++++++++++++++++ 5 files changed, 179 insertions(+), 6 deletions(-) create mode 100644 test/OpenTelemetry.Exporter.Jaeger.Tests/JaegerExporterOptionsTests.cs diff --git a/src/OpenTelemetry.Exporter.Jaeger/CHANGELOG.md b/src/OpenTelemetry.Exporter.Jaeger/CHANGELOG.md index 7049872f884..4083e8eb32a 100644 --- a/src/OpenTelemetry.Exporter.Jaeger/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Jaeger/CHANGELOG.md @@ -2,6 +2,12 @@ ## Unreleased +* The `JaegerExporterOptions` defaults can be overridden using + `OTEL_EXPORTER_JAEGER_AGENT_HOST` and `OTEL_EXPORTER_JAEGER_AGENT_PORT` + envionmental variables as defined in the + [specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md#jaeger-exporter). + ([#2123](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2123)) + ## 1.1.0 Released 2021-Jul-12 diff --git a/src/OpenTelemetry.Exporter.Jaeger/Implementation/JaegerExporterEventSource.cs b/src/OpenTelemetry.Exporter.Jaeger/Implementation/JaegerExporterEventSource.cs index 747982f555b..45ec68f326a 100644 --- a/src/OpenTelemetry.Exporter.Jaeger/Implementation/JaegerExporterEventSource.cs +++ b/src/OpenTelemetry.Exporter.Jaeger/Implementation/JaegerExporterEventSource.cs @@ -16,6 +16,7 @@ using System; using System.Diagnostics.Tracing; +using System.Security; using OpenTelemetry.Internal; namespace OpenTelemetry.Exporter.Jaeger.Implementation @@ -37,10 +38,31 @@ public void FailedExport(Exception ex) } } + [NonEvent] + public void MissingPermissionsToReadEnvironmentVariable(SecurityException ex) + { + if (this.IsEnabled(EventLevel.Warning, EventKeywords.All)) + { + this.MissingPermissionsToReadEnvironmentVariable(ex.ToInvariantString()); + } + } + [Event(1, Message = "Failed to send spans: '{0}'", Level = EventLevel.Error)] public void FailedExport(string exception) { this.WriteEvent(1, exception); } + + [Event(2, Message = "Failed to parse environment variable: '{0}', value: '{1}'.", Level = EventLevel.Warning)] + public void FailedToParseEnvironmentVariable(string name, string value) + { + this.WriteEvent(2, name, value); + } + + [Event(3, Message = "Missing permissions to read environment variable: '{0}'", Level = EventLevel.Warning)] + public void MissingPermissionsToReadEnvironmentVariable(string exception) + { + this.WriteEvent(3, exception); + } } } diff --git a/src/OpenTelemetry.Exporter.Jaeger/JaegerExporterOptions.cs b/src/OpenTelemetry.Exporter.Jaeger/JaegerExporterOptions.cs index ea6ebdb1b91..d6ef31ef731 100644 --- a/src/OpenTelemetry.Exporter.Jaeger/JaegerExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.Jaeger/JaegerExporterOptions.cs @@ -14,7 +14,10 @@ // limitations under the License. // +using System; using System.Diagnostics; +using System.Security; +using OpenTelemetry.Exporter.Jaeger.Implementation; namespace OpenTelemetry.Exporter { @@ -22,6 +25,40 @@ public class JaegerExporterOptions { internal const int DefaultMaxPayloadSizeInBytes = 4096; + internal const string OTelAgentHostEnvVarKey = "OTEL_EXPORTER_JAEGER_AGENT_HOST"; + internal const string OTelAgentPortEnvVarKey = "OTEL_EXPORTER_JAEGER_AGENT_PORT"; + + public JaegerExporterOptions() + { + try + { + string agentHostEnvVar = Environment.GetEnvironmentVariable(OTelAgentHostEnvVarKey); + if (!string.IsNullOrEmpty(agentHostEnvVar)) + { + this.AgentHost = agentHostEnvVar; + } + + string agentPortEnvVar = Environment.GetEnvironmentVariable(OTelAgentPortEnvVarKey); + if (!string.IsNullOrEmpty(agentPortEnvVar)) + { + if (int.TryParse(agentPortEnvVar, out var agentPortValue)) + { + this.AgentPort = agentPortValue; + } + else + { + JaegerExporterEventSource.Log.FailedToParseEnvironmentVariable(OTelAgentPortEnvVarKey, agentPortEnvVar); + } + } + } + catch (SecurityException ex) + { + // The caller does not have the required permission to + // retrieve the value of an environment variable from the current process. + JaegerExporterEventSource.Log.MissingPermissionsToReadEnvironmentVariable(ex); + } + } + /// /// Gets or sets the Jaeger agent host. Default value: localhost. /// diff --git a/src/OpenTelemetry.Exporter.Jaeger/README.md b/src/OpenTelemetry.Exporter.Jaeger/README.md index f0b5bbbc4cb..e69929ea840 100644 --- a/src/OpenTelemetry.Exporter.Jaeger/README.md +++ b/src/OpenTelemetry.Exporter.Jaeger/README.md @@ -29,17 +29,22 @@ dotnet add package OpenTelemetry.Exporter.Jaeger ## Configuration You can configure the `JaegerExporter` through `JaegerExporterOptions` +and environment variables. The `JaegerExporterOptions` setters +take precedence over the environment variables. + +## Options Properties + +The `JaegerExporter` can be configured using the `JaegerExporterOptions` properties: -* `AgentHost`: Usually `localhost` since an agent should usually be running on - the same machine as your application or service. -* `AgentPort`: The compact thrift protocol port of the Jaeger Agent (default - `6831`). +* `AgentHost`: The Jaeger Agent host (default `localhost`). +* `AgentPort`: The compact thrift protocol UDP port of the Jaeger Agent + (default `6831`). * `MaxPayloadSizeInBytes`: The maximum size of each UDP packet that gets - sent to the agent. (default `4096`). + sent to the agent (default `4096`). * `ExportProcessorType`: Whether the exporter should use [Batch or Simple exporting processor](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/sdk.md#built-in-span-processors) - . + (default `ExportProcessorType.Batch`). * `BatchExportProcessorOptions`: Configuration options for the batch exporter. Only used if ExportProcessorType is set to Batch. @@ -47,6 +52,16 @@ See the [`TestJaegerExporter.cs`](../../examples/Console/TestJaegerExporter.cs) for an example of how to use the exporter. +## Environment Variables + +The following environment variables can be used to override the default +values of the `JaegerExporterOptions`. + +| Environment variable | `JaegerExporterOptions` property | +| --------------------------------- | -------------------------------- | +| `OTEL_EXPORTER_JAEGER_AGENT_HOST` | `AgentHost` | +| `OTEL_EXPORTER_JAEGER_AGENT_PORT` | `AgentPort` | + ## References * [Jaeger](https://www.jaegertracing.io) diff --git a/test/OpenTelemetry.Exporter.Jaeger.Tests/JaegerExporterOptionsTests.cs b/test/OpenTelemetry.Exporter.Jaeger.Tests/JaegerExporterOptionsTests.cs new file mode 100644 index 00000000000..4716f975a2f --- /dev/null +++ b/test/OpenTelemetry.Exporter.Jaeger.Tests/JaegerExporterOptionsTests.cs @@ -0,0 +1,93 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using Xunit; + +namespace OpenTelemetry.Exporter.Jaeger.Tests +{ + public class JaegerExporterOptionsTests : IDisposable + { + public JaegerExporterOptionsTests() + { + this.ClearEnvVars(); + } + + public void Dispose() + { + this.ClearEnvVars(); + } + + [Fact] + public void JaegerExporterOptions_Defaults() + { + var options = new JaegerExporterOptions(); + + Assert.Equal("localhost", options.AgentHost); + Assert.Equal(6831, options.AgentPort); + Assert.Equal(4096, options.MaxPayloadSizeInBytes); + Assert.Equal(ExportProcessorType.Batch, options.ExportProcessorType); + } + + [Fact] + public void JaegerExporterOptions_EnvironmentVariableOverride() + { + Environment.SetEnvironmentVariable(JaegerExporterOptions.OTelAgentHostEnvVarKey, "jeager-host"); + Environment.SetEnvironmentVariable(JaegerExporterOptions.OTelAgentPortEnvVarKey, "123"); + + var options = new JaegerExporterOptions(); + + Assert.Equal("jeager-host", options.AgentHost); + Assert.Equal(123, options.AgentPort); + } + + [Fact] + public void JaegerExporterOptions_InvalidPortEnvironmentVariableOverride() + { + Environment.SetEnvironmentVariable(JaegerExporterOptions.OTelAgentPortEnvVarKey, "invalid"); + + var options = new JaegerExporterOptions(); + + Assert.Equal(6831, options.AgentPort); // use default + } + + [Fact] + public void JaegerExporterOptions_SetterOverridesEnvironmentVariable() + { + Environment.SetEnvironmentVariable(JaegerExporterOptions.OTelAgentHostEnvVarKey, "envvar-host"); + + var options = new JaegerExporterOptions + { + AgentHost = "incode-host", + }; + + Assert.Equal("incode-host", options.AgentHost); + } + + [Fact] + public void JaegerExporterOptions_EnvironmentVariableNames() + { + Assert.Equal("OTEL_EXPORTER_JAEGER_AGENT_HOST", JaegerExporterOptions.OTelAgentHostEnvVarKey); + Assert.Equal("OTEL_EXPORTER_JAEGER_AGENT_PORT", JaegerExporterOptions.OTelAgentPortEnvVarKey); + } + + private void ClearEnvVars() + { + Environment.SetEnvironmentVariable(JaegerExporterOptions.OTelAgentHostEnvVarKey, null); + Environment.SetEnvironmentVariable(JaegerExporterOptions.OTelAgentPortEnvVarKey, null); + } + } +}