feat(propagator-env-carrier): add environment variable carrier helpers#6774
feat(propagator-env-carrier): add environment variable carrier helpers#6774pellared wants to merge 10 commits into
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #6774 +/- ##
==========================================
+ Coverage 94.92% 94.94% +0.01%
==========================================
Files 377 378 +1
Lines 12817 12858 +41
Branches 2924 2932 +8
==========================================
+ Hits 12167 12208 +41
Misses 650 650
🚀 New features to boost your workflow:
|
|
CC @open-telemetry/semconv-cicd-approvers |
maryliag
left a comment
There was a problem hiding this comment.
Thank you for working on this! Added a few questions/comments
| } | ||
| } | ||
|
|
||
| get(_carrier: unknown, key: string): string | undefined { |
There was a problem hiding this comment.
can you just not have _carrier here and below if the function don't use them? If you need this format, consider using never as type, so users don't try to pass something
There was a problem hiding this comment.
Addressed in 2eb8181
I switched EnvironmentGetter to TextMapGetter<void>. That still prevents callers from passing an object directly, but avoids the awkward undefined as never pattern. This also follows what is already done in
| */ | ||
| export class EnvironmentSetter implements TextMapSetter<EnvironmentCarrierMap> { | ||
| set(carrier: EnvironmentCarrierMap, key: string, value: string): void { | ||
| carrier[normalizeKey(key)] = value; |
There was a problem hiding this comment.
the set uses local carrier, and the get uses the global, this opens for chances of the global one not getting updated and the get not working as expected.
There was a problem hiding this comment.
this opens for chances of the global one not getting updated
This is correct (sic!). This is to follow https://opentelemetry.io/docs/specs/otel/context/env-carriers/#operational-guidance and https://opentelemetry.io/docs/specs/otel/context/env-carriers/#process-spawning.
Also see https://opentelemetry.io/docs/specs/otel/context/env-carriers/#supplementary-guidelines
|
|
||
| const getter = new EnvironmentGetter(); | ||
|
|
||
| assert.deepStrictEqual(getter.keys({}), ['TRACEPARENT']); |
There was a problem hiding this comment.
can we have documented somewhere about which one takes precedent? So users can expect the same results if running the test multiple times
right now is dependent on the order to which the key was set, if that is indeed the expectation, make it clear, or change to something that always give the same results, such as returning the keys in alphabetical order
There was a problem hiding this comment.
Good call. I strongly believe we have agreed in some reviews or maybe even Spec SIG call that this is an error scenario (name collision) and the behavior is not specified for this case. I think it would be good to cover call it out explicitly in the specification and document it here in EnvironmentGetter. Thoughts?
| const originalEnv = { ...process.env }; | ||
|
|
||
| beforeEach(() => { | ||
| clearEnv(); |
There was a problem hiding this comment.
no need to delete twice, you're already deleting at the end of each test
There was a problem hiding this comment.
Note that env vars such as TRACEPARENT can be used by CI/CD automation. For instance GitHub Actions may use it in future and it may make these tests flaky. Therefore, I think it is safer to even clear before the test. Side note: one of the main reason why env var carrier was added was the work of the CI/CD SIG.
There was a problem hiding this comment.
in that case, I suggest adding env names that you know won't conflict with pre existing values
There was a problem hiding this comment.
What about integration tests under describe('propagator integration' ? Do we want to remove them? Note that there are similar tests in https://github.com/open-telemetry/opentelemetry-js/blob/main/experimental/packages/shim-opencensus/test/propagation.test.ts
There was a problem hiding this comment.
no need to remove the test, but I want to make them deterministic, if there is a chance an env variable changed outside of the tests could affect the results and cause flaky tests, we want to avoid that.
Even if you delete TRACEPARENT before a test, but you say that other processes might be using it, there is no guarantee that in between the before and the actual test, that value can be added to the env and the test fails.
The majority of your test don't need to use the env TRACEPARENT, do they? you can call yabadabadoo and should still work 😄
For the test of propagator integration, seems like that is the env variable you want to test, so you can leave it there, and if we ever get flaky tests we can decide what to do
| /** | ||
| * TextMapSetter that writes propagation values to an environment map. | ||
| */ | ||
| export class EnvironmentSetter implements TextMapSetter<EnvironmentCarrierMap> { |
There was a problem hiding this comment.
I think it is safer to have EnvironmentSetter implements TextMapSetter<void> and accept Record<string, string> or EnvironmentCarrierMap in the constructor. This follows the pattern used in
See test scenarios it('should inject for reference.
@maryliag, thoughts?
| const originalEnv = { ...process.env }; | ||
|
|
||
| beforeEach(() => { | ||
| clearEnv(); |
There was a problem hiding this comment.
no need to remove the test, but I want to make them deterministic, if there is a chance an env variable changed outside of the tests could affect the results and cause flaky tests, we want to avoid that.
Even if you delete TRACEPARENT before a test, but you say that other processes might be using it, there is no guarantee that in between the before and the actual test, that value can be added to the env and the test fails.
The majority of your test don't need to use the env TRACEPARENT, do they? you can call yabadabadoo and should still work 😄
For the test of propagator integration, seems like that is the env variable you want to test, so you can leave it there, and if we ever get flaky tests we can decide what to do
| const ASCII_UNDERSCORE = '_'.charCodeAt(0); | ||
| const ASCII_CASE_OFFSET = ASCII_LOWER_A - ASCII_UPPER_A; | ||
|
|
||
| /* |
There was a problem hiding this comment.
| /* | |
| /** |
nit
Which problem is this PR solving?
Fixes #6223
Short description of the changes
Implement environment variable carrier following https://opentelemetry.io/docs/specs/otel/context/env-carriers/ and open-telemetry/opentelemetry-specification#5102
This is important for interoperability with other languages (https://github.com/open-telemetry/opentelemetry-specification/blob/main/spec-compliance-matrix.md?plain=1#L254) and tooling.
Type of change
How Has This Been Tested?
Example usage from
README.md.Checklist: