@beautinique/backend-logger
v1.0.2
Published
Backend Logger for Beautinique project.
Maintainers
Readme
@beautinique/backend-logger
Framework-agnostic, production-ready logging for Beautinique backend services and microservices, built on Pino and pino-http.
- Secure by default - credentials, tokens, and cookies are always redacted, in every environment.
- Fast - raw JSON to
stdoutin production, no unnecessary allocations or blocking I/O. - One shape everywhere - the same request/response/error serializers and log-level mapping across every service, so Loki/Grafana queries stay consistent.
- Works anywhere - CLIs, workers, cron jobs, background queues, and HTTP servers (Express, Fastify, or plain
node:http).
Installation
npm install @beautinique/backend-loggerIf you want human-readable output in development (pretty: true), also install pino-pretty in the service that needs it:
npm install -D pino-prettypino-pretty is an optional peer dependency - it is only ever loaded when pretty is enabled, so production installs don't pay for it.
Core logger - createLogger
createLogger returns a fully configured Pino Logger. Use it anywhere - HTTP servers, CLIs, workers, cron jobs, background queues:
const logger = createLogger({
service: 'orders-worker',
pretty: true,
context: { region: 'ap-south-1' }, // extra static fields on every log line
});
logger.info('Worker started');
logger.error({ err: someError }, 'Job failed');| Option | Default | Description |
| --------- | ------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| service | (required) | Tags every log line - use this to filter/group logs per service in Grafana. |
| pretty | process.env.IS_DEV === 'true' | Human-readable, colorized output via pino-pretty. Also controls whether error stack traces are included. |
| context | undefined | Extra static fields merged into every log line. |
| logsDir | undefined | Additionally write logs to files in this directory, split by category (see "File logging" below). |
| redact | undefined | Extra redact paths, additively merged with the built-in secure defaults (see below). Cannot remove the defaults. |
| ... | | Any other native Pino LoggerOptions (level, formatters, hooks, ...) are passed straight through. |
HTTP logger - createHttpLogger
createHttpLogger returns pino-http middleware. It is intentionally independent from createLogger's own configuration (it has its own pretty/body-logging behaviour) while writing through the same Pino instance you pass it:
const logger = createLogger({ service: 'gateway' });
app.use(
createHttpLogger({
logger,
ignorePaths: ['/metrics'], // merged with the default ignore list
}),
);| Option | Default | Description |
| ------------------------------------------------------------------------------------ | ------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| logger | (required) | The Pino instance to attach request/response logs to. |
| pretty | process.env.IS_DEV === 'true' | Enables development-only behaviour (currently: logging the parsed request body). |
| ignorePaths | undefined | Extra paths to exclude from auto-logging, merged with /health, /favicon.ico, /robots.txt. |
| autoLogging | enabled | Pass false to disable entirely, or { ignore } - your predicate is combined with the default ignore list, not replaced. |
| customProps / customReceivedObject / customSuccessObject / customErrorObject | - | If supplied, merged on top of this package's own structured output (e.g. requestId) rather than replacing it. |
Always enforced (not configurable), so every service produces the same log shape:
- Request ID: reuses an inbound
x-request-idheader, or generates one withcrypto.randomUUID(). Available asrequestIdon every request/success/error log line. - Log level mapping: 2xx/3xx →
info, 4xx →warn, 5xx or an unhandled error →error. - Serializers: the secure request/response/error serializers described below.
- Success message format:
"Request completed with status <code>".
File logging
By default, logs only go to stdout (see "Where do logs go?" below). Passing logsDir additionally writes them to files in that directory, split into four categories:
const logger = createLogger({
service: 'gateway',
logsDir: 'logs', // created automatically if missing
});| File | Contents |
| --------------- | -------------------------------------------------------------------------------------------------------------- |
| request.log | Every HTTP request/response log line (from createHttpLogger), regardless of outcome - a full traffic trail. |
| error.log | Every error/fatal level log line - including request-tied ones, so it's a complete error feed on its own. |
| warning.log | Every warn level log line - including request-tied ones (e.g. 4xx responses). |
| success.log | Everything else (info/debug/trace) that is not already part of an HTTP request - plain application messages, so this file doesn't get flooded with routine request traffic. |
This is intentionally simple - plain append-only file streams, no rotation or worker threads. For log rotation, shipping to Loki, etc., see the roadmap in the package description.
Where do logs go by default?
Without logsDir, this package only ever writes to stdout (colorized in development, raw JSON in production) - it does not persist logs anywhere by itself. Persisting/collecting logs long-term is normally handled by your deployment infrastructure: a container runtime captures stdout, a shipper (Promtail/Fluent Bit/Grafana Agent) forwards it to Loki, and Grafana queries Loki. logsDir exists for simple local/file-based persistence when that infrastructure isn't in place yet.
Serializers
- Request -
id,method,url,query,params,ip,remoteAddress,remotePort,userAgent. Raw headers are never included.bodyis only included whenprettyis enabled. - Response -
statusCodeonly. - Error - recursively serializes
Error.causechains andAggregateError.errors, is circular-reference safe (via aWeakSetrecursion guard), and never throws - any thrown value (not justErrorinstances) is normalized into one first. Stack traces are stripped unlessprettyis enabled.
Redaction
These paths are always redacted, in every environment, and cannot be disabled - only extended via the redact option:
req.headers.authorization,req.headers.cookie,req.headers["x-api-key"]password,confirmPassword,token,accessToken,refreshToken- at the top level, and underbody.*/req.body.*(where a logged request body ends up nested).
createLogger({
service: 'gateway',
redact: { paths: ['user.ssn'] }, // merged with the defaults above
});Repository
https://github.com/Nageshwar1997/BQ-Packages
Homepage
https://github.com/Nageshwar1997/BQ-Packages
Issues
https://github.com/Nageshwar1997/BQ-Packages/issues
Author
Nageshwar Pawar
License
This package is licensed under the MIT License. See the root LICENSE file for details.
