@logbrew/sdk
0.1.40, @logbrew/node 0.1.24, and @logbrew/express 0.1.10. Each output
block shows its real output.
Choose Winston or Pino
Both libraries write structured JSON logs. Keep the library that your app already uses. The LogBrew setup is different for each one.Prepare a LogBrew project
1
Create a project key
Sign in with the CLI. Create a project and store its ingest
key in an owner-only file.The CLI does not print the key. In production, use the secret manager of
your platform.
2
Install the packages
The packages require Node.js 18.19 or newer. Install Winston, Pino, or
both.
3
Set the key and the deployment identity
createLogBrewNodeClient() reads the key from LOGBREW_SERVER_API_KEY.
The service name is the name in package.json. Set
LOGBREW_SERVICE_NAME to use a different name. The examples use ES
modules, so set "type": "module" in package.json.Node.js log levels
Each library has its own level names and numbers. LogBrew stores 4 levels and keeps the original level in metadata.
In Winston, a lower number is more severe. In Pino, a higher number is more
severe. Set
info in production and debug only for a short diagnosis.
Winston logger
Save this file aswinston-app.js. The first format drops records below the
logger level before any transport gets them. The LogBrew transport receives
every record that the logger writes, so it needs this filter.
node winston-app.js. The console gets 1 JSON line for each record at
info or higher. The stack is shortened here.
context.* metadata.
The transport sends the error name and message, but not the stack. Set
includeErrorStack: true in createLogBrewWinstonTransport() to send the
stack. Each message also becomes a breadcrumb on the next issue. Set
breadcrumbs: false to stop this.
Pino logger
Save this file aspino-app.js. Call installLogBrewPinoInstrumentation()
once, before the first log. It reads each finished Pino record. Pino still
writes to its own destination.
node pino-app.js. The host name and the stack are shortened here.
debug record before LogBrew sees
it.
The
token field is not in LogBrew. LogBrew drops credential, cookie, body,
query, URL, and stack fields, and keeps your Pino redact paths as a second
control. pid, hostname, and time are Pino defaults, so LogBrew does not
copy them.
Automatic capture requires Pino 9.11 or newer in the 9.x line, or Pino 10.1
or newer. For older Pino versions, use createLogBrewPinoDestination() from
@logbrew/sdk as a Pino destination.
To read Pino output in development, send it to pino-pretty.
Express logger
logbrewMiddleware() creates 1 request span for each request.
logbrewErrorHandler() reports errors as issues. A Pino log inside a request
gets the trace ID and span ID of that request. Save this file as
express-app.js.
The span name uses the route template, not the concrete path. The
listening on 3000 log has no trace, because it is outside a request.
Let the middleware create its own request clients. Do not pass the
process-wide client to logbrewMiddleware() or logbrewErrorHandler().
The middleware shuts down its request client after each response.
Add the trace to Winston logs
For Winston, give the transport the active trace.logbrewTransport to the transports list of the logger. A Winston log
inside an Express request then has the trace ID and span ID of the request.
Read the logs back
<trace_id> from a trace
or an issue. To read from CI or a coding agent, use a project read key. See
Verify your setup.
Shut down without lost logs
The client sends queued events 1 second after the first event or at 50 events. When the event loop is empty, the client sends the remaining events for at most 2 seconds.process.exit() and signals skip that step. Call
await client.shutdown() before you exit, as the SIGTERM handler in the
Express example does.
Recover from problems
To choose log fields, see
Structured logging. For other frameworks, see
SDK integration.
