Appearance
OTEL_RESOURCE_ATTRIBUTES adds attributes to every span and metric at the resource level (set once, applies to the whole process). The APIs on this page let you go further - attach custom attributes globally from code, scope them to a specific block or function call, or tag spans with agent identity - without restarting your process or touching environment variables.
Global custom attributes
Pass custom_span_attributes and/or custom_metrics_attributes to elsai_arms.init() to have every auto-instrumented span or metric include them:
python
elsai_arms.init(
custom_span_attributes={"team": "platform", "tier": "premium"},
custom_metrics_attributes={"deployment": "us-east-1"},
)These behave like resource attributes but are set in code rather than via environment variable, and can be computed at startup (e.g. from config you've already loaded).
Scope attributes to a block of code
using_attributes() attaches attributes only to spans created while it's active - as a context manager or as a decorator:
python
# As a context manager
with elsai_arms.using_attributes(user_id="u_123", session_id="s_456"):
completion = client.chat.completions.create(...)
# As a decorator
@elsai_arms.using_attributes(feature="checkout")
def handle_checkout(order):
completion = client.chat.completions.create(...)Attributes set this way apply only to spans created inside the with block or during the decorated function call - they don't leak into unrelated spans elsewhere in your application.
Attach attributes to a single call
inject_additional_attributes() runs a callable with attributes attached for that call only, useful when you don't want to wrap a whole block:
python
result = elsai_arms.inject_additional_attributes(
lambda: client.chat.completions.create(...),
{"request_source": "batch_job"},
)Tag spans with agent identity
agent_context() and agent_version_context() tag spans and metrics with gen_ai.agent.name and gen_ai.agent.version respectively. These are what power the Agents page's per-agent grouping and version snapshots - use them if you want explicit control over agent identity instead of relying on inferred grouping from service.name.
python
with elsai_arms.agent_context(name="support-agent"):
with elsai_arms.agent_version_context(version="v3"):
completion = client.chat.completions.create(...)Manual spans with custom attributes
For manually created spans (as opposed to attaching attributes to auto-instrumented ones), use elsai_arms.start_trace() and set custom metadata directly on the returned span - see Manual Tracing for the full @elsai_arms.trace / start_trace() reference.
python
with elsai_arms.start_trace(name="checkout-flow") as trace:
completion = client.chat.completions.create(...)
trace.set_result(completion.choices[0].message.content)
trace.set_metadata({"order_id": "o_789", "cart_value": 129.99})