With pino integrating pino multistream this package is no longer needed and may not be maintained in the future.
See pino multistream
const loggerFactory = require('cosmas').default;
or with import
import loggerFactory from 'cosmas';
const logger = loggerFactory; // factory itself is a logger
// or
const logger = loggerFactory();
const logger = loggerFactory({
disableFields: ['error.stack'],
enableFields: ['req.protocol']
});
See Options for a list of possible options.
Every logger can be used to create a child logger. Child logger inherits all configuration of its parent and cannot override them.
Child logger can specify its own name which is then concatenated with parent's name. Therefore the child logger name is parentNamechildName
.
const parentLogger = loggerFactory('database', { pretty: false });
const childLogger = parentLogger('.updates');
Logger itself is an enhanced and specifically configured pino
instance, so you may use all basic pino
log methods
logger.info('hello world')
logger.error('this is at error level')
logger.info('the answer is %d', 42)
logger.info({ obj: 42 }, 'hello world')
logger.info({ obj: 42, b: 2 }, 'hello world')
logger.info({ obj: { aa: 'bbb' } }, 'another')
All pino
levels are supported and additionaly there is a warning
level which is equivalent to warn
level.
Default minimal log level is debug
.
All loglevels up to warning (exclusive) - trace, debug and info - are logged to stdout
only.
All loglevels from warning up (inclusive) - warning, error, fatal - are logged to stderr
only.
You can enhance cosmas logger with automatic Sentry logging functionality.
Sentry SDK @sentry/node
is a peer dependency. If you want cosmas to use it, install it in your project.
import extendSentry from 'cosmas/sentry'
// (1) Let cosmas initialize sentry with provided DSN
const myLogger = loggerFactory();
extendSentry(myLogger, { sentry: 'https://<key>@sentry.io/<project>' }); // this will CHANGE the logger instance and returns it
// or
const sentryLogger = extendSentry(myLogger, { sentry: 'https://<key>@sentry.io/<project>' });
// (2) Configure sentry yourself and let cosmas use it
Sentry.init({/*...*/})
const myLogger = loggerFactory();
extendSentry(myLogger, { sentry: true });
After sentry extension, the interface of log methods will change.
const myLogger = loggerFactory();
myLogger.fatal('message');
myLogger.fatal({ foo: 'bar' }, 'message');
const sentryLogger = extendSentry(myLogger);
sentryLogger.fatal('message', sentryCallback);
sentryLogger.fatal({ foo: 'bar' }, sentryCallback);
sentryLogger.fatal({ foo: 'bar' }, 'message', sentryCallback);
All log methods accept an optional sentryCallback
argument. You can use it to pass a function which will obtain a Sentry scope
which can be edited that way.
import { Scope } from '@sentry/node';
sentryLogger.fatal('message', (scope: Scope) => {
// scope.setContext
// scope.setTags
// scope.setExtras
});
When configured, cosmas (additionally to standard logging) captures all logs via Sentry SDK. Logs containing stack
are logged as exceptions via captureException
(preserves stack trace) and all other messages via captureMessage
.
Either way, scope is appropriately set, as well as all payload is passed on in scope's metadata.
By default, Cosmas only logs to Sentry logs with warn
or higher level. You can change this behaviour by setting sentryLevel
option.
cosmas
contains an express middleware which you can use to log all requests and responses of your express application.
Usage:
const express = require('express');
const logger = require('cosmas').default;
// or
import logger from 'cosmas';
const app = express();
// or
const router = express.Router();
app.use(logger.express)
// or
router.use(logger.express)
By default, it will log all incoming requests in debug
level, all outcoming responses with out
property in debug
level and all outcoming responses without out
property on info
level.
If you use it together with logger's error express middleware, it will also log all errors in error
level.
app.use(logger.expressError)
All those log messages will contain request and possibly response, error, time from request to response, status code and user-agent
, x-deviceid
and authorization
request headers.
You might want to omit some requests or responses from logging completely. Right now, there are two ways to do it and you can even use both at once.
- Use
options.ignoredHttpMethods
to define an array of HTTP methods you want to omit. By default allOPTIONS
requests and responses are ommited. See options for details - Use
options.skip
method to define custom rules for request/response skipping. Set it to a function which accepts an Express'sRequest
andResponse
and returnsboolean
. If the return value istrue
, request (or response) will not be logged. You might want to usematchPath
helper to ignore requests based on thereq.originalUrl
value
const { matchPath } = require('cosmas/utils');
const logger = require('cosmas').default({
skip: matchPath(/heal.h/),
});
cosmas
is meant to be used throughout different environments (development, testing, production) and some of its configuration is setup differently based on the environment it runs in. By default, severity
(contains current log level) and pkgVersion
(contains current version of cosmas
) fields are added to logged object.
If the NODE_ENV
environment variable is set to test
, all logs are turned off (minimal loglevel is set to silent
which effectively turns logging off).
If you set pretty
option to true
, you enable pretty print mode intended for development use. cosmas.pkgVersion
, cosmas.loggerName
and severity
are ommited from the output.
Standard pino log is used and it's optimized for Google Stackdriver logging. That means that default log level is debug
, pretty print is turned off and pino's messageKey
option is set to message
.
Options override both default logger configuration and environment-specific configuration. However, do not forget to specify it during the first cosmas
. During it, root logger is created and it cannot be changed later.
defaultLevel
- set logger's minimal loglevel (default isdebug
)disableFields
- list of paths which will be omitted from the objects being logged (if any)enableFields
- list of paths which will not be omitted by default serializers from objects being loggedignoredHttpMethods
- list of HTTP methods which will not be logged by express logging middleware at all. Defaults to['OPTIONS']
streams
- list of stream objects, which will be passed directly to pino-multistream's multistream function instead of defaultcosmas
streampretty
- if set totrue
, logger will use pino pretty human-readable logs. This option can be overriden bystreams
disableStackdriverFormat
- if set tofalse
, logger will addseverity
field to all log objects, so that log levels in Google Stackdriver work as expected. Defaults tofalse
skip
- Function to be used in express middlewares for filtering request and response logs. If the function returnstrue
for a given request, no message will be logged. No default value.config
- object, which will be passed to underlying logger object. Right now, underlying logger is pino, so for available options see pino API docssentry
-true
to enable without configuring or<sentry dsn>
to enable and configure with dsn beforehand,false
to disable (default)sentryLevel
- set minimum level to log to sentry (defaultwarn
)
cosmas
defines some pino serializers on its own
error
- logsmessage
,code
,stack
anddata
fieldsprocessEnv
- logsNODE_PATH
andNODE_ENV
req
- logsbody
,query
,url
,method
,headers.x-deviceid
,headers.authorization
,headers.user-agent
and omitspassword
andpasswordCheck
frombody
andquery
res
- logsout
,time
Cosmas uses some object keys for its own purposes. Those keys should not be used in data you send to log functions as they may be overwritten by Cosmas. Those keys are:
cosmas.loggerName
- used for the name of loggercosmas.pkgVersion
- used for the version ofcosmas
message
- used for the log message text
This problem is caused by a way VS Code handles console output. Therefore it appears in Winston and pino (underlying library of cosmas) as well.
However, it can be easily solved by adding eithe
"console": "integratedTerminal",
or
"outputCapture": "std"
to the debug configuration in your launch.json
file.