Pino Logging
Structured request logging via lifecycle hooks — request received, response sent, errors caught.
Pino is the fastest Node.js JSON logger. Katman's loggingHooks plugs it into the lifecycle hooks system so every request, response, and error is logged automatically.
Setup
import { } from "katman"
import from "pino"
import { } from "katman/pino"
const = ({
: () => ({ : getDB() }),
: ({ : () }),
})That's it. Every request flowing through your API is now logged.
What gets logged
When a request is received:
{ "level": 30, "path": "users/list", "hasInput": true, "msg": "request received" }When a response is sent:
{ "level": 30, "path": "users/list", "durationMs": 0.42, "msg": "response sent" }When an error occurs:
{ "level": 50, "path": "users/create", "error": "CONFLICT", "msg": "request error" }The durationMs field measures how long the procedure took, rounded to two decimal places.
Options
import { } from "katman/pino"
({
: pino(),
: true, // log "request received" (default: true)
: true, // log "response sent" (default: true)
})Set logRequests: false to skip the "request received" messages and only log responses and errors. This is useful in high-traffic production environments where you want to reduce log volume.
Errors are always logged regardless of these settings.
Using any logger
The logger option accepts any object that implements this interface:
interface Logger {
(: <string, unknown>): Logger
(: <string, unknown>, ?: string): void
(: <string, unknown>, ?: string): void
(: <string, unknown>, ?: string): void
(: <string, unknown>, ?: string): void
}This means you're not locked into Pino. Any logger with compatible methods works — winston with a wrapper, consola, or even a custom logger.
The interface is Pino-compatible by design. If you use Pino, it works out of the box. If you use something else, you may need a thin adapter.
Combining with other hooks
loggingHooks returns a plain hooks object. You can combine it with other hooks by spreading:
import { } from "katman/pino"
const = katman({
: () => ({}),
: {
...({ : pino() }),
"serve:start": ({ }) => {
.(`Server ready at ${}`)
},
},
})What's next?
- OpenTelemetry — distributed tracing for each procedure call
- Rate Limiting — protect your API from abuse
- Server — lifecycle hooks and
serve()options