Skip to main content

flattrace

flattrace

Flat file, deep trace. flattrace records what a tool did as small, local JSONL events: nested steps, outcomes, errors and measured durations, even across child processes. Python, Rust and TypeScript writers share one v1 envelope. Check traces, find slow steps and redact a bundle for a bug report—all offline, without a collector, server or account. Code, docs and examples are MIT licensed.

Install

Registry packages are coming soon; these commands become valid after publication:

pip install flattrace                 # Python writer + flattrace CLI
cargo add flattrace serde_json        # Rust writer (Linux)
npm install flattrace                 # Node writer + TypeScript declarations

Until then, from a checkout: python3 -m pip install .; use flattrace = { path = "../flattrace/crates/flattrace" } in Cargo.toml; or run npm --prefix typescript install && npm --prefix typescript run build and npm install ./typescript in your Node project. Rust also needs serde_json. Python requires 3.10+, Node requires 22.18+, and Rust targets Linux.

Quickstart

Each ten-line example writes a fresh file in the current directory; remove or rename an existing demo file before rerunning. Explicit-path writers are strict; use the environment-based API described below in production.

Python

Save as demo.py, then python3 demo.py:

from flattrace import Writer

w = Writer("python.jsonl", "demo", "0.1.0")
span = w.start("calculate", {"items": 3})
result = sum([1, 2, 3])
w.point("result", {"value": result}, span=span)
w.end(span, "ok")
w.close()
print(result)
print("Wrote python.jsonl")

Rust

After cargo new demo and adding the dependencies above, replace src/main.rs with this and run cargo run (Linux):

use flattrace::Writer;
use serde_json::json;
fn main() -> std::io::Result<()> {
    let mut w = Writer::create(std::path::Path::new("rust.jsonl"), "demo", "0.1.0", vec![], "demo")?;
    let span = w.start("calculate", json!({"items": 3}), None)?;
    let result: i32 = [1, 2, 3].iter().sum();
    w.point("result", json!({"value": result}), Some(&span), None)?;
    w.end(&span, "ok", json!({}), None)?;
    w.finish("ok")?; println!("{result}"); println!("Wrote rust.jsonl"); Ok(())
}

TypeScript / JavaScript

Save as demo.mjs, then node demo.mjs. The same code works in TypeScript:

import { Writer } from 'flattrace';

const w = new Writer('node.jsonl', 'demo', '0.1.0');
const span = w.start('calculate', { items: 3 });
const result = [1, 2, 3].reduce((a, b) => a + b, 0);
w.point('result', { value: result }, span);
w.end(span, 'ok');
w.close();
console.log(result);
console.log('Wrote node.jsonl');

Check and analyse

The Python package supplies the CLI for all three writers:

flattrace check python.jsonl rust.jsonl node.jsonl
flattrace stats python.jsonl rust.jsonl node.jsonl
flattrace stats traces/ --json          # recursive; also reads .jsonl.gz
flattrace check --events flattrace-events.json python.jsonl

A deterministic synthetic fixture illustrates real CLI output (not performance data):

flattrace check tests/fixtures/legacy/1.jsonl
tests/fixtures/legacy/1.jsonl: 5 valid events
flattrace stats tests/fixtures/legacy/1.jsonl
Runs: 1  files: 1  duplicates excluded: 0
Status: {"ok": 1}
Levels (runs): {"unknown": 1}
Span durations across runs (ms; inclusive totals are NOT additive):
  file.open: n=1 p50=0 p95=0 max=0 total=0
    self: n=1 p50=0 p95=0 max=0 total=0
  run: n=1 p50=0 p95=0 max=0 total=0
    self: n=1 p50=0 p95=0 max=0 total=0
Errors by name (explicit error/outcome/severity; coalesced count): {}
Warnings by name (explicit data.severity=warn/warning only; otherwise unknown): {}
Slowest runs, with dominant spans (inclusive ms; unknown durations last):
  compat 00000000000000000000000000000002 ok 0 ms (tests/fixtures/legacy/1.jsonl)
    file.open: n=1 p50=0 p95=0 max=0 total=0
      self: n=1 p50=0 p95=0 max=0 total=0
    run: n=1 p50=0 p95=0 max=0 total=0
      self: n=1 p50=0 p95=0 max=0 total=0
Self = parent residence minus sequential, contained LOCAL direct-child residence; not CPU time. Cross-process children are not subtracted. Overlap/async/unknown => unknown, never wall-time subtraction.

Exit 0 means valid, complete evidence; 1 means validation issues or unfinished work; 2 means invocation or I/O failure. Missing ends stay unfinished. Inclusive nested durations must not be added as elapsed time; self_ms is unknown when local overlap or incomplete evidence prevents safe attribution.

Instrument a real tool

Use Writer.from_env / Writer::from_env / Writer.fromEnv: FLATTRACE_DIR=traces enables a new file per run, unset/empty disables tracing. Environment sink failures warn once and disable the sink without stopping product work; structural API errors still surface. FLATTRACE_LEVEL=0 disables I/O, level 1 is actions/decisions/aggregates, and level 2+ adds per-item detail. The tool gates detail; writers do not filter your calls.

Own a flattrace-events.json with static names, span/point kinds and required events per command. End every local span, then close/finish the run—never end the root directly. Propagate the enclosing span's traceparent and directory to children, each with its own writer/file. See the agent skill, nested process example, examples and API/analysis reference.

Why flattrace?

  • Versus OpenTelemetry: much smaller operational surface for studying local tools after they run. W3C-width IDs and parentage are familiar, but this is not OTLP, an OTel SDK, distributed monitoring, or an automatic OTel exporter.
  • Versus ad-hoc JSON logs: one shared envelope adds pairing, parentage, sequence checks, durations and unfinished-run detection. It is not a general log framework or a guarantee of crash persistence.

Share carefully

flattrace export python.jsonl rust.jsonl node.jsonl --out reviewed-share

Export consistently replaces paths/hosts/users and masks common credential patterns. It is not a secret detector: never log credentials; review the bundle and supply --path, --host, --user for ambiguous names before sharing. Only share reviewed exports, never raw traces. Originals remain untouched.

Develop and extend

SPEC.md is normative; JSON Schema describes the envelope, not complete stream validation. See CONTRIBUTING.md for all suites, AGENTS.md for repository invariants, CHANGELOG.md, ROADMAP.md, and optional learning conventions. No uploader, retention service or live collector is included.

Metadata

Release files for flattrace 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for flattrace 0.1.0
File Size Uploaded Provenance
flattrace-0.1.0.tar.gz 18.3 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for flattrace 0.1.0
File Interpreter ABI Platform
flattrace-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 40.3 kB

Release files / flattrace-0.1.0.tar.gz

Download URL flattrace-0.1.0.tar.gz
Size 18.3 kB
Tags Source
SHA-256 checksum
How to use checksums
a80afa58572eff2e8f863fb886ed55bab1a19d1e2b7c665ecba0862733045018
BLAKE2b-256 checksum
How to use checksums
ff3d2ebf08944b2fcc71ac1873eddf81b86bc9963c11ff51ac52e2e84d22b18d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.9.27 {"installer":{"name":"uv","version":"0.9.27","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / flattrace-0.1.0-py3-none-any.whl

Download URL flattrace-0.1.0-py3-none-any.whl
Size 22.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
afabc7187b78806723c3ac6c4808eed1c83d6c5628e5d3d065186ee74eff32c8
BLAKE2b-256 checksum
How to use checksums
bc8179a9e223a5afeea833c613f37d51909f9232f1108e8098f0d775fcfba69d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.9.27 {"installer":{"name":"uv","version":"0.9.27","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for flattrace 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page