LZ Log Reader
Rebuild a generation from its .txt log — no image needed
- positive_text
- negative_text
- seed
- steps
- cfg
- sampler_name
- scheduler
- width
- height
- ckpt_name
If you've ever lost an image but still had its log file, you know the pain of trying to hand-rebuild the settings. LZ Log Reader is the automated version: point it at a .txt log written by the pack's LZSaveImageAndLog, and it parses the file back into typed outputs - positive text, negative text, seed, steps, CFG, sampler, scheduler, dimensions, and checkpoint name. Feed those into an LZKSamplerDecode and the generation reassembles itself.
How it works
Two inputs: filepath (the log file) and index (which generation block to read). The parser understands the multi-block format that LZSaveImageAndLog writes - blocks start with Date:, then carry Model: (with the checkpoint's (Hash: …) extracted separately), Size:, a combined Seed: | Steps: | CFG: | Sampler: | Scheduler: line, then Positive: and Negative: sections. With index = -1 (the default) it returns the last block in the file; set a specific index to pull an earlier run.
Outputs map straight onto what a sampler wants:
- positive_text / negative_text - reconstructed prompt strings.
- seed (INT), steps (INT), cfg (FLOAT), sampler_name, scheduler (STRINGs).
- width / height (INTs), ckpt_name (STRING).
If the file is missing or unparseable, it returns safe defaults (empty strings, seed 0, steps 20, cfg 8, euler/normal, 512×512) rather than throwing - which is friendly but means a bad path looks like a valid 512×512 run at seed 0. That's the trap to watch.
The honest framing
This node only makes sense inside the pack's logging story. It reads logs in a specific format - the one LZSaveImageAndLog writes. If your logs come from any other source (A1111's parameters text, ComfyUI's PNG chunks, someone else's save node), this reader won't understand them; you'd be better off with a generic log parser. It's not a general metadata reader, it's the read-half of a specific write-half.
Where it shines is the round-trip: save with LZSaveImageAndLog, then later drop LZLogReader → LZKSamplerDecode → LZSaveImageAndLog and you have a "replay an old generation" chain where the log file is the recipe. Combined with the pack's CSV logger for searchability, you've got the full reproducibility loop.
Installing it
cd ComfyUI/custom_nodes
git clone https://github.com/liz-ils/ComfyUI-LZNodes
restart → MyCustomNodes/Log. ComfyUI Manager: search ComfyUI-LZNodes. No extra dependencies - pure Python stdlib parsing.
Where people get burned
- Index semantics:
-1is "last block," not "all blocks" - if your log has ten runs and you want the first, you need index0. - The silent default fallback described above: check the file path before trusting outputs; empty text + seed 0 usually means "file not found," not "this was a seed-0 run."
- Negative prompts spanning multiple lines are captured until the parser hits a blank or an outdent - if the log was written by a different tool with different formatting, that heuristic can swallow or truncate content.
For the pack's own ecosystem it's a tidy little tool. Just don't expect it to read the world's logs.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| filepath | STRING | — | |
| index | INT | -1-1–10000 | — |
Outputs (10)
| Name | Type | Description |
|---|---|---|
| positive_text | STRING | — |
| negative_text | STRING | — |
| seed | INT | — |
| steps | INT | — |
| cfg | FLOAT | — |
| sampler_name | STRING | — |
| scheduler | STRING | — |
| width | INT | — |
| height | INT | — |
| ckpt_name | STRING | — |