diff --git a/.changelog/2432.changed b/.changelog/2432.changed new file mode 100644 index 00000000000..0c29e0a0a6a --- /dev/null +++ b/.changelog/2432.changed @@ -0,0 +1 @@ +`opentelemetry-api`: document baggage current context behavior. diff --git a/docs/api/baggage.rst b/docs/api/baggage.rst index 34712e78bd8..aa180b8b24a 100644 --- a/docs/api/baggage.rst +++ b/docs/api/baggage.rst @@ -1,6 +1,73 @@ opentelemetry.baggage package ======================================== +The baggage API stores name/value pairs in an OpenTelemetry +``Context``. The helper functions in :mod:`opentelemetry.baggage` +return updated ``Context`` values. They do not mutate or attach the +current context automatically. + +This distinction matters when reading baggage: + +* ``baggage.get_all()`` reads from the current context. +* ``baggage.get_all(context=ctx)`` reads from the explicit context. +* ``baggage.set_baggage(...)`` returns a context containing the new + baggage entry. + +For example: + +.. code-block:: python + + from opentelemetry import baggage + + ctx = baggage.set_baggage("tenant", "acme") + + print(baggage.get_all()) + # {} + + print(dict(baggage.get_all(context=ctx))) + # {'tenant': 'acme'} + +To make the returned context current for the current execution unit, +attach it and later detach it with the token returned by +``context.attach``: + +.. code-block:: python + + from opentelemetry import baggage, context + + ctx = baggage.set_baggage("tenant", "acme") + token = context.attach(ctx) + try: + print(dict(baggage.get_all())) + # {'tenant': 'acme'} + finally: + context.detach(token) + +Always pair ``context.attach`` with ``context.detach``. Dropping the +token can leak baggage into later work on the same execution unit. + +Passing ``context=...`` to another API is also different from attaching +that context. For example, ``tracer.start_as_current_span(..., +context=ctx)`` uses ``ctx`` to choose the parent span, but it does not +make ``ctx`` current for later calls to ``baggage.get_all()``. Attach +the context first when the current baggage should be visible inside the +span scope: + +.. code-block:: python + + from opentelemetry import baggage, context, trace + + tracer = trace.get_tracer(__name__) + ctx = baggage.set_baggage("tenant", "acme") + + token = context.attach(ctx) + try: + with tracer.start_as_current_span("work"): + print(dict(baggage.get_all())) + # {'tenant': 'acme'} + finally: + context.detach(token) + Subpackages ----------- diff --git a/docs/api/context.rst b/docs/api/context.rst index e73d8f674b2..582d1998af5 100644 --- a/docs/api/context.rst +++ b/docs/api/context.rst @@ -1,6 +1,37 @@ opentelemetry.context package ============================= +OpenTelemetry context values are immutable snapshots. Functions such as +``set_value`` and the baggage helpers return a new ``Context`` object +rather than mutating the current one. + +There are two common ways to use a context: + +* Pass it explicitly to APIs that accept a ``context=...`` parameter. +* Attach it with ``context.attach`` so it becomes current for the + current execution unit, then restore the previous context with + ``context.detach``. + +For example: + +.. code-block:: python + + from opentelemetry import context + + ctx = context.set_value("key", "value") + + print(context.get_current().get("key")) + # None + + token = context.attach(ctx) + try: + print(context.get_current().get("key")) + # value + finally: + context.detach(token) + +This is the same model used by :mod:`opentelemetry.baggage`. + Module contents ---------------