Trace inputs and outputs
Log Inputs
Most auto-instrumentors automatically populate the input field without requiring manual logging. This section reviews manual instrumentation of input.
In the tracing tab, our table view looks for the span attributes "input.value"
(or SpanAttributes.INPUT_VALUE
or SemanticConventions.INPUT_VALUE
) to populate the input column.

When viewing a single span, certain fields are highlighted more prominently. For example, in LLM-type spans, the Input messages are captured by the SpanAttributes.LLM_INPUT_MESSAGES
key. This enables you to view the full series of messages exchanged between the user and assistant on one page.

This example code shows how you can instrument the inputs of a python app.
One thing to note is the format of the LLM_INPUT_MESSAGES
. This attribute is represented as a list of chat completion params, which have role
and content
fields. In order to set this, you need to set the index as well as each field for each message, as shown in the example below. This example uses the ChatCompletionMessageParam
message type from OpenAi, but any data following the format of example_messages
below will do.
import json
from typing import List
from openai.types.chat import ChatCompletionMessageParam
from openinference.semconv.trace import MessageAttributes, SpanAttributes
from opentelemetry.trace import Span
example_messages = [
{
"role": "user",
"content": "something the user said",
},
{
"role": "assistant",
"content": "something the LLM responded with",
},
]
def set_input_attrs(
span: Span,
messages: List[ChatCompletionMessageParam],
prompt_template: str,
prompt_vars: dict | str,
) -> None:
# INPUT_VALUE shows up on the table view under the input column
# It also shows up under the `input` tab on the span
span.set_attribute(
SpanAttributes.INPUT_VALUE,
messages[-1].get("content", ""), # get the last message for input
)
# LLM_INPUT_MESSAGES shows up under `input_messages` tab on the span page
for idx, msg in enumerate(messages):
# Set the role per message
span.set_attribute(
f"{SpanAttributes.LLM_INPUT_MESSAGES}.{idx}.{MessageAttributes.MESSAGE_ROLE}",
msg["role"],
)
# Set the content per message
span.set_attribute(
f"{SpanAttributes.LLM_INPUT_MESSAGES}.{idx}.{MessageAttributes.MESSAGE_CONTENT}",
msg.get("content", ""),
)
Log Outputs
Most auto-instrumentors automatically populate the output field without requiring manual logging. This section reviews manual instrumentation of output.
In the tracing tab, our table view looks for the span attributes "output.value"
(or SpanAttributes.OUTPUT_VALUE
or SemanticConventions.OUTPUT_VALUE
) to populate the Output column.

When viewing a single span, there are two output fields that are highlighted. Output messages are captured by the SpanAttributes.LLM_OUTPUT_MESSAGES
key. This enables you to view the full message returned.

This example code shows how you can log outputs as well. This follows a similar convention to input logging:
from openai.types.chat import ChatCompletionAssistantMessageParam
from openinference.semconv.trace import MessageAttributes, SpanAttributes
from opentelemetry.trace import Span
def set_output_attrs(
span: Span,
response_message: ChatCompletionAssistantMessageParam,
) -> None:
# OUTPUT_VALUE shows up on the table view under the output column
# It also shows up under the `output` tab on the span
span.set_attribute(SpanAttributes.OUTPUT_VALUE, response_message.get("content", ""))
# This shows up under `output_messages` tab on the span page
# This code assumes a single response
span.set_attribute(
f"{SpanAttributes.LLM_OUTPUT_MESSAGES}.0.{MessageAttributes.MESSAGE_ROLE}",
response_message["role"],
)
span.set_attribute(
f"{SpanAttributes.LLM_OUTPUT_MESSAGES}.0.{MessageAttributes.MESSAGE_CONTENT}",
response_message.get("content", ""),
)
Last updated
Was this helpful?