Beignet is experimental alpha software. The 0.0.x package line is for early
evaluation, and APIs may change between releases while the framework settles.
Pino-backed LoggerPort provider for Beignet.
Use this package when you want ctx.ports.logger backed by Pino while keeping
application code dependent on the stable LoggerPort interface from
@beignet/core/ports.
createPinoLoggerProvider(...) returns the stable PinoLoggerProvider type.
LoggerPinoConfig describes its validated config; the Zod schema remains
internal.
bun add @beignet/core @beignet/provider-logger-pino pino
Pretty development logs are optional:
bun add -d pino-pretty
import { createNextServer, createNextServerLoader } from "@beignet/next";
import { createPinoLoggerProvider } from "@beignet/provider-logger-pino";
import { initialPorts } from "@/infra/port-wiring";
export const getServer = createNextServerLoader(() =>
createNextServer({
ports: initialPorts,
providers: [createPinoLoggerProvider()],
context: ({ ports }) => ({
requestId: crypto.randomUUID(),
ports,
}),
}),
);
The provider installs ctx.ports.logger.
It flushes the provider-owned Pino logger during server.stop() so buffered
destinations and transports can drain before shutdown.
beignet doctor --strict checks that installed Pino logger providers are
registered in server/providers.ts.
The provider reads LOG_-prefixed environment variables:
| Variable | Default | Description |
|---|---|---|
LOG_LEVEL |
info |
trace, debug, info, warn, error, or fatal |
LOG_FORMAT |
json |
json or pretty |
LOG_SERVICE |
none | Optional service name added to log bindings |
LOG_TIMESTAMP |
true |
Include ISO timestamps; accepts true or false |
LOG_FORMAT=pretty requires pino-pretty. If it is unavailable, the provider
falls back to JSON logging and emits a warning.
Use createPinoLoggerProvider(...) when you want to pass options directly
instead of relying only on LOG_* env vars. Options override env-derived
values:
import { createPinoLoggerProvider } from "@beignet/provider-logger-pino";
export const providers = [
createPinoLoggerProvider({
level: "debug",
format: "pretty",
service: "api",
timestamp: true,
}),
];
Use createPinoLogger(...) when the app owns Pino configuration, transports,
or destinations:
import { createPinoLogger } from "@beignet/provider-logger-pino";
import pino from "pino";
const destination = pino.destination("./app.log");
const pinoLogger = pino({ level: "info" }, destination);
const logger = createPinoLogger({ logger: pinoLogger });
The direct factory only adapts the supplied Pino logger to LoggerPort; the
caller owns flushing and destination shutdown.
ctx.ports.logger.info("Post published", {
postId: post.id,
actorId: ctx.actor.type === "user" ? ctx.actor.id : undefined,
});
const log = ctx.ports.logger.child({ requestId: ctx.requestId });
log.error("Failed to publish post", { error });
| Export | Purpose |
|---|---|
createPinoLogger(options) |
Adapt an app-owned Pino logger to LoggerPort |
CreatePinoLoggerOptions |
Options for createPinoLogger() |
createPinoLoggerProvider(options?) |
Provider factory; omitted options use LOG_* env values |
CreatePinoLoggerProviderOptions |
Options for createPinoLoggerProvider() |
LoggerPinoConfig |
Validated provider config type |
LoggerPort |
Re-export from @beignet/core/ports |
LogLevel |
Re-export from @beignet/core/ports |
The provider contributes ctx.ports.logger, the standard Beignet
LoggerPort. Use createPinoLogger(...) when app infrastructure needs to own
the underlying Pino logger; application workflows should continue to depend on
the stable port.
This provider does not record devtools provider events for each log call. Logs
are the primary output. Use provider instrumentation on the external providers
doing work, and include requestId, traceId, actor, tenant, or feature
metadata in log bindings when those fields are useful operational context.
Invalid LOG_* configuration fails during provider setup. If
LOG_FORMAT=pretty is configured without pino-pretty, the provider falls back
to JSON logging and emits a warning instead of failing startup.
Use LOG_FORMAT=pretty for local development when pino-pretty is installed.
Use a memory or fake LoggerPort in use-case tests when assertions should not
depend on console output.
Use JSON logs in production unless the runtime explicitly expects formatted
text. Set LOG_SERVICE per deployed service and include request/trace metadata
from Beignet context so logs correlate with devtools, provider events, and
error reports.
MIT