-
Notifications
You must be signed in to change notification settings - Fork 711
[carriers] add env carrier #4609
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import os | ||
import typing | ||
from opentelemetry.propagators.textmap import Getter, Setter | ||
|
||
class EnvironmentGetter(Getter[dict]): | ||
"""This class decorates Getter to enable extracting from context and baggage | ||
from environment variables. | ||
""" | ||
|
||
KEY_MAPPING = { | ||
"TRACEPARENT": "traceparent", | ||
"TRACESTATE": "tracestate", | ||
"BAGGAGE": "baggage" | ||
} | ||
|
||
def __init__(self): | ||
self.env_copy = dict(os.environ) | ||
self.carrier = {} | ||
|
||
for env_key, env_value in self.env_copy.items(): | ||
if env_key in self.KEY_MAPPING: | ||
self.carrier[self.KEY_MAPPING[env_key]] = env_value | ||
else: | ||
self.carrier[env_key] = env_value | ||
|
||
def get(self, carrier: dict, key: str) -> typing.Optional[typing.List[str]]: | ||
"""Get a value from the carrier for the given key""" | ||
val = self.carrier.get(key, None) | ||
if val is None: | ||
return None | ||
if isinstance(val, typing.Iterable) and not isinstance(val, str): | ||
return list(val) | ||
return [val] | ||
|
||
def keys(self, carrier: dict) -> typing.List[str]: | ||
"""Get all keys from the carrier""" | ||
return list(self.carrier.keys()) | ||
|
||
class EnvironmentSetter(Setter[dict]): | ||
"""This class decorates Setter to enable setting context and baggage | ||
to environment variables. | ||
Comment on lines
+40
to
+41
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn't the purpose to set env var for some external process that is going to be spawned? From https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/context/env-carriers.md#environment-variable-immutability and https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/context/env-carriers.md#process-spawning:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes! and i'm not sure how best to handle that implementation detail in practice at the carrier level, which is why this is the current set. In my head, the only real path forward I see with that portion is to set a dictionary with that new context, and let the implementer use that returned dictionary when they do a popen run like the below psuedo code: # somehow the user sets traceparent, tracestate, and baggage and setter returns an env dictionary instead of what it does now
# the user then takes that and sets it in popen
popen.run(["something"], env=env_dict_from_setter) |
||
""" | ||
|
||
KEY_MAPPING = { | ||
"TRACEPARENT": "traceparent", | ||
"TRACESTATE": "tracestate", | ||
"BAGGAGE": "baggage" | ||
} | ||
|
||
def set(self, carrier: typing.Optional[dict], key: str, value: str) -> None: | ||
"""Set a value in the environment for the given key. | ||
|
||
Args: | ||
carrier: Not used for environment setter, but kept for interface compatibility | ||
key: The key to set | ||
value: The value to set | ||
""" | ||
env_key = self.KEY_MAPPING.get(key, key.upper()) | ||
|
||
os.environ[env_key] = value |
Uh oh!
There was an error while loading. Please reload this page.
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.
Why do we have a special handling only for these 3 keys?
Couldn't 't it be a generic rule how the env carrier works?
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've removed them and pushed the change. They were there from my working prototype enforcing on those were set. However, in the specification we do outline that those are the three well-known values that SHOULD be used. Ultimately, it doesn't matter. Any keys in the environment, when lowered, will only be considered valid context in the text map propagator when they match one of the well-known specs supported in the SDK. (b3/w3c/etc)