Cap'n Log: the official RocketCode Logger
Flexible and externally-configurable and redactable logging engine with these great features:
- Finely configurable, to the method level. Different methods can have different logging levels.
- Easily mark text in your logs as redactable with
%<
and%>
so they can be excluded from logs by enabling a configuration. - Logs can be output in several formats:
text
,ansi-text
(text coloured for readability), andjson
, and can be routed to transportsconsole
,stream
,file
orgroup
(any combination of transports). - No external dependencies.
Configuration
This doesn't have a configuration file per se but a configuration object. This would normally be a part of you project's larger configuration file. If your file were in, for example, JSON or YAML format, it could be parsed into an object this would accept that configuration and use its part.
All configurations are under debug.logging
.
Sections
defaults
(required)
This section specifies the default values for modules, methods, and paths that are not listed in this configuration. There are two configs here:
-
debug.logging.defaults.transport
the name of the default transport -
debug.logging.defaults.level
the default log level
transports
(optional)
(Default: logging ansi text to console)
This section specifies the configuration for each type of transport. Transports have these members:
-
name
the name of the transport. -
type
the type of transport. Defaultconsole
. Right now onlyconsole
is supported. Future versions may includefile
,stream
,http-post
,mq
, etc butconsole
will always be the default. -
format
format for output.json
,text
, oransi-text
. Default:ansi-text
. Thetext
format is plain text but theansi-text
format uses ansi codes to colour-highlight text in a terminal. JSON outputs one complete JSON object per log entry. -
showSensitive
whether or not to show sensitive information. If this is set tofalse
, it'll replace all the information marked sensitive with[redacted]
. Sensitive text may be highlighed ifshowSensitive
is set totrue
. If usingansi-text
format, sensitive text will be underlined. Default value isfalse
.
modules
(optional)
This section provides specific configurations for modules, methods, and paths. By default, this section is an empty array, which implies everything logged using the default settings.
Each element in the modules
array is an object with:
-
name
the name of the module -
transport
(optional) the transport to use for this module, if you want to use a different transport from that specified in thedefaults
section. -
level
(optional) the log level to use for this module, if you wan to use a different level from that specified in thedefaults
section. -
methods
(optional) method-specific configurations, if you want to give single methods different logging levels or transports. In this context, a method can be a JavaScript method or an HTTP method. Themethods
array has a similar format, except if it's an HTTP method, it'll also have apaths
config, which can be used to give single paths different logging levels or transports.
Usage
A simple example of loading the config and then logging in a method.
import logger from `capn-log`;
const MODULE = 'myModule';
// Set the configuration. The JSON.parse bit is just an example.
logger.config = JSON.parse(fs.readFileSync('configFile.json').toString());
function myMethod(param1, param2) {
const log = logger(MODULE, myModule);
// the %< and %> mark the second parameter as sensitive
log.debug('Called with params (%s, %<%s%>)', param1, param2);
}
APIs
logger.config
setter that sets the logger configuration
Before this setter is called, it's assumed that all logs at level info
or lower should be written to console
in ansi-text
format, with text marked as sensitive redacted.
logger.config = JSON.parse(
fs.readFileSync('configFile.json').toString()
);
logger(module, method, [path])
gets a logger
Creates or gets a logger for a module
and method
. A method can be a JavaScript method or an HTTP method. If method
is an HTTP method, include a third parameter for path
. method
can be a named (i.e. not anonymous) function or a string
.
function myFunction() {
const log = logger('myModule', myFunction);
// [stuff]
}
function myFunction() {
const log = logger('myModule', 'myFunction');
// [stuff]
}
router.get('/mypath', (req, res, next) => {
const log = logger('myRoute', 'GET', '/mypath');
// [stuff]
});
fault
, error
, warn
, info
, verbose
, debug
, trace
Log to the different levels. The logs are filtered based on level and the level is indicated in the log. The parameters are similar to util.format
(and, hence, console.log
) with a few differences:
-
%<
and%>
-- mark a section of text as sensitive. Anything between these marks will be redacted unlessshowSensitive
is set totrue
for the transport. -
%s
substitute astring
parameter here -
%d
substitute anumber
parameter here -
%%
print%
function myFunction() {
const log = logger('myModule', myFunction);
log.info('Called with %s at %d%%', 'string param', 100);
// '[ info] myModule.myFunction: Called with string param at 100%'
}
Style guide
This section is a purely a suggestion. This logging engine will not break if you choose not to follow these conventions, nor will it enforce them, but they will allow a more usable log.
- Expect production apps to have their maximum logging level set to
info
. Excessive logging toinfo
and lower (fault
is lowest,trace
is highest) will affect the performance of production applications and make the logs less useful. - Each log entry to
verbose
or higher should fit into a single line.-
fault
,error
, andwarn
lines should be a single log with additional information added withinfo
log. - Each
info
log should be a single line, but many info logs can be used together to explain a single issue. -
verbose
is typically of development and debugging interest.
-
-
verbose
andtrace
logs can take multiple lines, such as stringifications of complex objects - If you choose to use this logging engine in a package, such as
npm
module names should be prefixed<package_name>/<module>
Log Levels
Level | Name | Description |
---|---|---|
0 | FAULT |
Application errors, especially those that could cause the application to exit in error, such as misconfiguration or unhandled exceptions. |
1 | ERROR |
Runtime errors that would make a task impossible, such as invalid inputs or downstream errors. |
2 | WARN |
Conditions that don't look right and could indicate or cause problems. |
3 | INFO |
Informational logging that would be useful to have in production. |
4 | VERBOSE |
Additional logging that would be useful for diagnosing problems with production or development apps, but not as noisy as DEBUG . |
5 | DEBUG |
Detailed information about objects, useful for solving bugs |
6 | TRACE |
Most detailed information, and comes with stack traces. |