Make traces useful for your app. Auto-instrumentation captures the basics — inputs, outputs, tokens, latency. But your app has context that matters: customer tier, A/B test variant, prompt template version, error details. This page covers all the ways to add it.
Start with the standard attribute names Arize AX expects:
Semantic Conventions
OpenInference Semantic Conventions are the standardized attribute names that Arize AX uses to render your trace data correctly — model name, messages, token counts, span kinds, and more. When you use these attributes, your data shows up in the right places in the UI.
Install the semantic conventions package:Use SpanAttributes to set standardized attribute names on your spans: Install the semantic conventions package:Use SemanticConventions to set standardized attributes: In Java, use the attribute strings directly: Install the semantic-conventions package:Set attributes using typed constants instead of raw strings:
Beyond attribute names, every span has built-in primitives for signaling outcome and marking moments during execution:
Status, Events, and Exceptions
Set Status
Signal whether a span succeeded or failed. Every span carries a status — OK, ERROR, or UNSET.
Add Events
Span Events are lightweight log messages attached to a span at a point in time.
Record Exceptions
Capture exception details and mark the span as failed in one flow:
Errors in Go are values, not exceptions — RecordError captures one and SetStatus marks the span as failed:
With outcome primitives covered, the next layer is how inputs and outputs are captured with structure:
Log Structured Inputs and Outputs
Set input.value / output.value for the table view, and llm.input_messages / llm.output_messages for structured chat messages:
Semantic conventions and structured I/O cover standard LLM data. But your app has its own context that doesn’t fit any standard attribute:
Custom Attributes
Customer tier, environment, feature flags, A/B test variants — custom attributes let you attach this app-specific data to spans so you can filter, group, and analyze by it in Arize AX.
Best practice: vendor your attributes (e.g., mycompany.) so they don’t clash with semantic conventions.
Get the current span and set your custom attributes: Set attributes when creating a span or on an active span: Set attributes directly on the span: Get the current span and set attributes — attribute.String / attribute.Int / attribute.Bool cover most cases:
When to use a custom attribute vs. metadata:
- Custom attribute — attached to a single span, each one a distinct filterable field in the UI. Use for values you filter or group by: customer tier, A/B variant, feature flag.
- Metadata (via
using_metadata in Python, setMetadata in JS/TS, or WithMetadata in Go) — propagates to every child span in a context and is stored as a single JSON field. Use for request-wide context: request ID, experiment name, pipeline version.
Propagate Attributes to All Child Spans
Set attributes once on OpenTelemetry Context, and tracing integrations will propagate them to all child spans automatically.
using_attributes
Convenience — combines using_session, using_user, using_metadata, using_tags, and using_prompt_template:get_attributes_from_context
Read context attributes and attach them to manually created spans:setAttributes
Combine with other setters:getAttributesFromContext
The helpers stash values on context.Context (via unexported keys, not OTel baggage), so they flow through your in-process call graph but never leak out as baggage HTTP headers on downstream requests. The per-provider instrumentors (openinference-instrumentation-openai-go, openinference-instrumentation-anthropic-sdk-go) read them back and apply them to every LLM span descended from the context, even when the call is several layers deep.WithMetadata takes a pre-serialized JSON string — Go has no native dict literal, so callers json.Marshal their own map. (Python using_metadata and JS setMetadata take dicts/objects because both languages have built-in JSON encoding for them.)WithSession / WithUser
ApplyContextAttributes
Read context attributes and attach them to manually created spans:WithSuppression
Exclude evaluator or grader calls from the customer’s trace — descendant calls through an instrumented client emit no span:Go has no combined setter analogous to Python’s using_attributes — chain the individual With* helpers when you need to set multiple values. The order doesn’t matter; each returns a derived context.
using_tags / setTags set tag.tags on spans. For project- or dataset-level tags (a separate platform feature), see Tags.
Prompt templates have their own dedicated propagation helper:
Prompt Templates and Variables
Instrument prompt templates so you can experiment with changes in the Prompt Playground.
Recommended for LLM spans only.
There’s no context helper for prompt templates in Go — set the attributes directly on the LLM span using semantic-conventions constants:
Prompt templates are set at span-creation time. For data that arrives later — review status, corrections, labels added after generation — patch the span after it’s been ingested:
Log Latent Metadata
Useful when your system enriches data after generation time — for example, adding review status, corrections, or labels that weren’t available when the trace was created.
Next step
Group multi-turn conversations together with sessions: