Logging and traces
Logging and traces
Section titled “Logging and traces”Every plugin gets ctx.log, a console logger tagged with its id:
ctx.log.info("editor opened", docId);ctx.log.debug("columns", columns.map((column) => column.key));ctx.log.trace("render", { rows: rows.length });ctx.log.child("tasks").warn("task without id ignored", row);What actually reaches the console depends on one setting, General → Log
level: off, error, warn (default), info, debug, trace. A message
prints when its level is at or below the selected one, so debug and trace calls
can stay in the code permanently.
The shell uses the same logger: the kernel traces every event (emit,
handle) at the trace level and reports handler failures as errors, and the
table reports empty or malformed columns as warnings. Set the level to
trace to follow the UI → event → handler → store loop in the console.
Reading the level from a plugin
Section titled “Reading the level from a plugin”The same logger exposes the current level, so a plugin can skip expensive work or open its own debug view:
if (ctx.log.enabled("trace")) ctx.log.trace("state", expensiveSnapshot());
const level = ctx.log.level(); // "off" | "error" | … | "trace"const stop = ctx.log.onLevelChange((next) => ctx.log.info("level is now", next));// call stop() in the plugin's `dispose()`In a React component, useLogLevel() from @app/kernel re-renders on change
(useful to show a debug panel only at debug/trace).
To change the level, emit the shell setting — never write it directly:
ctx.emit("settings/value.set", { pluginId: "shell", key: "logLevel", value: "trace" });In code outside a plugin (a package, a component), createLogger("scope")
from @app/kernel gives the same logger; setLogLevel / logLevel read and
change the current level.
Documentation under CC BY 4.0 · © SCFlow contributors ·Back to supplychainflow.org