Skip to main content

Trace Claude Code with Langfuse

还没翻译译自英文(langfuse.com)本页 62 段都还没译

Claude Code Tracing with Langfuse

YouTube video player: https://www.youtube-nocookie.com/embed/fsoBHf_WNmQ?si=XFUGjR6dE84oj2Ga

What is Claude Code?: Claude Code is Anthropic's agentic coding tool that lives in your terminal. It can understand your codebase, help you write and edit code, execute commands, create and run tests, and help you accomplish complex coding tasks with natural language. Claude Code brings the power of Claude's AI capabilities directly into your development workflow.

What is Langfuse?: Langfuse is an open-source AI engineering platform. It helps teams trace LLM applications, debug issues, evaluate quality, and monitor costs in production. Use Langfuse Cloud (hosted by Langfuse, free tier, no infrastructure to run) or self-host it.

NEW: Install via the Claude Code plugin marketplace

The easiest way to set this up is now the Langfuse Observability Plugin. Run these two commands and restart Claude Code:

claude plugin marketplace add langfuse/Claude-Observability-Plugin
claude plugin install langfuse-observability@langfuse-observability

On enable, you'll be prompted for your LANGFUSE_PUBLIC_KEY, LANGFUSE_SECRET_KEY, and LANGFUSE_BASE_URL. Your secret key is stored in your OS keychain. Requires Python 3.9+ and pip install "langfuse>=4.0,<5".

For AI-assisted or manual setup, see the steps below.

What Can This Integration Trace?

By using Claude Code's hooks system, this integration captures full conversation interactions and sends them to Langfuse. You can monitor:

  • User inputs: Capture every prompt and message you send to Claude Code
  • Assistant responses: Track Claude's responses and reasoning
  • Tool invocations: See when Claude Code uses tools like file editing, bash commands, or web searches
  • Tool inputs and outputs: Inspect data passed to and returned from each tool
  • Session information: Group related interactions into logical sessions
  • Timing information: Understand how long operations take

Claude Code is one of several agents Langfuse traces; our guide to tracing coding agents covers Codex, Copilot, Cursor, and team-level rollout patterns.

How It Works

Claude Code provides a hooks system that allows you to run custom scripts at different lifecycle points. This integration uses the Stop hook, which runs after each Claude Code response.

  1. A global "Stop" hook is configured to run each time Claude Code responds
  2. The hook reads Claude Code's generated conversation transcripts
  3. Messages are converted into Langfuse traces and sent to your Langfuse project
  4. All turns from the same session are grouped using a shared session_id

Tracing is opt-in per project using environment variables in your project's .claude/settings.json.

Quick Start

Note

Easiest path: have Claude Code set this up for you. Open a Claude Code session in any project and paste in the URL to this page along with the instruction "Implement this integration." Claude will read the page, create the hook script, and register it in your settings. You still need to add your API keys yourself (covered in the Enable Tracing Per-Project step below) — those should never be generated by an LLM. If you prefer to install everything by hand, follow the steps below.

Set up Langfuse

  1. Sign up for Langfuse Cloud or self-host Langfuse.
  2. Create a new project and copy your API keys from the project settings.

Install Dependencies

Install the Langfuse Python SDK:

pip install "langfuse>=4.0,<5"

Note

The hook script reaches into Langfuse SDK 4.x internals (_otel_tracer, _create_observation_from_otel_span) to backdate observations to historical timestamps. These attributes are implementation details — pinning the SDK to >=4.0,<5 prevents a future minor-version rename from silently breaking the hook. If you want to upgrade past 4.x, update the script first.

Create the Hook Script

Create the hook script at ~/.claude/hooks/langfuse_hook.py:

mkdir -p ~/.claude/hooks

Note

On macOS, the .claude directory is hidden by default. Press Cmd + Shift + . in Finder to show hidden folders if you want to browse it in the GUI.

View full langfuse_hook.py script

Register the Hook

Open your existing global Claude Code settings file at ~/.claude/settings.json (Claude Code creates this on first run) and add a Stop hook entry. If the file already has a hooks block, merge the Stop array into it rather than overwriting:

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "python3 ~/.claude/hooks/langfuse_hook.py"
          }
        ]
      }
    ]
  }
}

This registers the hook globally so it runs for all Claude Code sessions.

Enable Tracing Per-Project

Add your Langfuse credentials to Claude Code's per-project settings file at .claude/settings.json in the project root. Make sure this file is listed in your project's .gitignore so your secret keys aren't committed. Add an env block:

{
  "env": {
    "TRACE_TO_LANGFUSE": "true",
    "LANGFUSE_PUBLIC_KEY": "pk-lf-...",
    "LANGFUSE_SECRET_KEY": "sk-lf-...",
    "LANGFUSE_BASE_URL": "https://cloud.langfuse.com"
  }
}

Note

Tracing is opt-in per project. The hook runs globally but immediately exits if TRACE_TO_LANGFUSE is not set to "true" for that project.

Environment Variables:

VariableDescriptionRequired
TRACE_TO_LANGFUSESet to "true" to enable tracingYes
LANGFUSE_PUBLIC_KEYYour Langfuse public keyYes
LANGFUSE_SECRET_KEYYour Langfuse secret keyYes
LANGFUSE_BASE_URLLangfuse base URL. EU: https://cloud.langfuse.com, US: https://us.cloud.langfuse.com, Japan: https://jp.cloud.langfuse.com, HIPAA: https://hipaa.cloud.langfuse.comNo (defaults to EU)
CC_LANGFUSE_DEBUGSet to "true" for verbose debug loggingNo

Start Using Claude Code

Now when you use Claude Code in a project with tracing enabled, conversations will be sent to Langfuse:

cd your-project
claude

View Traces in Langfuse

Open your Langfuse project to see the captured traces. The structure mirrors how Claude Code actually works:

  • Turn trace (Claude Code - Turn N): One trace per conversation turn — from your prompt to the final assistant response.
  • Generation spans (Claude Generation 1, Claude Generation 2, …): One per assistant message in the turn. Each generation has the input it received (your prompt, or the previous batch of tool results), the text response, and any tool calls the LLM decided to make.
  • Tool spans (Tool: Read, Tool: Bash, …): Nested under the generation that triggered them. Each shows the tool input, the output, and how long it took.
  • Session grouping: All turns from the same Claude Code session are grouped via session_id — open the Sessions tab to see the full run.

What to look for

The trace view turns Claude Code from a black box into a diagnostic surface. Common things worth scanning for:

  • Claude reading the same file multiple times across a session → add a CLAUDE.md to the project root so it has the context up front.
  • Repeat tool calls with near-identical inputs (same web search, same grep) → tighten the prompt or success criteria.
  • Long stretches of file reads before any code is written → the task may be underspecified.

Troubleshooting

No traces appearing in Langfuse

Most issues come down to one of four things:

  1. The hook isn't firing. Tail the log:
tail -f ~/.claude/state/langfuse_hook.log

If the file is empty after a Claude Code session, one possibility is that the hook isn't registered — re-check ~/.claude/settings.json and make sure the Stop hook entry is present. With the default (non-debug) log level, an empty file is also consistent with the hook running but exiting early (e.g. TRACE_TO_LANGFUSE unset, missing keys, or Langfuse init failure), so if the Stop hook is present, jump to step 3 to enable debug logging.

  1. TRACE_TO_LANGFUSE isn't the exact string "true". In .claude/settings.json it must be the JSON string "true" (lowercase, quoted), not a boolean and not "True". The hook checks for this exact value and exits silently otherwise. Also verify the public key starts with pk-lf-.

  2. Enable debug mode for verbose logs. This is usually the fastest way to find the actual cause:

{
  "env": {
    "CC_LANGFUSE_DEBUG": "true"
  }
}
  1. Wrong Python, wrong directory, or missing SDK. Confirm python3 resolves to a recent Python (3.9+), that pip show langfuse returns a result for that interpreter, and that you ran claude from inside the project directory whose .claude/settings.json has the env vars set.

Permission errors

Make sure the hook script is executable:

chmod +x ~/.claude/hooks/langfuse_hook.py

Hook script errors

Test the script manually to check for errors:

TRACE_TO_LANGFUSE=true \
LANGFUSE_PUBLIC_KEY="pk-lf-..." \
LANGFUSE_SECRET_KEY="sk-lf-..." \
python3 ~/.claude/hooks/langfuse_hook.py

Check the log file for errors:

cat ~/.claude/state/langfuse_hook.log

Langfuse SDK version mismatch

The hook script targets Langfuse Python SDK 4.x and uses internal attributes (_otel_tracer, _create_observation_from_otel_span) to backdate observations to historical timestamps. If ~/.claude/state/langfuse_hook.log shows:

emit_turn failed: RuntimeError: Langfuse SDK X.Y.Z is missing _otel_tracer ...

reinstall a compatible version:

pip install "langfuse>=4.0,<5"

If you intentionally upgraded past 4.x, you will need to update _start_backdated in the hook script to match the new SDK surface.

Authentication errors

Verify your Langfuse API keys are correct and the base URL matches your region:

  • EU region: https://cloud.langfuse.com
  • US region: https://us.cloud.langfuse.com
  • Japan region: https://jp.cloud.langfuse.com
  • HIPAA region: https://hipaa.cloud.langfuse.com

Resources