How I Auto-Log Every Claude Code Session to Track My Own Learning
Building a self-logging system with Claude Code hooks, git-based session capture, and weekly digest generation — so I never lose context between sessions.
I work across multiple repos simultaneously — a data pipeline backend in Go/Rust, a React frontend, a personal site, side projects. By Thursday I’ve forgotten what I was debugging on Monday. By next week I’ve forgotten the architectural decision we made and why.
I built a system to fix this. It auto-logs every Claude Code session as it happens, appends it to a daily markdown file, and generates a weekly digest of concepts and patterns from the work. Here’s how it’s built.
The Core Problem
Context loss compounds in two ways:
Within a project: You spend 45 minutes debugging a weird ClickHouse replication issue, find the fix, move on. Next time the same issue surfaces you start from scratch because you didn’t write it down.
Across projects: You’re an EM touching multiple repos. The mental context for each one is different. Without a log, switching between them means re-orienting every time.
I tried explicit daily journals. They require discipline I don’t always have at end-of-day. I tried JIRA / Linear tickets. Too much ceremony for small learnings. What I wanted was a system that captures without requiring me to actively do the capturing.
The Architecture
Three moving parts:
1. Claude Code Hooks (Automatic Capture)
Claude Code supports hooks — shell commands that run on lifecycle events (session start, session stop, file edit, etc.). I configured a stop hook that fires whenever a session ends:
{
"hooks": {
"Stop": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "python3 /path/to/log_session.py"
}
]
}
]
}
}
The script runs automatically — I don’t have to remember to log.
2. The Session Logger (log_session.py)
The logger does three things:
- Gets the current repo context — runs
git status --shortandgit log --oneline -5to capture what was in-flight - Appends to a daily file — writes to
logs/sessions/YYYY-MM-DD.mdin a structured format - Stamps the timestamp — so you can see the rhythm of work across a day
import subprocess
import datetime
from pathlib import Path
def get_git_context():
try:
status = subprocess.run(
["git", "status", "--short"],
capture_output=True, text=True, cwd="."
).stdout.strip()
log = subprocess.run(
["git", "log", "--oneline", "-5"],
capture_output=True, text=True, cwd="."
).stdout.strip()
return status, log
except Exception:
return "", ""
def append_session_log(repo_name: str, status: str, commits: str):
today = datetime.date.today().isoformat()
log_dir = Path("logs/sessions")
log_dir.mkdir(parents=True, exist_ok=True)
log_file = log_dir / f"{today}.md"
timestamp = datetime.datetime.now().strftime("%H:%M")
entry = f"""
### {today} {timestamp} - Auto-logged session in {repo_name}
**Recent commits:**
{commits}
**Uncommitted changes:**
{status}
"""
with open(log_file, "a") as f:
if not log_file.exists() or log_file.stat().st_size == 0:
f.write(f"# Session Log - {today}\n\n")
f.write(entry)
The output is intentionally raw. I’m not trying to be clever about what gets logged — just capture the state.
3. The Weekly Digest (session_learning_report.py)
Once a week (via cron, 9 AM Monday), a report generator reads the last 7 days of session logs and produces a learning digest. It:
- Counts sessions per project
- Extracts concept mentions (SQL, Rust, ClickHouse, Solana, etc.)
- Flags questions phrased as learning opportunities (“why does X work this way”, “what’s the difference between Y and Z”)
- Outputs a ranked list of concepts to review
The output is a markdown file in docs/session-insights/ that I can skim in 2 minutes to remember what the week looked like.
A sample from a week in January:
| Concept | Mentions | Signal |
|--------------|----------|--------|
| solana | 12 | 🟡 Review |
| dbt | 11 | 🟡 Review |
| clickhouse | 9 | 🟢 Familiar |
| sql | 9 | 🟢 Familiar |
| rust | 9 | 🟢 Familiar |
The emoji signals are simple thresholds: seen once or twice is just noise, 5+ times means it’s worth a deliberate study session.
What I’ve Learned From the Logs
Running this for ~3 months now, a few observations:
I use Claude Code more than I think. A week I’d characterize as “light” often has 60–80 sessions across repos. High-output weeks hit 200+. It’s made me more intentional about what I’m asking versus just reaching for it as a reflex.
The uncommitted changes column is more valuable than the commit log. Commits represent resolved decisions. The uncommitted state captures what’s in-flight — which is where context loss actually hurts. Seeing ?? useTokenSearch.ts on a Monday means I know where I left off.
Learning gaps cluster. The same concepts show up on the review list week after week until I actually sit down and go deep. Solana’s account model was on my list for six weeks before I finally spent an afternoon reading through the docs properly.
The log is a forcing function for writing. Looking at a week of raw session logs and realizing “that ClickHouse work was genuinely interesting” is what prompted the pipeline post I wrote. The log makes invisible work visible.
The Setup
If you use Claude Code and want something similar:
- Add a
Stophook in your Claude settings pointing to a simple script - The script should capture
git status,git log --oneline -5, and the current directory/repo name - Append to a date-stamped markdown file
- Optional: add a weekly cron that aggregates across log files
The whole thing is ~100 lines of Python and a one-line JSON hook config. Low overhead, high return.
The goal isn’t perfect documentation. It’s just enough signal that Monday-you can orient quickly to where Friday-you left off.