Run History
ETLPlus records local run history for etlplus run and exposes that history through stable
read/query commands in the CLI.
What Gets Recorded
Each
etlplus runinvocation gets arun_id.Start and finish metadata are persisted to the configured local history backend.
The default backend is SQLite at
${ETLPLUS_STATE_DIR:-~/.etlplus}/history.sqlite.A JSONL backend is also available through
ETLPLUS_HISTORY_BACKEND=jsonl.You can set pipeline defaults with a top-level
historyblock containingenabled,backend,state_dir, andcapture_tracebacks.etlplus runcan override those defaults with--history/--no-history,--history-backend,--history-state-dir, and--capture-tracebacks/--no-capture-tracebacks.Effective precedence is CLI overrides, then environment variables for backend and state directory, then pipeline config, then package defaults.
DAG-style runs persist one compact aggregate run summary on the parent run row.
DAG-style
run --job/run --allexecutions also persist one per-job history row for each executed/succeeded/failed/skipped job, including plan order, timing, terminal status, and per-job result summaries.etlplus schedule --run-pendingreuses the sameetlplus runpath, so scheduled dispatches are recorded in the same local history store.Scheduler-triggered runs may add a nested
result_summary.schedulerobject with the schedule name, trigger kind, catch-up flag, and original scheduled timestamp.
When traceback capture is enabled, failed runs also persist a capped error_traceback string in the
run-level history row.
Today, the persisted history is written by etlplus run. The read/query commands below inspect that
local store; they do not require external services.
The stable v1.x read surface is the CLI query family documented here: history, log, status,
report, and the read-only local dashboard exposed through etlplus ui.
Commands
etlplus history
Inspect normalized persisted history.
Scope:
--level run|jobFilters:
--job,--pipeline,--run-id,--status,--since,--until,--limitOutput: JSON by default, explicit JSON with
--json, or a Markdown table with--table
Example:
etlplus history --job file_to_file_customers --status succeeded --limit 10 --table
Inspect per-job DAG history:
etlplus history --level job --pipeline customer_sync --status skipped --table
etlplus log
Inspect raw persisted history events without normalization.
Scope:
--level run|jobFilters:
--job,--pipeline,--run-id,--status,--since,--until,--limitStreaming:
--followpolls for newly observed matching raw records until interruptedFollow-mode output is compact line-oriented JSON regardless of
--pretty
Example:
etlplus log --run-id 8e4a33d7 --follow
etlplus log --level job --pipeline customer_sync --status skipped --follow
etlplus status
Show the latest normalized run or job row.
Scope:
--level run|jobFilters:
--job,--pipeline,--run-idOutput: one normalized run/job object as JSON, or
{}with exit code1when no match exists
Example:
etlplus status --job file_to_file_customers
etlplus status --level job --job file_to_file_customers
etlplus report
Aggregate normalized run or job history.
Scope:
--level run|jobFilters:
--job,--pipeline,--run-id,--status,--since,--untilGrouping:
--group-by job|pipeline|run|status|dayOutput: grouped JSON by default or a Markdown table with
--tableMetrics include run counts, success-rate percentage, and average/minimum/maximum duration
Example:
etlplus report --group-by day --since 2026-03-01T00:00:00Z --table
Aggregate per-job history by pipeline:
etlplus report --level job --group-by pipeline --since 2026-03-01T00:00:00Z --table
etlplus ui
Launch the optional local history UI.
Scope: read-only view over the same persisted local store used by
history,log,status, andreportTransport: one lightweight local HTTP server with HTML at
/and the raw snapshot payload at/snapshot.jsonRefresh:
--refresh-secondscontrols simple page reload pollingBrowser:
--no-browsersuppresses automatic browser launchSecurity: the default host is
127.0.0.1. The local UI does not provide authentication or TLS, so avoid binding to0.0.0.0unless you understand that this exposes local run-history data on that network interface.
Example:
etlplus ui --port 8765 --limit 25
Headless or scripted launch:
etlplus ui --no-browser --limit 25
The /snapshot.json endpoint exposes the same read-only run and job snapshot used by the HTML page.
The UI is intentionally additive on the v1.x line: it does not introduce a new history backend,
schema, or write path. It reads the same normalized run and job records already exposed by the
stable CLI commands.
Output Conventions
historyreturns normalized records.logreturns raw backend-native records.statusreturns a single normalized record.reportreturns grouped rows plus a top-level summary in JSON mode.The top-level normalized run and job shapes are the stable
v1.xcontract; nestedresult_summarykeys may grow additively over time for richer DAG summaries. DAG-aware run-level summaries stay compact and aggregate-oriented; detailed per-job execution data is available through--level job.Scheduler metadata is additive-only; scheduled runs still use the same top-level run and job shapes as manual
etlplus runinvocations.
Stable Normalized Fields
Stable normalized run fields:
run_idpipeline_namejob_nameconfig_pathconfig_sha256statusstarted_atfinished_atduration_msrecords_inrecords_outerror_typeerror_messageerror_tracebackresult_summaryhostpidetlplus_version
Stable normalized job fields:
run_idjob_namepipeline_namesequence_indexstarted_atfinished_atduration_msrecords_inrecords_outstatusresult_statuserror_typeerror_messageskipped_due_toresult_summary
These normalized run/job shapes are the supported read contract across both SQLite and JSONL backends. Raw backend append records remain debug-oriented and backend-specific.
Event-to-history mapping for etlplus run
Event stream field |
Persisted history field(s) |
Notes |
|---|---|---|
|
|
Stable join key across STDERR events, STDOUT payloads, and persisted history. |
|
|
Same command invocation start time in ISO-8601 UTC form. |
|
|
Semantically the same elapsed run duration. |
|
|
Event statuses are |
|
|
Stable failure metadata when present. |
Event-only fields today:
eventcommandlifecycletimestamp
History-only fields today:
config_sha256records_inrecords_outerror_tracebackhostpidfull run/job
result_summaryjob_runs.sequence_indexjob_runs.skipped_due_to
DAG job detail is intentionally persisted in job_runs; ETLPlus does not currently promise a
one-event-per-job stream contract.