Span attributes and events
Use GenAI conventions for standard model-call data or Braintrust attributes to set Braintrust fields directly. Recognized GenAI span events can also supply message data.GenAI attributes
Braintrust implements the OpenTelemetry GenAI semantic conventions. When you send traces with these attributes, they are automatically mapped to Braintrust fields.GenAI events
In addition to attributes, Braintrust also processes GenAI events on spans to extract input/output messages. These events follow the OpenTelemetry GenAI semantic conventions for events:
The message events listed above are processed in the order they appear in the span. When they produce a nonempty input or output message list, that list takes precedence over the corresponding attribute-derived field.
Each event is also stored as a separate log row associated with the span. Mapping a GenAI event into the span’s input or output does not remove the event record.
Braintrust attributes
You can also use thebraintrust namespace to set fields in Braintrust directly:
Fields mapped from
braintrust.* attributes are removed from metadata and stored in the corresponding Braintrust fields. Nonempty input or output arrays whose elements have valid chat roles are recognized as LLM message arrays.
Attribute example
This example sets GenAI and Braintrust attributes using flattened names and JSON-encoded values:Python
Why are some attributes missing from metadata?
Why are some attributes missing from metadata?
For Braintrust-hosted organizations, source attributes such as
ai.prompt, gen_ai.input.messages, and llm.input_messages are removed from metadata once Braintrust has mapped them to a structured field (input, output, metrics, etc.). The data itself can be found on the structured field it was mapped into.Self-hosted deployments behave the same way when the STRIP_OTEL_ATTRIBUTES_FROM_METADATA environment variable is set on the api-ts service.To keep the raw attributes on metadata for a specific span, set the braintrust.otel.preserve_attributes attribute to true on that span.For details, see Strip OTel attributes from metadata.Log records
Each OTLP record becomes a separate row withspan_attributes.type set to log:
Log attributes do not undergo the GenAI mapping used for trace spans. For example, a
gen_ai.usage.input_tokens attribute on a log remains in metadata rather than becoming a token metric.
A record with valid trace and span IDs shares its owning span’s span_id and trace’s root_span_id, while retaining its own unique row id. A record with a trace ID only joins that trace with a generated span ID. A record without a trace ID receives its own span and root IDs.
OpenTelemetry span events received through /otel/v1/traces, including GenAI events, are also stored as separate log rows. Each event row shares its span’s span_id and root_span_id and has its own row id. The event name is stored in output, and its attributes are stored in metadata. Recognized GenAI events can also populate fields on the owning span, as described in GenAI events.
Log levels and exceptions
On Braintrust-hosted deployments, the severity number maps tospan_attributes.log_level:
If the severity number is absent,
0, or outside these ranges, Braintrust does not derive a log level. The original severity number and text remain in context.otel.log.
On Braintrust-hosted deployments, the top-level error field is populated from nonempty exception attributes: exception.stacktrace, exception.type, or exception.message. Severity and message body alone do not populate it. Use span_attributes.log_level to find error-level messages, and error to find records carrying exception details.
The canonical log-level mapping and exception-only
error behavior require data plane v2.15.0 or later. On earlier versions, inspect the original severity fields in context.otel.log. Error-level severity can populate error even without exception attributes.