Skip to main content

Lightweight span-based tracing for LangChain/LangGraph agents

Project description

 ██████╗ ████████╗██████╗  █████╗  ██████╗███████╗██████╗
██╔════╝ ╚══██╔══╝██╔══██╗██╔══██╗██╔════╝██╔════╝██╔══██╗
██║  ███╗   ██║   ██████╔╝███████║██║     █████╗  ██████╔╝
██║   ██║   ██║   ██╔══██╗██╔══██║██║     ██╔══╝  ██╔══██╗
╚██████╔╝   ██║   ██║  ██║██║  ██║╚██████╗███████╗██║  ██║
 ╚═════╝    ╚═╝   ╚═╝  ╚═╝╚═╝  ╚═╝ ╚═════╝╚══════╝╚═╝  ╚═╝

Lightweight span-based tracing for LangChain and LangGraph agents.

Emits structured JSONL spans via Python's standard logging — no new infrastructure, no agents, no dashboards required.

Python PyPI License: MIT LangChain LangGraph


What it does

Every time an LLM call happens inside your agent, gtracer captures it as a structured span and writes it to stdout as JSON:

run
└── agent "main"
    ├── llm_call seq:1  ← tokens, model, message delta, latency
    │   └── tool_call search_database  ← input, result, duration
    ├── llm_call seq:2
    │   └── tool_call calculator
    └── llm_call seq:3  ← final answer

Works with CloudWatch, Datadog, or any stdout log consumer. Zero configuration — spans are live the moment you import the package.


Install

pip install gtracer
# or
uv add gtracer

Quick Start

1. Import and go

import gtracer  # spans are live immediately — nothing else needed

gtracer auto-configures at import time. It attaches its own JSON handler with propagate=False — it never touches your app's root logger, no double-emission, no interference.

2. Wrap your agent

from gtracer import tracer, tracing_handler

async def run(session_id: str, user_input: str):
    tracer.start_trace(session_id)

    with tracer.span("run", tags={"session_id": session_id}):
        with tracer.span("agent", attrs={"agent": "main"}) as agent_span:
            result = await my_agent.ainvoke(
                {"messages": [{"role": "user", "content": user_input}]},
                config={"callbacks": [tracing_handler]},
            )
            agent_span.set("output_type", type(result).__name__)
            return result

Every LLM call is now automatically captured — tokens, model, latency, message deltas.

3. Instrument your tools

from langchain_core.tools import tool
from gtracer import tracer, tracing_handler, _span_id

@tool
async def search_database(query: str) -> str:
    """Run a database query."""
    llm_parent = tracing_handler.last_llm_span(_span_id.get())
    with tracer.span("tool_call",
                     attrs={"tool": "search_database", "input": {"query": query}},
                     parent_span_id=llm_parent) as span:
        result = await execute_query(query)
        span.set("result", result)
        return result

Silence in Production

Set the env var — no code change needed:

GTRACER_ENABLED=false

Tracing mechanics (spans, callbacks, token counts) stay fully active. Only stdout output is suppressed.


Span Schema

Every span event is a flat JSON object on a single line:

{
  "ts": "2026-03-30T10:00:00",
  "level": "TRACE",
  "event": "span.end",
  "span_name": "llm_call",
  "trace_id": "abc123",
  "span_id": "a1b2c3d4",
  "parent_span_id": "e5f6a7b8",
  "status": "ok",
  "duration_ms": 1823,
  "attrs": {
    "agent": "main",
    "model": "claude-sonnet-4-6",
    "seq": 2,
    "tokens": {
      "input": 461,
      "output": 277,
      "total": 738,
      "input_cache_read": 15541
    },
    "stop_reason": "tool_use"
  }
}

Each llm_call span captures:

Field Description
attrs.tokens input, output, total, cache_read, cache_creation
attrs.model exact model ID from the provider response
attrs.delta new messages added since the previous LLM call
duration_ms wall-clock latency in milliseconds
attrs.stop_reason tool_use, end_turn, etc.

Configuration

from gtracer import configure

configure(truncation_limit=50_000)  # max chars for message content fields (default)

Supported Patterns

Pattern Description
create_agent ReAct loop with tool use and structured output
StateGraph LangGraph graphs with custom nodes
Nested agents Agent-as-a-tool with causal span parenting
Deep Agents LangChain create_deep_agent with sub-agents
Parallel tools Concurrent tool calls under the same llm_call parent

See docs/documentation.md for full integration patterns, API reference, and gotchas.


Requirements

Python langchain-core

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

gtracer-0.1.3.tar.gz (11.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

gtracer-0.1.3-py3-none-any.whl (13.6 kB view details)

Uploaded Python 3

File details

Details for the file gtracer-0.1.3.tar.gz.

File metadata

  • Download URL: gtracer-0.1.3.tar.gz
  • Upload date:
  • Size: 11.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.28 {"installer":{"name":"uv","version":"0.9.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for gtracer-0.1.3.tar.gz
Algorithm Hash digest
SHA256 e53ce378894eb1964004210904d5acf82f6e15c6b025dc96bca374864716e6f1
MD5 43198847aef762093af38a127231c51a
BLAKE2b-256 ded5c2c31db398c425dc5d141afca4add1e767571bbb420413a6d36b36328e1a

See more details on using hashes here.

File details

Details for the file gtracer-0.1.3-py3-none-any.whl.

File metadata

  • Download URL: gtracer-0.1.3-py3-none-any.whl
  • Upload date:
  • Size: 13.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.28 {"installer":{"name":"uv","version":"0.9.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for gtracer-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 b90061389163f50074eae9654398584094d7cf63cdeeb6c4b186a5aa3c79b2b2
MD5 737e1260fadbb6fe7c71b4f06c7ecc9d
BLAKE2b-256 c06df96c68ab842640f41f7c8a8978bdd9606c50378f7efadfc2ca26e6fbf033

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page