Structured logger that targets both the console and remote cloud formats. This includes:
- Pretty formatting for the console.
- Request logging middleware.
- Google Cloud structured logger.
- Google Cloud batched tracing via OpenTelemetry.
yarn install @bedrockio/loggerconst logger = require('@bedrockio/logger');
logger.setupGoogleCloud({
// Set up gcloud structured logging. Default true.
logging: true,
// Set up gcloud tracing. Default true.
tracing: true,
});This initialization code should be added as early as possible in your application.
Enable both logging and tracing and tell the tracing to ignore specific paths.
const logger = require('@bedrockio/logger');
logger.setupGoogleCloud({
tracing: {
ignoreIncomingPaths: ['/'],
},
});In development, setting process.env.LOG_LEVEL will set the log level which
silences lower level output:
- debug
- info
- warn
- error
The default is info which silences debug level logs.
Sets the logger to use console output for development. This is the default.
Sets the logger to output structured logs in JSON format. Accepts an options
object:
getTracePayload- This connects the logger to tracing, allowing you to batch logs by requests.
Enables batched Google Cloud tracing for Koa and Mongoose. This will allow discovery of slow operations in your application. The Cloud Trace API must be enabled to use this.
logger.debug('Hello');
logger.info('Hello');
logger.warn('Hello');
logger.error('Hello');The basic methods will output logs at different levels.
logger.info({
foo: 'bar',
});Passing an object into the console logger will output it as you would see in the
console. When using the Google Cloud logger it will output a structured JSON
payload that allows inspecting of the object in the
logging console.
logger.info('foo', 'bar');
logger.info(obj1, obj2);Multiple arguments will be concatenated together in the console logger. The Google Cloud logger will present a truncated message and export complex objects to the JSON payload.
logger.info('%s -> %s', 'foo', 'bar'); // foo -> barBasic printf style formatting is supported out of the box by the console logger,
and the Google Cloud console will format basic tokens (%s, %d, and %i).
Note that decimal precision formatting such as "%.2d" is not supported.
Koa middleware that logs HTTP requests:
const Koa = require('koa');
const logger = require('@bedrockio/logging');
const app = new Koa();
app.use(logger.middleware());You can append custom fields to every log entry with getExtraFields — a
function that receives the Koa context and returns an object of fields to
include.
app.use(logger.middleware({
getExtraFields: (ctx) => ({
organizationId: ctx.state?.organization?.id,
requestId: ctx.get('x-request-id'),
}),
}));Note: getExtraFields is ignored when shouldLogVerbose is active, as verbose
logging provides its own set of extra fields.
By default, requests with status >= 500 are logged at error level and all
others at info. You can override this with the getLogLevel option — a
function that receives the Koa context and returns a log level string.
app.use(logger.middleware({
// Log 4xx responses as warnings.
getLogLevel: (ctx) => {
if (ctx.status >= 500) return 'error';
if (ctx.status >= 400) return 'warn';
return 'info';
},
}));If getLogLevel returns a falsy value, the default behavior is used.
The logger middleware can record request body, query, and response body. This
is controlled by the shouldLogVerbose option — a function that receives the
Koa context and returns truthy to enable verbose logging for that request.
app.use(logger.middleware({
// Log verbose info for all error responses.
shouldLogVerbose: (ctx) => ctx.status >= 400,
}));app.use(logger.middleware({
// Log verbose info for a specific route.
shouldLogVerbose: (ctx) => ctx.url.startsWith('/1/foo'),
}));By default, fields matching common sensitive names (token, password,
secret, hash, jwt) are automatically stripped from logged bodies and
queries. You can customize this with allowedFields (whitelist) and
disallowedFields (blacklist), which filter individual keys within each logged
object.
Each accepts a string, regex, array of strings/regexes, or a function that receives the Koa context and returns any of the above.
app.use(logger.middleware({
shouldLogVerbose: (ctx) => ctx.status >= 400,
// Only include specific fields in logged bodies.
allowedFields: ['name', 'email', 'status'],
}));app.use(logger.middleware({
shouldLogVerbose: (ctx) => ctx.status >= 400,
// Exclude additional fields beyond the defaults.
disallowedFields: /token|password|secret|hash|jwt|creditCard/i,
}));app.use(logger.middleware({
shouldLogVerbose: (ctx) => true,
// Use a function for dynamic filtering.
allowedFields: (ctx) => {
return ctx.method === 'GET' ? ['q', 'page'] : ['name', 'email'];
},
}));