Custom transports
Subclass LoggerTransport or CfLoggerTransport, register before build(), and tune levels in flare.json.
AI generated, pending review
Add a custom transport when you need logs in a sink beyond the default console output. Register every transport before the first host.build(); post-build registration does not update the live logger.
1. Choose a base class
Section titled “1. Choose a base class”| Runtime | Base class | Import |
|---|---|---|
| Node.js | LoggerTransport | @flare-ts/core |
| Cloudflare Workers | CfLoggerTransport | @flare-ts/core |
2. Implement the transport
Section titled “2. Implement the transport”A transport is a class with:
static transportName: must match the key inlog.transportswhen you override per-transport levelstatic deps: pinned empty; transports take no service dependencies, and callinginject()throws. Construction-time needs come fromstatic configplusthis.config()and from clients you open inonStart()static config(optional): config tokens available viathis.config()in lifecycle hookswrite(record: LogRecord): void: required; receives filtered records onlyonStart?()/onStop?()(optional): lifecycle hooks in registration order (shutdown in reverse)
Example for Workers:
import { CfLoggerTransport, LOG_CONFIG } from "@flare-ts/core";import type { LogRecord } from "@flare-ts/core";
class MetricsTransport extends CfLoggerTransport { public static override readonly transportName = "metrics"; public static override readonly config = [LOG_CONFIG];
public write(record: LogRecord): void { if (record.level === "error" || record.level === "fatal") { // forward to your sink } }}Node example: subclass LoggerTransport instead of CfLoggerTransport. The rest of the shape is the same.
3. Register on the host
Section titled “3. Register on the host”import { FlareHost } from "@flare-ts/core";import { node } from "@flare-ts/core/node";
const host = new FlareHost(node);host.logging.transport(MetricsTransport);
const app = host.build();app.run();The runtime’s default console transport is wired in first. Transports you register follow in registration order.
4. Tune levels in config (optional)
Section titled “4. Tune levels in config (optional)”Name transports in flare.json under log.transports. Keys must match each class’s transportName:
{ "log": { "level": "info", "transports": { "console": { "level": "debug" }, "metrics": { "level": "error" } } }}Per-transport level overrides the global log.level for that transport only.
Rules and constraints
Section titled “Rules and constraints”| Rule | Detail |
|---|---|
Register before build() | The live logger snapshots its transport list during build() |
No this.inject() in transports | Open clients in onStart() and read settings with this.config(); calling inject() throws |
| Node async lifecycle | onStart and onStop may return Promise<void>; the logger awaits them |
| Workers sync lifecycle | CfLoggerTransport.onStart and onStop must not return a Promise |
Related
Section titled “Related”- Logging overview
- flare.json reference
- Host: when
build()compiles the logger