Skip to main content

Save logs of claude code, and convert them into HTML

Project description

Claude Logging

Automatically keep logs of "claude code" sessions, and convert them to HTML.

Features

  • Automatically log claude sessions in ~/.claude/logs
  • Convert logged session into HTML files
  • Strips control characters and preserves text formatting
  • Converts terminal output to styled HTML
  • Supports syntax highlighting, bold text, and colors
  • Includes line numbering and theme toggling in the HTML output

NOTE: this tool has largely been written by claude itself. The quality of the code is a direct consequence of it.

Installation

The easiest way is to run it without need of installation through uxv:

uvx claude-logging

This will start a normal claude session, but will record the log in ~/.claude/logs.

For automatic logging of every invocation of claude, you can put an alias in your ~/.bashrc or equivalent:

alias claude="uxv claude-logging"

If you prefer a more classical installation method, you can use pip:

pip install claude-logging

Usage

Default Mode: Record Claude Sessions

When you run the command claude-logging, it will:

  1. Create a log directory at ~/.claude/logs/ if it doesn't exist
  2. Generate a unique log filename based on your current directory and timestamp
  3. Run the claude command with all provided arguments
  4. Record the entire session to the log file

All the arguments are directly passed to the underyling claude program.

HTML Conversion Mode

Convert existing log files to HTML:

# Convert a log file to HTML
claude-logging dump ~/.claude/logs/my.log

# Bulk convert multiple files
claude-logging dump ~/.claude/logs/my*.log

# Output to a specific file
claude-logging dump ~/.claude/logs/my.log -o my.html

# Use stdin/stdout
cat logfile.log | claude-logging dump - > output.html

Example logs

These are some of the sessions in which I used claude to write claude-logging:

You can click on a line or shift-click on a range of lines to generate a permalink to a specific part of the log. For example, this is when I asked claude not to build windows wheels.

How it works

Unfortunately claude doesn't seem to offer a way to get a structured log of the conversation, so the only possible way is to get a dump of the terminal.

This is doable using the script program in linux, which records all characters sent to a TTY:

script --flush --quiet --return --command "claude $*" "$LOG_FILE"

However, the resulting file is not directly usable, because claude is a rich terminal application and it constantly redraws parts of the screen. The raw log includes all characters ever sent to the TTY, including the ones which are responsible to erase one or more lines, and the ones which are responsible to redraw.

For example, for each key pressed by the user, claude erases and redraws the whole input box. If you inspect a raw log files using less -R you can see it clearly. This is part of the log generated by typing hello in the input box:

╭──────────────────────────────────────────────────────────────────────────────╮
│ >                                                                            │
╰──────────────────────────────────────────────────────────────────────────────╯
  ! for bash mode · / for commands                              \⏎ for newline



╭──────────────────────────────────────────────────────────────────────────────╮
│ > Try "how do I log an error?"                                               │
╰──────────────────────────────────────────────────────────────────────────────╯
  ! for bash mode · / for commands                              \⏎ for newline



╭──────────────────────────────────────────────────────────────────────────────╮
│ > h                                                                          │
╰──────────────────────────────────────────────────────────────────────────────╯
  ! for bash mode · / for commands                              \⏎ for newline



╭──────────────────────────────────────────────────────────────────────────────╮
│ > he                                                                         │
╰──────────────────────────────────────────────────────────────────────────────╯
  ! for bash mode · / for commands                              \⏎ for newline



╭──────────────────────────────────────────────────────────────────────────────╮
│ > hel                                                                        │
╰──────────────────────────────────────────────────────────────────────────────╯
  ! for bash mode · / for commands                              \⏎ for newline



╭──────────────────────────────────────────────────────────────────────────────╮
│ > hell                                                                       │
╰──────────────────────────────────────────────────────────────────────────────╯
  ! for bash mode · / for commands                              \⏎ for newline



╭──────────────────────────────────────────────────────────────────────────────╮
│ > hello                                                                      │
╰──────────────────────────────────────────────────────────────────────────────╯
  ! for bash mode · / for commands                              \⏎ for newline

The solution is to "replay" all the commands sent to the terminal, in order to get the final state of the screen. For doing that we need to write a basic version of a terminal emulator: fortunately, we just need to support a handful number of ANSI escape sequences. This is the job of termdump.c and pytermdump.c

The core logic is in termdump.c, which takes a raw log file and produces the "final state" of the terminal. Ironically, claude itself was not able to produce a working version of termdump.c, which was written by chatgpt.

Once we have the "dumped" version of the screen, we can convert it into HTML using ansi2html.py.

License

MIT License

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

claude_logging-0.4.0.tar.gz (16.3 kB view details)

Uploaded Source

Built Distributions

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

claude_logging-0.4.0-cp38-abi3-musllinux_1_2_x86_64.whl (28.3 kB view details)

Uploaded CPython 3.8+musllinux: musl 1.2+ x86-64

claude_logging-0.4.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (30.2 kB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ x86-64

File details

Details for the file claude_logging-0.4.0.tar.gz.

File metadata

  • Download URL: claude_logging-0.4.0.tar.gz
  • Upload date:
  • Size: 16.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for claude_logging-0.4.0.tar.gz
Algorithm Hash digest
SHA256 d0b7f488fb8d6187218178db5d52e9120f8947d7f4dbfd2733424b7287dc6cf8
MD5 5d032f74a79d592500cc8f85de79d5f2
BLAKE2b-256 1b89bedb9562c465330b244adcf5809121822b97681569ccd55ed90a68d945ec

See more details on using hashes here.

Provenance

The following attestation bundles were made for claude_logging-0.4.0.tar.gz:

Publisher: build-and-publish.yml on antocuni/claude-logging

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file claude_logging-0.4.0-cp38-abi3-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for claude_logging-0.4.0-cp38-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 f85ec0d690b6b3aafb16d6eb88e0f6f3b91212e62a69fa963be04c028ab5ac71
MD5 6fcff1ea0c26daa0f26e581675c1b003
BLAKE2b-256 259aa0f3107a013c895d6410f35766d1abbba5873828efdb254d20aef7ef2702

See more details on using hashes here.

Provenance

The following attestation bundles were made for claude_logging-0.4.0-cp38-abi3-musllinux_1_2_x86_64.whl:

Publisher: build-and-publish.yml on antocuni/claude-logging

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file claude_logging-0.4.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for claude_logging-0.4.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 4dae2e4a56439d6bf88938af4f791ffb693d90e52cf645f70300c881970c2241
MD5 e4583419b05483a876c0a32e362f31b0
BLAKE2b-256 e3c0a8d5c6da8e0564a88e531610780870921f4a0ae70328ce54db57fa621511

See more details on using hashes here.

Provenance

The following attestation bundles were made for claude_logging-0.4.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: build-and-publish.yml on antocuni/claude-logging

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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