summaryrefslogtreecommitdiffhomepage
path: root/bin
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-06-03 14:55:52 +0900
committerAdam Malczewski <[email protected]>2026-06-03 14:55:52 +0900
commitbcc449a5cba183c7358ab48ed4f2140bb1a3238c (patch)
tree60e8a686d5768ff76eab805faaec7a01ec352ff5 /bin
parent656aad2752991ff32e98fed270fa330355650c17 (diff)
downloaddispatch-bcc449a5cba183c7358ab48ed4f2140bb1a3238c.tar.gz
dispatch-bcc449a5cba183c7358ab48ed4f2140bb1a3238c.zip
chore(bin/up): DEBUG=1 writes LLM debug logs to /app/logging (host: logging/)
Add a DEBUG=1 convenience flag to bin/up that turns on full LLM debug logging (DISPATCH_DEBUG_LLM) plus the per-step usage/cache split (DISPATCH_DEBUG_USAGE) and routes the JSON request/response files into the container's /app/logging, which maps to the project-root logging/ dir on the host via the existing .:/app bind mount. This makes it easy to verify cache hits (including the prompt-cache warming replay) without docker exec. - bin/up: DEBUG=1 sets DISPATCH_DEBUG_LLM/_USAGE=1 and DISPATCH_DEBUG_LLM_DIR= /app/logging as DEFAULTS (explicit DISPATCH_DEBUG_* still win). Pre-creates the host log dir; /app/* targets are already host-owned so no sudo chown, while the /tmp fallback keeps its ownership fix. - docker-compose.yml: forward DISPATCH_DEBUG_LLM_DIR into the api container. - .gitignore: ignore logging/.
Diffstat (limited to 'bin')
-rwxr-xr-xbin/up69
1 files changed, 52 insertions, 17 deletions
diff --git a/bin/up b/bin/up
index 6f9c3ed..a47135c 100755
--- a/bin/up
+++ b/bin/up
@@ -9,35 +9,70 @@ export HOST_UID="$(id -u)"
export HOST_GID="$(id -g)"
export HOST_USER="$(whoami)"
+# --- DEBUG=1 convenience flag ------------------------------------
+# `DEBUG=1 bin/up` turns on full LLM debug logging (request/response
+# bodies) AND the per-step usage split (cache read/write tokens), and
+# routes the JSON log files into `logging/` at the project root. That
+# directory is mounted into the container at /app/logging via the
+# `.:/app` bind, so the files land on the host where you can
+# `tail -F logging/*.json` without `docker exec`. `logging/` is
+# gitignored.
+#
+# It only sets DEFAULTS -- any DISPATCH_DEBUG_* var you set explicitly
+# still wins, so fine-grained control (e.g. a custom verbosity or a
+# different log dir) is preserved.
+if [ -n "${DEBUG:-}" ] && [ "$DEBUG" != "0" ]; then
+ : "${DISPATCH_DEBUG_LLM:=1}"
+ : "${DISPATCH_DEBUG_USAGE:=1}"
+ : "${DISPATCH_DEBUG_LLM_DIR:=/app/logging}"
+fi
+
# Debug-logger pass-through. docker-compose only forwards env vars that are
# (a) set in the parent shell AND (b) referenced in docker-compose.yml's
-# `environment:` block — so without this `export` step the variables would
+# `environment:` block -- so without this `export` step the variables would
# be invisible to the container even when the user prefixes the command with
# DISPATCH_DEBUG_LLM=1. We re-export here (rather than relying on the shell's
-# inline `VAR=… cmd` syntax) so it works whether the user sets them inline,
+# inline `VAR=... cmd` syntax) so it works whether the user sets them inline,
# in their shell rc, or via `.env`.
#
-# All variables default to empty — when unset, the logger short-circuits and
+# All variables default to empty -- when unset, the logger short-circuits and
# does nothing.
export DISPATCH_DEBUG_LLM="${DISPATCH_DEBUG_LLM:-}"
export DISPATCH_DEBUG_LLM_VERBOSITY="${DISPATCH_DEBUG_LLM_VERBOSITY:-}"
export DISPATCH_DEBUG_USAGE="${DISPATCH_DEBUG_USAGE:-}"
+# Container-side log directory. Empty => the logger uses its built-in default
+# (/tmp/dispatch/llm-debug). DEBUG=1 sets it to /app/logging (see above).
+export DISPATCH_DEBUG_LLM_DIR="${DISPATCH_DEBUG_LLM_DIR:-}"
-# Pre-create the LLM debug log directory owned by the host user. Without
-# this, docker auto-creates the bind-mount source as root on first start,
-# and the container's bun process (running as host UID) then gets EACCES
-# on every log write — silent except for `[dispatch-debug] Failed to
-# write ...: EACCES` lines drowned in stderr.
+# Pre-create the debug log directory owned by the host user. Without this,
+# docker auto-creates the bind-mount source as root on first start, and the
+# container's bun process (running as host UID) then gets EACCES on every log
+# write -- silent except for `[dispatch-debug] Failed to write ...: EACCES`
+# lines drowned in stderr.
#
-# If the directory already exists and is NOT owned by us (likely from a
-# prior root-mkdir by docker), fix it with sudo. This prompts once and
-# then never again — files we write afterwards are owned correctly.
-LOG_DIR=/tmp/dispatch/llm-debug
-mkdir -p "$LOG_DIR" 2>/dev/null || true
-if [ ! -O "$LOG_DIR" ]; then
- current_owner=$(stat -c '%U' "$LOG_DIR" 2>/dev/null || echo "unknown")
- echo "bin/up: $LOG_DIR is owned by '$current_owner', fixing ownership to '$HOST_USER'..."
- sudo chown -R "$HOST_UID:$HOST_GID" "$LOG_DIR"
+# The host path depends on which container dir the logger targets:
+# - /app/<sub> -> the project bind-mount, host path $PROJECT_DIR/<sub>
+# (already host-owned; a plain mkdir is enough).
+# - otherwise -> the dedicated /tmp/dispatch/llm-debug volume; may have
+# been root-created by a prior run, so fix ownership.
+case "${DISPATCH_DEBUG_LLM_DIR}" in
+ /app/*)
+ HOST_LOG_DIR="$PROJECT_DIR/${DISPATCH_DEBUG_LLM_DIR#/app/}"
+ mkdir -p "$HOST_LOG_DIR" 2>/dev/null || true
+ ;;
+ *)
+ HOST_LOG_DIR=/tmp/dispatch/llm-debug
+ mkdir -p "$HOST_LOG_DIR" 2>/dev/null || true
+ if [ ! -O "$HOST_LOG_DIR" ]; then
+ current_owner=$(stat -c '%U' "$HOST_LOG_DIR" 2>/dev/null || echo "unknown")
+ echo "bin/up: $HOST_LOG_DIR is owned by '$current_owner', fixing ownership to '$HOST_USER'..."
+ sudo chown -R "$HOST_UID:$HOST_GID" "$HOST_LOG_DIR"
+ fi
+ ;;
+esac
+
+if [ -n "${DISPATCH_DEBUG_LLM}" ]; then
+ echo "bin/up: debug logging ON -> ${DISPATCH_DEBUG_LLM_DIR:-/tmp/dispatch/llm-debug} (host: $HOST_LOG_DIR)"
fi
# Start all services