stdlog

A Node.js log utility that logs messages to stderr by default.

npm install stdlog
10 downloads in the last day
105 downloads in the last week
349 downloads in the last month

stdlog

A Node.js log utility that logs messages to stderr by default.

Overview

The stdlog package logs messages to stderr using five log levels: ERROR, WARN, INFO, DEBUG, and TRACE. An alternate stream or file can be used as well.

The name of the default log (the one returned when requiring the stdlog package) is based on the name of the requiring module's package or, if not part of a package, the basename of the requiring module. The name, level, output, and format of each log can be configured.

Child logs can also be created. Each child inherits the properties of the parent log. Child logs dynamically inherit the properties of the parent log unless overridden in the child log.

Installation

Add stdlog to your package.json dependencies:

"dependencies": {
    ...,
    "stdlog": "0.0.x"
}

Install the dependencies:

$ npm install

Require and use the log:

var log = require('stdlog');
log.error('An error occurred');

Logging

Log Levels

There are five log levels. Each level has a numeric value and a string name. The numeric value and the string name can be used interchangeably. The name is case-insensitive when used in the setLevel method or when specified as the level property in an options object.

  1. ERROR
  2. WARN
  3. INFO (this is the default log level)
  4. DEBUG
  5. TRACE

In addition, the log level having the numeric value zero (or the string name NONE) disables all logging.

Log Methods

There are five corresponding log methods:

log.error(message [,args]);
log.warn(message [,args]);
log.info(message [,args]);
log.debug(message [,args]);
log.trace(message [,args]);

Each of these takes a message string (or an object, such as an Error) as the first parameter. The message can contain optional placeholders that are replaced by the values of any additional arguments.

  • If the first argument is an object, then that object is converted to a string and becomes the error message.

  • If the arguments following the message parameter are primitive values, then these values are accessed using numerical placeholders. For example, {0} is the first argument after the message parameter, {1} is the second argument after the message parameter, and so on.

  • If the first argument following the message parameter is an array, then the numeric placeholders are array index values (e.g., {0}, {1}, etc.).

  • If the first argument after the message argument is an object, then the placeholders are the object property names (e.g., {code}).

See Also: strformat

Configuration

There are four configuration options: name, level, output, and format. Each of these has a default value and can be set using a configuration method or by setting an environment variable.

Log Name

The default log name comes from the package name of the parent module (the module calling require). If no package.json file is found, then the basename of the parent module is used. The log name can be set using the setName({String}) method or by setting the STDLOG_NAME environment variable.

Regardless of how the name is specified, only the basename of the string is used as the log name. By only using the basename, the log name can be set from the module.filename string. For example, if the module filename is /opt/server/lib/handler.js, then calling setName(module.filename) results in a log name of handler.

Log Level

The default log level is INFO. The log level can be set using the setLevel({Number|String}) method or by setting the STDLOG_LEVEL environment variable.

The value of the argument or the environment variable can be either a number, the string representation of a number, or the case-insensitive log level name.

Note that every log instance exports the levels as constants. Therefore, calling log.setLevel(log.DEBUG) has the same result as calling log.setLevel('debug').

Log Output

The default log output is stderr. The log output can be set by calling the setOutput({Object|String}) method or by setting the STDLOG_OUTPUT environment variable.

If the argument is an object, then is must provide a write function.

If the argument is a string, then the following rules apply:

  1. The string stderr is interpreted as the stderr stream.
  2. The string stdout is interpreted as the stdout stream.
  3. Otherwise, the string is the pathname of a log file subject to the following:
    • A string beginning with a dot is resolved against the current working directory.
    • A string not beginning with a dot is resolved against the package or module directory of the parent module (the one requiring the stdlog package).

In the case of a log file, a file having the resolved name is created if it does not exist. Any intermediate directories (e.g., logs) are created using the mkdirp utility. Log messages are then appended to that file.

Log Format

The default log format is

{timestamp} {level} [{pid}] {id}: {message}

The log format can be set by calling the setFormat({String}) method or by setting the STDLOG_FORMAT environment variable.

The following placeholders are available for use in the log format specification:

  • {timestamp} - The ISO 8601 timestamp string using the UTC timezone.
  • {level} - The log level name string (e.g., ERROR).
  • {pid} - The numeric process id.
  • {id} - The log id. This is a dot-separated sequence of log names from the root log down through each child log and terminating with the current log.
  • {name} - The log name. This is the only placeholder not used in the default format.
  • {message} - The log message. Embedded newline characters are prefixed with a greater-than sign followed by a space so that multi-line messages are easily identified and parsed.

Log Options

Any or all of these options can be configured at once using the setOptions({Object}) method:

log.setOptions({
    name: 'server',
    level: 'trace',
    output: './server.log',
    format: '{level}: {message}'
});

Log Exceptions

An invalid value, such as an incorrect log level, results in an exception being thrown. Exceptions are thrown by the setOptions method as well as by any of the individual configuration methods.

Inheritance

A child log instance is created from a parent log instance by calling the create({Object|String}) method. A child log inherits the properties of the parent log. If a property is changed in the parent log after the child log has been created, then the changed property will also be reflected in the child log. Any property can be overridden in the child log and will shadow that property from the parent log.

The {name} placeholder in the log format is replaced by the names of all ancestor logs as well as the name of the child log. Each name is separated from the previous name with a dot.

In the following example, the root log is called 'parent'. A child log called 'child' is then created.

var parent = require('stdlog');
parent.setName('parent');
var child = parent.create();
child.setName('child');
child.info('informational message');

The output of this example is as follows:

2012-09-20T14:50:06.930Z INFO [6169] parent.child: informational message

The primary purpose of log inheritance is for identifying the source of log messages down to submodules. Therefore, the create method offers three convenience features with respect to its argument:

  1. If the argument is a string, then it is passed to the setName method of the child log after the child log is created.
  2. If the argument is a module (i.e., an object having the filename property), then the module's filename property is passed to the setName method of the child log after the child log is created.
  3. If the argument is an options object (i.e., an object not having the filename property), then it is passed to the setOptions method of the child log after the child log is created.

Therefore, the following constructs are all equivalent:

child = parent.create(module.filename);
child = parent.create(module); /* this is the most convenient */
child = parent.create({name: module.filename});

Summary

Methods

create({Object|String})
setOptions({Object|String})
setName({String})
setLevel({Number|String}
setOutput({Object|String}
setFormat({String})

Motivation

The following three points motivated the creation and design of the stderr utility:

  1. The console facility writes some messages to stdout and others to stderr. The UNIX convention is for stdout to be used for process output and stderr to be used for sideband information. The stdlog package logs all messages to stderr by default.

  2. There are many other logging packages available. Some provide interesting color coding, others offer sophisticated interfaces to network log aggregators. This utility is a simple stream-based logger with the ability of appending messages to a log file.

  3. The UNIX syslog facility offers more severity levels. This module is not intended for system logging so levels such as CRITICAL are of lesser value to a server operating as a guest process on an operating system. The five levels of ERROR, WARN, INFO, DEBUG, and TRACE offer a reasonable compromise.

Performance

The decision on whether or not to log a messages based on the current log level is made before any string formatting takes place. Therefore, log statements can be left in the code with minimal performance impact.

License

(The MIT License)

Copyright (c) 2012 Frank Hellwig

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

npm loves you