Jibo Log - Centralized logging facility
A module to centralize and control (and log to syslog or files) all
logging messages. Use this everywhere instead of console.log and
friends.
To use:
const {Log} = require('jibo-log');
const log = new Log('my-namespace');
log.debug('this is a debug');
log.info('this is an info');
log.warn('this is a warning');
log.error('this is an error');
Use log.debug, log.info, log.warn, log.error, instead of
console.log and friends.
log.log is also available, but it's just an alias for log.debug and
is there mainly for compatibility with the console object.
You specify a string to act as the name space of your log messages in
the new Log() constructor call. The name space will appear in front
of all your log messages. Each name space can be configured to show or
discard messages above/below a certain level, and separately for each
output channel (i.e. console, syslog, or file). jibo-log creates a
hierarchy of namespaces, separated by slashes, and a lower-level namespace
inherits the configuration of its closest ancestor, and may override that
configuration.
The level order is debug < info < warn < error. By default
debug messages are not printed to the syslog or console, but info and
above are.
Syslog messages
By default, syslog messages are enabled at the info level. However, note
that they will only truly be turned on if and only if the current
process's platform is linux and architecture is arm.
Error logging helper
log.iferr(err, [message])
A common JavaScript (and especially Node.js) convention is to indicate
an error condition as the first argument in a callback (usually named
err by convention). Frequently you want to log that such errors
happened, but many times it doesn't affect your program flow because
you still need to call some callback that you were given and are just
going to pass the error upward.
log.iferr() prints your message (at the error level) only if
err is truthy. Your message is followed by err stringified.
Use this:
log.iferr(err, 'error happened');
Instead of this:
if (err) {
log.error('error happened', err);
}
Your code will be more readable (and you can save a bunch of typing).
Logging uncaught exceptions
jibo-log registers a listener for uncaughtExceptions so they can
be logged. It will log the details of the exception and then re-throw
the exception. It also registers a listener for unhandled promise
errors.
It seems that handling uncaughtExceptions can sometimes confuse the stack information about where the original exception happened. If you are debugging such an issue you can temporarily disable this functionality:
Log.logUncaughtExceptions = false;
Log.logUnhandledRejections = false;
And the handlers will be uninstalled which may hopefully give you better information to help track down the problem. Please remove this call once you've resolved the issue or uncaught exceptions will not be logged and might be missed.
File names and line numbers
By default, logging to the console through jibo-log behaves the same way
as logging directly to the global console. It will include a stack trace only
if an Error object is called with log.error. If you are interested in seeing
the filename and line number for every logging call (even debug, info, and
warn calls), you can enable this feature by passing JSON configuration
to Log (see the next section) with outputs.console.outputFileAndLine set
to true.
Logging configuration
Logging can be configured statically using a JSON file in the following format:
{
"logUncaughtExceptions": true,
"logUnhandledRejections": true,
"outputs": {
"console": {
"outputFileAndLine": false
},
"syslog": {
"port": 514,
"target": "127.0.0.1"
},
"file": {
"filename": "",
"mode": "overwrite"
}
},
"namespaces": {
"": {
"console": "info",
"syslog": "info"
},
"Be.Radio.RadioPlayer": {
"console": "debug"
}
}
}
Once you've read the JSON file into an object of this format, or created one
manually, you can pass it to the static loadConfig method on Log before
performing any logging:
const fs = require('fs');
const {Log} = require('jibo-log');
Log.loadConfig(fs.readFileSync('/path/to/logging-config.json'));
In the skills-service-manager, the default configuration is specified
separately for each robot mode, and can be modified per mode on a robot, in
the four files found in /usr/local/etc/jibo-ssm.
For jibo-cli, a default config file is created at .jibo/t.logging.json
in your machine's home directory. If that file does not exist, run
jibo robot-list once, and it will be created. When using Jibo's
simulator, this file will be used. To use this configuration on robot,
copy this file to the robot and adjust permissions with the following:
scp t.logging.json root@{robot-ip}:/var/jibo/
ssh root@{robot-ip} "chmod 755 /var/jibo/t.logging.json"
If the permissions are not set correctly, you can get this console warning:
Could not load logging config file /var/jibo/t.logging.json
EACCES: permission denied, open '/var/jibo/t.logging.json'