Custom Attributes
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
Section titled “Global custom attributes”Pass custom_span_attributes and/or custom_metrics_attributes to shield360.init() to have every auto-instrumented span or metric include them:
import shield360
shield360.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
Section titled “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:
import shield360
# As a context managerwith shield360.using_attributes(user_id="u_123", session_id="s_456"): completion = client.chat.completions.create(...)
# As a decorator@shield360.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
Section titled “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:
import shield360
result = shield360.inject_additional_attributes( lambda: client.chat.completions.create(...), {"request_source": "batch_job"},)Tag spans with agent identity
Section titled “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.
import shield360
with shield360.agent_context(name="support-agent"): with shield360.agent_version_context(version="v3"): completion = client.chat.completions.create(...)Manual spans with custom attributes
Section titled “Manual spans with custom attributes”For manually created spans (as opposed to attaching attributes to auto-instrumented ones), use shield360.start_trace() and set custom metadata directly on the returned span - see Manual Tracing for the full @shield360.trace / start_trace() reference.
with shield360.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})