17: Trace

Phlo's trace mode is a runtime instrumentation layer that logs every call to a generated method, prop getter, static or native function with timing and arguments. Per request Phlo writes a JSON dump to data/trace/<id>.json. Meant for debugging and profiling, not for production.

17.1: What trace does

With trace on, Phlo's compiler injects one line at the top of every generated method:

trace('class->method', compact('arg1', 'arg2'))

And Phlo loads functions.trace.php (a generated variant of functions.php) so that native helpers, esc(), arr(), loop(), view(), apply(), everything, get a trace call too. The result: a complete chronological log of what happened during a request.

17.2: Enabling

In your dev entrypoint:

phlo_app (
    id:    'Example',
    host:  'dev.example.nl',
    build: true,
    debug: true,
    trace: true,
)

Then run build::run so the generated PHP contains the trace() injections. From the next request on, every call is logged.

Trace output goes to data/trace/. The directory is created automatically.

17.3: What a trace contains

One JSON file per request with:

Field Contents
id Date-time + random suffix, also the file name
path, method, route Request context
ts, ms, count Start timestamp, total duration, number of events
active Map per file → kind → call count (quick overview of "what got touched a lot")
sequence Order of first touch per file (visualizes the request path through your app)
events Complete log: see below

Each event in events:

{
    "t":    12.345,
    "k":    "call",
    "c":    "user",
    "n":    "byEmail",
    "node": "user->byEmail",
    "f":    "user.phlo",
    "args": {"email": "jordi@example.nl"}
}
Field Meaning
t Offset in ms since request start
k Kind: call, static, get (prop get), set (prop set), function
c, n Class and name
f Source file (resolved via classmap + sourcemap)
args Snipped arguments, see X.4

17.4: Argument snipping

Full argument values would make the trace unreadable. Phlo snips:

Type Becomes
null, bool, int, float unchanged
string > 200 characters ... truncated at 200
array '[N items]' (length only)
object with an id property {class: ..., id: ...}
Other object {class: ...}

That is enough to see which records were touched without dumping the entire payload.

17.5: Reading via the Phlo Control Center

The Phlo Control Center has a Trace tab that reads data/trace/index.json. The most recent trace is at the top; a selectbox opens older ones. Per trace you see active, sequence and the event stream.

index.json keeps the last 100 traces. Older ones are auto-pruned along with their JSON file.

17.6: Maintenance: `build::traceShadow`

functions.trace.php is a generated file. Whenever you add something to or change something in functions.php, regenerate it:

php www/app.php build::traceShadow

This parses functions.php and injects, in every function foo($a, $b), as the first statement:

trace('foo', compact('a', 'b'))

Then you align the contents of functions.trace.php with the source. The command is only relevant for those working on the Phlo runtime itself, not for app code.

17.7: When to use it, when not

Do:

Don't:

Turn trace: true on when you need it; turn it off when you're done. The Control Center keeps showing the historical traces until the auto-prune cleans them up.

We use essential cookies to make this site work. With your permission we also use analytics to improve the site.