Log Traces

Traces give you instant visibility into what's working, what's not, and why. Includes advanced analysis and debugging features.

Overview

A trace represents a single execution of your AI workflow. Each trace contains:

  • Spans - Individual operations (LLM calls, tools, etc.)
  • Metadata - Custom attributes you attach
  • Metrics - Latency, tokens, cost
  • Status - Success, error, or running

Basic Usage

Using the Decorator

The simplest way to log traces is with the @instrument decorator:

agent.py
from turingpulse_sdk import instrument

@instrument(name="customer-support-agent")
def handle_support_request(query: str, user_id: str):
    response = agent.run(query)
    return response

result = handle_support_request("How do I reset my password?", "user-123")

With Full Options

agent.py
from turingpulse_sdk import instrument

@instrument(
    name="customer-support-agent",
    operation="handle_request",
    labels={"team": "support", "channel": "web"},
    metadata={"version": "1.2.3"},
)
def handle_support_request(query: str, user_id: str):
    response = agent.run(query)
    return response

Span Types

When using framework integrations (LangGraph, LangChain, OpenAI, etc.), spans are created automatically with the correct type. The SDK captures the full hierarchy of your workflow.

TypeUse Case
llmLLM API calls
toolTool/function invocations
retrievalVector search, RAG
agentAgent decision steps
chainChain executions
customAny other operation

Adding Metadata

Attach custom metadata to traces using the @instrument decorator:

agent.py
from turingpulse_sdk import instrument

@instrument(
    name="support-agent",
    metadata={"environment": "production", "version": "1.2.3"},
    labels={"priority": "high", "department": "billing"},
)
def handle_request(request):
    return process(request)
💡
Searchable Metadata
Labels are indexed and searchable in the dashboard. Use consistent keys across traces for effective filtering.

Capturing Inputs & Outputs

Control what gets captured in your traces:

config.py
from turingpulse_sdk import init, TuringPulseConfig

init(TuringPulseConfig(
    api_key="sk_live_...",
    workflow_name="my-agent",
    capture_arguments=True,     # Log function arguments
    capture_return_value=True,  # Log return values
    redact_fields=["password", "api_key", "secret"],  # Auto-redact sensitive fields
))

Error Handling

Errors are automatically captured and attached to traces:

error_handling.py
from turingpulse_sdk import instrument

@instrument(name="my-agent")
def risky_operation():
    try:
        result = external_api.call()
        return result
    except APIError:
        raise
ℹ️
Automatic Error Capture
The SDK automatically captures exceptions with full stack traces and sets the trace status to error. You do not need to manually record errors.

Async Support

TuringPulse fully supports async/await:

async_agent.py
from turingpulse_sdk import instrument

@instrument(name="async-agent")
async def async_agent(query: str):
    docs = await vector_store.asearch(query)
    response = await llm.achat(messages=[
        {"role": "user", "content": f"Context: {docs}\nQuestion: {query}"}
    ])
    return response

import asyncio
result = asyncio.run(async_agent("What is the weather?"))

Framework Integrations

For supported frameworks, tracing is automatic:

LangGraph

langgraph_example.py
from turingpulse_sdk_langgraph import instrument_langgraph

instrumented = instrument_langgraph(
    compiled_graph,
    name="langgraph-agent",
)

result = instrumented({"messages": [...]})

LangChain

langchain_example.py
from turingpulse_sdk_langchain import instrument_langchain

instrumented = instrument_langchain(
    chain,
    name="langchain-agent",
)

result = instrumented.invoke({"input": "Hello"})

See the SDK Integration guides for more details.

Best Practices

  • Use consistent agent IDs - Same ID across environments for easy comparison
  • Add meaningful labels - User IDs, request types, and versions help with debugging and filtering
  • Use framework integrations - Auto-instrumentation captures spans without manual code changes
  • Handle sensitive data - Use redact_fields to automatically strip sensitive values from telemetry

Next Steps