6.2. After main: LeanProfiler
LeanProfiler measures boundaries chosen by the Lean application. A source indexer can use names that do not exist inside the compiler or a foreign library:
profileFromEnvironment "indexer.run" do
for (sourcePath, fileIndex) in sourcePaths.zipIdx do
withStep fileIndex do
let contents ← span "source.read" (readSource sourcePath)
let syntax ← span "source.parse" (parseSource contents)
span "source.analyze" (analyzeSource syntax)
Its measurements come from Lean and Std runtime APIs:
-
IO.monoNanosNowfor monotonic span boundaries; -
IO.getTIDfor the current Lean thread; -
IO.Process.getPIDfor Trace Event process identity; -
IO.getNumHeartbeatsfor the current thread's work counter; -
Std.IO.Process.getResourceUsagefor session-wide process counters.
Heartbeats add a Lean-specific signal alongside elapsed time. LeanProfiler does not discover operations by itself: the application decides where a span begins, what it is called, and which metadata it carries.
None of these APIs produces accelerator kernel timestamps. A completion hook can synchronize a device and attach allocator counters, but an absent field means “not observed,” not zero.