Set Session ID and User ID
Adding SessionID and UserID as attributes to Spans for Tracing
About
Traces are isolated by default. Without a session or user identifier, there is no way to connect multiple traces that belong to the same conversation or the same end user. Setting session.id and user.id on spans links them together so traces can be grouped by conversation and filtered by user in the dashboard. Both values are added to the OpenTelemetry context and automatically picked up by traceAI auto-instrumentors as span attributes.
When to use
- Conversation debugging: Group traces by session ID to view the full message history for a single conversation and find where it breaks.
- User-level analysis: Filter spans by user ID to identify which users have the best or worst experiences.
- Session and user metrics: Aggregate evaluation results by
session.idoruser.idto compare performance across sessions and users.
How to
Install packages
Install the required package to use using_attributes with an LLM client.
pip install traceAI-openainpm install @opentelemetry/api # or yarn add @opentelemetry/api
# Assuming your traceAI or equivalent auto-instrumentation package is already installed. Set session ID and user ID
Choose your approach:using_session, using_user, or using_attributes.
Add a session ID to the current OpenTelemetry context. Any LLM call within the block will include session.id as a span attribute. The session ID must be a non-empty string.
from fi_instrumentation import using_session
with using_session(session_id="my-session-id"):
# Calls within this block will generate spans with the attributes:
# "session.id" = "my-session-id"
...import { context, propagation } from "@opentelemetry/api";
const sessionId = "my-js-session-id"; // Example session ID
const activeContext = context.active();
const baggageWithSession = propagation.createBaggage({
"session.id": { value: sessionId }
});
const newContext = propagation.setBaggage(activeContext, baggageWithSession);
context.with(newContext, () => {
// Calls within this block by auto-instrumented libraries (like traceAI)
// should generate spans with the attribute: "session.id" = "my-js-session-id"
// e.g., myInstrumentedFunction();
}); @using_session(session_id="my-session-id")
def call_fn(*args, **kwargs):
# Calls within this function will generate spans with the attributes:
# "session.id" = "my-session-id"
... Add a user ID to the current OpenTelemetry context. Any LLM call within the block will include user.id as a span attribute. The user ID must be a non-empty string.
from fi_instrumentation import using_user
with using_user("my-user-id"):
# Calls within this block will generate spans with the attributes:
# "user.id" = "my-user-id"
...import { context, propagation } from "@opentelemetry/api";
const userId = "my-js-user-id"; // Example user ID
const activeContext = context.active();
const baggageWithUser = propagation.createBaggage({
"user.id": { value: userId }
});
const newContext = propagation.setBaggage(activeContext, baggageWithUser);
context.with(newContext, () => {
// Calls within this block by auto-instrumented libraries (like traceAI)
// should generate spans with the attribute: "user.id" = "my-js-user-id"
// e.g., myInstrumentedFunction();
}); @using_user("my-user-id")
def call_fn(*args, **kwargs):
# Calls within this function will generate spans with the attributes:
# "user.id" = "my-user-id"
... Use using_attributes to set session ID, user ID, or both in a single call alongside an LLM client.
Defining a Session:
import openai
from fi_instrumentation import using_attributes
client = openai.OpenAI()
# Defining a Session
with using_attributes(session_id="my-session-id"):
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": "Write a haiku."}],
max_tokens=20,
)import { context, propagation } from "@opentelemetry/api";
// Assume 'openai' client or equivalent is initialized and used here.
// import OpenAI from 'openai';
// const client = new OpenAI();
const sessionId = "my-js-session-id";
const activeContext = context.active();
const baggageWithSession = propagation.createBaggage({
"session.id": { value: sessionId }
});
const newContext = propagation.setBaggage(activeContext, baggageWithSession);
context.with(newContext, () => {
// Example LLM call that would pick up the session.id from context
// response = client.chat.completions.create(
// model="gpt-3.5-turbo",
// messages=[{"role": "user", "content": "Write a haiku in JavaScript context."}],
// max_tokens=20,
// );
console.log('In context with session.id set via Baggage');
}); Defining a User:
# Ensure 'client' and 'using_attributes' are imported as in the previous Python example.
with using_attributes(user_id="my-user-id"):
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": "Write a haiku."}],
max_tokens=20,
)import { context, propagation } from "@opentelemetry/api";
// Assume 'client' (e.g., OpenAI client) is initialized and used here.
const userId = "my-js-user-id";
const activeContext = context.active();
const baggageWithUser = propagation.createBaggage({
"user.id": { value: userId }
});
const newContext = propagation.setBaggage(activeContext, baggageWithUser);
context.with(newContext, () => {
// Example LLM call that would pick up the user.id from context
// response = client.chat.completions.create(...);
console.log('In context with user.id set via Baggage');
}); Defining a Session AND a User:
# Ensure 'client' and 'using_attributes' are imported as in the previous Python example.
with using_attributes(
session_id="my-session-id",
user_id="my-user-id",
):
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": "Write a haiku."}],
max_tokens=20,
)import { context, propagation } from "@opentelemetry/api";
// Assume 'client' (e.g., OpenAI client) is initialized and used here.
const sessionId = "my-js-session-id";
const userId = "my-js-user-id";
const activeContext = context.active();
const baggageWithBoth = propagation.createBaggage({
"session.id": { value: sessionId },
"user.id": { value: userId }
});
const newContext = propagation.setBaggage(activeContext, baggageWithBoth);
context.with(newContext, () => {
// Example LLM call that would pick up both session.id and user.id from context
// response = client.chat.completions.create(...);
console.log('In context with session.id and user.id set via Baggage');
}); from fi_instrumentation import using_attributes
client = openai.OpenAI()
# Defining a Session
@using_attributes(session_id="my-session-id")
def call_fn(client, *args, **kwargs):
return client.chat.completions.create(*args, **kwargs)
# Defining a User
@using_attributes(user_id="my-user-id")
def call_fn(client, *args, **kwargs):
return client.chat.completions.create(*args, **kwargs)
# Defining a Session AND a User
@using_attributes(
session_id="my-session-id",
user_id="my-user-id",
)
def call_fn(client, *args, **kwargs):
return client.chat.completions.create(*args, **kwargs)
Key concepts
using_session:Context manager that addssession.idto the OpenTelemetry context. All spans from traceAI auto-instrumentors within the block will carry this attribute. Input must be a non-empty string.using_user:Context manager that addsuser.idto the OpenTelemetry context. All spans within the block will carry this attribute. Input must be a non-empty string.using_attributes:General-purpose context manager that accepts bothsession_idanduser_id(and other attributes). Useful when setting multiple context attributes in one call.- Baggage (JS/TS):The JS/TS equivalent of Python context managers. Use
propagation.createBaggage()andcontext.with()to propagate session and user IDs to child spans.
Next Steps
Set Up Tracing
Register a tracer provider and add instrumentation.
Add Attributes & Metadata
Attach custom data to spans for filtering and evals.
Instrument with traceAI Helpers
Use FITracer decorators and context managers for typed spans.
Mask Span Attributes
Redact sensitive data with TraceConfig before export.