Every plugin class that extends FDO_SDK inherits a set of logging methods. These write structured JSON log entries to rotating log files so you can trace plugin behavior during development and in production.
Log methods
All logging methods are available directly on your plugin class via this.
this.log(message)
Basic log entry at the configured log level (defaults to info):
this.log("Plugin is starting up");
Info-level log. Accepts optional metadata objects as additional arguments:
this.info("Plugin initialized", { plugin: this.metadata.name });
this.info("Handling request", { handler: "submitForm", userId: "u42" });
Warning-level log for conditions that are unexpected but recoverable:
this.warn("JSON store not available, falling back to in-memory");
this.warn("Slow handler response", { handler: "loadData", durationMs: 3200 });
Debug-level log for detailed diagnostic information. Only written when the log level is set to debug or lower:
this.debug("Cache miss for key", { key: "prefs:theme" });
Verbose-level log for high-frequency or low-priority diagnostic entries:
this.verbose("Processing item", { index: 42, total: 100 });
Silly-level log — the lowest priority. Use for trace-level details you only need in deep debugging sessions:
this.silly("Entering render path", { timestamp: Date.now() });
this.error(error)
Logs an Error object including the stack trace. Always pass an Error instance:
try {
// some operation
} catch (err) {
this.error(err as Error);
}
this.event(name, payload)
Emits a structured event log entry and returns a correlation ID. Use this for tracking multi-step flows across log entries:
const correlationId = this.event("plugin.init.start", { phase: "setup" });
this.debug("Init event emitted", { correlationId });
// Later in the flow:
this.event("plugin.init.complete", { correlationId, durationMs: 42 });
The correlation ID is a string in the format <name>-<timestamp>-<counter>. You can pass it along as payload in subsequent events to link log entries from the same logical operation.
this.getLogDirectory()
Returns the resolved path to the directory where this plugin’s log files are written:
this.info(`Log directory: ${this.getLogDirectory()}`);
Log file location
The SDK writes two rotating log files:
info-<DATE>.log — all log entries at info level and above
error-<DATE>.log — entries at error level only, with stack traces
The log root directory resolves in this order:
FDO_SDK_LOG_ROOT environment variable
./logs relative to the current working directory
In the FDO host runtime, log files are written directly into PLUGIN_HOME/logs/. Plugin identity (pluginId, component, sessionId) is embedded in each log entry as structured metadata rather than in a separate nested directory.
Files rotate daily and are kept for 7 days. Each file is capped at 1 MB before rotation.
Example: structured init logging
init(): void {
this.info("Plugin init started", { plugin: this.metadata.name });
const correlationId = this.event("plugin.init.custom", { phase: "start" });
this.debug("Custom init event emitted", { correlationId });
// ... setup work ...
this.event("plugin.init.custom", { phase: "complete", correlationId });
this.info(`Log directory: ${this.getLogDirectory()}`);
}
Example: tracking a multi-step handler
PluginRegistry.registerHandler("deployConfig", async (data: unknown) => {
const correlationId = this.event("handler.deploy.start", { data });
try {
// step 1
this.debug("Validating config", { correlationId });
// ... validation ...
// step 2
this.debug("Writing config to store", { correlationId });
// ... write ...
this.event("handler.deploy.success", { correlationId });
return { ok: true };
} catch (err) {
this.error(err as Error);
this.event("handler.deploy.failure", { correlationId, error: String(err) });
return { ok: false };
}
});
Use this.event() at the start and end of any multi-step operation and pass the returned correlation ID through subsequent log and event calls. This makes it easy to filter all log entries for a single logical flow in your log files.
Setting the log level
The default log level is info. To change it, set the LOG_LEVEL environment variable before starting your plugin process:
LOG_LEVEL=debug node plugin.js
Valid levels from highest to lowest priority: error, warn, info, verbose, debug, silly.