-
Notifications
You must be signed in to change notification settings - Fork 773
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for OTEL_EXPORTER_JAEGER_AGENT_HOST and OTEL_EXPORTER_JAEGER_AGENT_PORT #2123
Conversation
Codecov Report
@@ Coverage Diff @@
## main #2123 +/- ##
==========================================
- Coverage 85.04% 84.99% -0.05%
==========================================
Files 187 187
Lines 6103 6124 +21
==========================================
+ Hits 5190 5205 +15
- Misses 913 919 +6
|
|
||
public JaegerExporterOptions() | ||
{ | ||
string agentHostEnvVar = Environment.GetEnvironmentVariable(OTelAgentHostEnvVarKey); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would move this section to a new method - eg SetOptionsViaEnvironmentVariables
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Waiting for feedback (e.g. upvotes) from others as this may be subjective. This would be the only call in this constructor so it might be seen as an unnecessary level of indirection.
I have no strong opinion here.
Initially, I thought of doing something like:
this.AgentHost = GetStringFromEnvironmentVariable(OTelAgentHostEnvVarKey, "localhost");
this.AgentPort = GetIntFromEnvironmentVariable(OTelAgentPortEnvVarKey, 6831, value => JaegerExporterEventSource.Log.FailedToParseEnvironmentVariable(OTelAgentPortEnvVarKey, value));
but it felt unnecessary complex
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I kind of like these "general" methods but deferring until more usage seems reasonable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please wrap this inside try..catch incase user doesn't have permission to read, it'll throw.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will do
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Handled: 5909df2
@cijothomas Do we want to have another event for a generic Exception
? Personally, I do not like it b/c we can catch e.g. an OutOfMemoryException
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this looks good.
Should we add option to 'DisableEnvironmentVariablesRead' ? Currently it's a new feature that is forcefully on - so to avoid conflicts when there are multiple applications on the same server instance, there is a way to turn it off. E: Code has anyway higher importance... but then every single env variable has to be manually neutralized. Which still would cause unwanted feature to be turned on. |
From my experience (especially for cloud native apps) the env vars are set per process. IT is even possible it off in code by simply: Environment.SetEnvironmentVariable("OTEL_EXPORTER_JAEGER_AGENT_HOST", null);
Environment.SetEnvironmentVariable("OTEL_EXPORTER_JAEGER_AGENT_PORT", null); |
private const string OTelAgentHostEnvVarKey = "OTEL_EXPORTER_JAEGER_AGENT_HOST"; | ||
private const string OTelAgentPortEnvVarKey = "OTEL_EXPORTER_JAEGER_AGENT_PORT"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we want to have such keys as public static readonly
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My vote is to keep as constants. But I would make them internal const string
so you could use them in your unit tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For me using the hardcoded strings makes the test more readable. Especially that the env vars are defined by specs and won't likely change. Moreover it is a safeguard for against changing the const by mistake.
Therefore maybe let's keep it as it is? I tried to keep the code similar to OTEL_RESOURCE_ATTRIBUTES
implementation:
- https://github.com/open-telemetry/opentelemetry-dotnet/blob/6b7f2dd77cf9d37260a853fcc95f7b77e296065d/test/OpenTelemetry.Tests/Resources/ResourceTest.cs
- https://github.com/open-telemetry/opentelemetry-dotnet/blob/6b7f2dd77cf9d37260a853fcc95f7b77e296065d/test/OpenTelemetry.Tests/Resources/OtelEnvResourceDetectorTest.cs
- https://github.com/open-telemetry/opentelemetry-dotnet/blob/6b7f2dd77cf9d37260a853fcc95f7b77e296065d/src/OpenTelemetry/Resources/OtelEnvResourceDetector.cs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO it is an SSOT (single source of truth) principle type of thing. If it does need to ever change, it should be in one spot. Those other spots are misbehaving 🤣 Here's a good one:
Lines 467 to 474 in a5b42fb
if (expectedStatusCode == StatusCode.Error) | |
{ | |
Assert.Contains(jaegerSpan.Tags, t => t.Key == JaegerActivityExtensions.JaegerErrorFlagTagName && t.VType == JaegerTagType.BOOL && (t.VBool ?? false)); | |
} | |
else | |
{ | |
Assert.DoesNotContain(jaegerSpan.Tags, t => t.Key == JaegerActivityExtensions.JaegerErrorFlagTagName); | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed aad91eb
} | ||
else | ||
{ | ||
JaegerExporterEventSource.Log.FailedToParseEnvironmentVariable(OTelAgentPortEnvVarKey, agentPortEnvVar); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cijothomas Should we actually throw here? I think typically we do for misconfiguration during startup.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My answer would be no.
It is currently unspecified according to the spec.
Looking at the other part of the spec, it seems the general spirit is that the SDK should handle environment variable in a graceful way (e.g. if some environment variable wouldn't make sense, fall back to the default value rather than fail the app).
I think the reason is that environment variable might be invasive (e.g. a child process might inherit environment variable, someone might set global environment variable unintentionally), and we don't want that to crash the app.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just wondering in the case of a typo how visible will be that? Are the host and port logged in case of error sending to a destination? Perhaps log the host, port (all the options in general) at startup so one can easily check the effective configuration?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cijothomas What do you think of logging the options as an event with EventLevel.Informational
(or even EventLevel.Verbose
) e.g. here:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As long as we don't log credential by default, I'm supportive (Information/Verbose both sound good to me) 😃
- If the environment variable is something like
OTEL_EXPORTER_JAEGER_AGENT_PASSWORD
, we should not log it by default (or we should replace the password with something like******
). - If the user put credential in
OTEL_EXPORTER_JAEGER_AGENT_PORT
, it's their problem, we will log it (rather than trying to do some smart detection and guess if it could be credential).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@reyang @cijothomas
Should I do it as a separate PR?
Personally, I see it as a separate feature and maybe it would be worth adding a dedicated point in the changelog for it.
I added a "TODO (next PRs)" section in the PR description.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 to doing it as a separate PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pellared could you please also update https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/src/OpenTelemetry.Exporter.Jaeger#readme to include the env vars.
@pellared @pjanotti Is there a timeline you are looking to get this change as part of a stable release? |
@cijothomas thanks for considering the release timelines. Auto-Instrumentation wouldn't be in a stable release soon so we will have to live with provisional releases between 1.1.0 and 1.2.0 while we migrate auto-instrumentation to the SDK. |
PS. |
I think the root readme should be really small! |
To avoid adding last minute changes to the 1.1.0 release, this PR will be merged after 1.1.0 is shipped (later today). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Blocking, just to prevent accidental merge.
Co-authored-by: Cijo Thomas <cithomas@microsoft.com>
Ready to merge as 1.1.0 ship has sailed. Will wait till today evening to see if there are any feedbacks, and then merge. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Partially addresses #1453.
This feature is important so that we can reuse the SDK in https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation
Changes
The
JaegerExporterOptions
defaults can be overriden usingOTEL_EXPORTER_JAEGER_AGENT_HOST
andOTEL_EXPORTER_JAEGER_AGENT_PORT
envionmental variables as defined in the specification.The implementation is similar to OTel Go, OTel Python, and other languages as well.
For significant contributions please make sure you have completed the following items:
CHANGELOG.md
updated for non-trivial changesTODO (next PRs)