Class RunProgressWriter
- All Implemented Interfaces:
EventListener<Event>,EventListener,Consumer<Event>
runProgressFile system property names a file to write it to:
-DrunProgressFile=/var/run/my-crawl/progress.ndjson
Like -DenableJMX=true and
RunSummaryWriter.SYS_PROP_RUN_SUMMARY_FILE, this is a system
property rather than a configuration setting, because the caller that wants
the file is the one that launched the JVM — a supervising process, a
scheduler, a CI job — and it should not have to edit the crawl
configuration to ask for it. Nothing is written when the property is absent,
and nothing about the crawl configuration changes when it is present.
What it writes
One JSON object per line, of two kinds:
{"type":"progress","crawlerId":"x","at":"2026-09-12T04:10:00Z","elapsedMs":12345,
"queued":42,"processing":2,"processed":1203,"baseline":5000,
"sessionEventCounts":{"COMMITTER_UPSERT_END":1200, ...},
"runEventCounts":{"COMMITTER_UPSERT_END":1200, ...}}
{"type":"heartbeat", ... same fields ... }
The four counters are gauges: current state, answering how far along the crawl is. They cannot be derived from any tally, since a cumulative count of queueings says nothing about how deep the queue is now. The two maps are counters, by the crawler's own event names, so nothing here is a selection made in advance — a new event type appears as a new key. They differ only for a crawl that was stopped and resumed: the session totals span its attempts, as the gauges do, while the run counts describe the attempt that wrote the line.
A progress line is written only when the numbers actually changed since the last one, so a crawl that is politely waiting between requests stays quiet. A heartbeat line is written when nothing has changed for a while, which is what separates "slow" from "stuck" for a supervisor that can otherwise only see that the process is alive.
Why sampling rather than listening
The counts come from CrawlerMetrics
on a timer, not from an event fired per document. A crawl of a local file
system with several threads can finalize thousands of documents a second,
and a writer on that path would put file I/O in the crawl loop and produce a
volume of output nobody can consume. Sampling costs nothing per document and
bounds the output by wall-clock instead of by crawl speed — the faster
the crawl, the more it compresses.
Note that in a clustered crawl each node writes its own file, since each has its own view to report.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic final recordOne line of the progress file. -
Field Summary
Fields -
Method Summary
Modifier and TypeMethodDescriptionvoidstatic voidregisterIfRequested(EventManager eventManager) Registers a progress writer on the given event manager if the system property asks for one.
-
Field Details
-
SYS_PROP_RUN_PROGRESS_FILE
System property naming the file to write crawl progress to.- See Also:
-
SYS_PROP_RUN_PROGRESS_INTERVAL
How often the counters are sampled. Optional, as a duration string.- See Also:
-
SYS_PROP_RUN_HEARTBEAT_INTERVAL
How long without change before a heartbeat is written. Optional.- See Also:
-
-
Method Details
-
registerIfRequested
Registers a progress writer on the given event manager if the system property asks for one.Registering here rather than through the crawl configuration is the point: the crawler's configurable surface is unchanged, so a caller that compiles configurations does not have to know this exists.
- Parameters:
eventManager- the event manager to register with
-
accept
-