claude-code
claude-code copied to clipboard
feature request: ability to log/trace the full llm span (query and response)
as far as i can tell from spending half a day trying to figure this out, OTEL_LOG_USER_PROMPTS will log the prompt, but there is no way to log the response from claude.
is this true?
this seems crazy to me, is there a reason why everything but the response itself can be logged with otel? i don't see why it would be a privacy/security issue, since the response is returned to the user.
maybe there is something i'm missing, why is this a "privacy issue"?
playing around with this a little bit more, what i would specifically like to request is a OTEL_LOG_API_RESPONSES variable, which would default to false just like OTEL_LOG_USER_PROMPTS. (feel free to name differently)
functionally, this would contain the claude api responses in the same OTEL system as all of the other OTEL logs.
as a user, i can access all of the information separately (for example, see my workaround below) - so again i don't really understand why including the responses in the OTEL logging presents a user privacy or security issue.
for others who might also be frustrated by this limitation, right now i'm basically doing a workaround by combining the claude -p output with console otel logs.
unfortunately this becomes extremely messy if you want to try the interactive REPL (not -p ), so my workaround is probably not immediately relevant to the average user.
i make a script like this, then run it with ./script "my prompt"
#!/usr/bin/env zsh
set -euo pipefail
# ─────────────────────────────────────────────────────────────────────────────
# 1) Optional: Check for API key
# ─────────────────────────────────────────────────────────────────────────────
# if [[ -z "${ANTHROPIC_API_KEY:-}" ]]; then
# echo "ERROR: Please export ANTHROPIC_API_KEY before running." >&2
# exit 1
# fi
# ─────────────────────────────────────────────────────────────────────────────
# 2) Collect prompt
# ─────────────────────────────────────────────────────────────────────────────
if (( $# == 0 )); then
echo "Usage: $0 \"Your coding prompt…\"" >&2
exit 1
fi
PROMPT="$*"
# ─────────────────────────────────────────────────────────────────────────────
# 3) Prepare logging
# ─────────────────────────────────────────────────────────────────────────────
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
SESSION_ID=$(uuidgen)
LOG_DIR="${LOG_DIR:-$PWD/claude_logs}"
mkdir -p "$LOG_DIR"
JSON_LOG="${LOG_DIR}/${SESSION_ID}_${TIMESTAMP}.jsonl"
# ─────────────────────────────────────────────────────────────────────────────
# 4) Enable OpenTelemetry (metrics+events) [oai_citation:0‡docs.anthropic.com](https://docs.anthropic.com/en/docs/claude-code/monitoring-usage)
# ─────────────────────────────────────────────────────────────────────────────
export CLAUDE_CODE_ENABLE_TELEMETRY=1
export OTEL_METRICS_EXPORTER=console # prints metrics to console
export OTEL_LOGS_EXPORTER=console # print events to console
export OTEL_LOG_USER_PROMPTS=1 # include prompt text in events
export OTEL_METRIC_EXPORT_INTERVAL=10000 # 10s for faster debug
export OTEL_LOGS_EXPORT_INTERVAL=1000 # 1s for faster event flush
export OTEL_METRICS_INCLUDE_VERSION=1
# ─────────────────────────────────────────────────────────────────────────────
# 5) Run Claude Code in non-interactive “print” mode,
# with verbose, structured JSON output, and limited turns [oai_citation:1‡docs.anthropic.com](https://docs.anthropic.com/en/docs/claude-code/cli-reference)
# ─────────────────────────────────────────────────────────────────────────────
claude -p \
--max-turns 5 \
--output-format stream-json \
--verbose \
"${PROMPT}" \
>"$JSON_LOG"
echo "✅ Logged JSON events to $JSON_LOG"
additional breadcrumbs for users in interactive mode: most of what you would want to trace is already being stored in ~/.claude/projects/[project]/[hash].jsonl.
again re: claude's statement that this is a "privacy" issue, the logs are already on my machine and saved by default. it just seems annoying to have to write a script to put this into an observability tool, and potentially manually merge this information with the current OTEL implementation.
Yeah. My OpenTelemetry collector received the logs but it's completely useless:
{
"cache_creation_tokens": "1171",
"cache_read_tokens": "13929",
"cost_usd": "0.011956950000000001",
"duration_ms": "11145",
"event.timestamp": "2025-07-25T11:05:28.952Z",
"input_tokens": "4",
"model": "claude-sonnet-4-20250514",
"output_tokens": "225",
"session.id": "<REDACTED>",
"terminal.type": "zed",
"user.id": "<REDACTED>"
}
With fields like cost_usd and output_tokens, the log is definitely reported at response phase, yet it omits the actual response. What's the point!?
+1 - any update on this?
i've been using this: https://github.com/badlogic/lemmy/tree/main/apps/claude-trace