Skip to main content
Distributed tracing links LLM calls, tool invocations, and custom spans across services so every hop appears in one HoneyHive session for end-to-end debugging. Use session ID passing for simple setups or W3C context propagation when you need parent-child spans across services. Review tracing concepts for sessions and context, and tracer initialization for per-request session patterns in web servers and Lambda.

Which distributed tracing approach should you use?

HoneyHive supports two approaches. Pick the one that fits your needs.
Pass the session ID between services so all events land in the same session. Events are grouped together but appear as siblings, not as parent-child.Best for: Simple architectures, serverless (Lambda), cases where you only need events in the same session.
1

Get the session ID from Service A

from honeyhive import HoneyHiveTracer
import os

tracer = HoneyHiveTracer.init(api_key=os.getenv("HH_API_KEY"))

session_id = tracer.session_id
2

Pass the session ID to Service B

Include it in your HTTP request headers or body:
import requests

response = requests.post(
    "https://service-b.example.com/api/endpoint",
    json={"query": "hello", "session_id": session_id},
)
3

Initialize the tracer with the session ID in Service B

from honeyhive import HoneyHiveTracer
import os

# Extract session_id from request (Flask example)
session_id = request.json.get("session_id")

tracer = HoneyHiveTracer.init(
    api_key=os.getenv("HH_API_KEY"),
    session_id=session_id,  # Links to Service A's trace
)

What helper functions are available?

enrich_span_context()

A context manager that creates a span enriched with HoneyHive-specific fields. Use it on the client side to wrap outgoing calls so the span carries inputs, outputs, and metadata.
ParameterTypeDescription
event_namestr(required) Name for the span.
inputsdictInput data recorded on the span.
outputsdictOutput data recorded on the span.
metadatadictArbitrary metadata attached to the span.
metricsdictNumeric metrics (latency, token counts, etc.).
configdictConfiguration snapshot for this span.
user_propertiesdictEnd-user properties for the request.
errorstrError message if the operation failed.
feedbackdictFeedback signals (e.g., ratings).

inject_context_into_carrier()

Injects W3C traceparent, session ID, and project into an outgoing headers dict so the remote service can continue the trace.
ParameterTypeDescription
headersdictHTTP headers dict to inject context into.
tracerHoneyHiveTracerThe active tracer instance.

with_distributed_trace_context()

A context manager used on the server side to extract incoming trace context and attach all child spans to the caller’s trace.
ParameterTypeDescription
headersdictIncoming HTTP request headers.
tracerHoneyHiveTracerThe active tracer instance on the server.

How do you trace across serverless boundaries?

For Lambda functions, call tracer.flush() before the handler returns to ensure all spans are exported before the runtime freezes. Use the session ID approach to link Lambda invocations to the calling service.
from honeyhive import HoneyHiveTracer
import os

def handler(event, context):
    session_id = event.get("session_id")

    tracer = HoneyHiveTracer.init(
        api_key=os.getenv("HH_API_KEY"),
        session_id=session_id,
    )

    result = process_event(event)
    tracer.flush()  # Drain pending spans before Lambda freezes
    return {"statusCode": 200, "body": result}
Use the x86_64 runtime architecture and install the matching binary:
pip install \
    --platform manylinux2014_x86_64 \
    --target ./site-packages \
    --implementation cp \
    --python-version 3.11 \
    --only-binary=:all: \
    --upgrade honeyhive

Where should you go next?

Tracing Introduction

Sessions, events, and context propagation concepts

Distributed Tracing Tutorial

End-to-end walkthrough with Google ADK