Skip to content

Commit

Permalink
[doc] Update README.md for 0.2.9
Browse files Browse the repository at this point in the history
  • Loading branch information
indexzero committed May 20, 2011
1 parent 6e546dc commit 5d584fb
Showing 1 changed file with 105 additions and 47 deletions.
152 changes: 105 additions & 47 deletions README.md
Expand Up @@ -5,14 +5,14 @@ A multi-transport async logging library for node.js. <span style="font-size:28px
## Installation

### Installing npm (node package manager)
<pre>
```
curl http://npmjs.org/install.sh | sh
</pre>
```

### Installing winston
<pre>
```
[sudo] npm install winston
</pre>
```

## Motivation
Winston is designed to be a simple and universal logging library with support for multiple transports. A transport is essentially a storage device for your logs. Each instance of a winston logger can have multiple transports configured at different levels. For example, one may want error logs to be stored in a persistent remote location (like a database), but all logs output to the console or a local file.
Expand All @@ -24,34 +24,38 @@ There are two different ways to use winston: directly via the default logger, or

### Using the Default Logger
The default logger is accessible through the winston module directly. Any method that you could call on an instance of a logger is available on the default logger:
<pre>

``` js
var winston = require('winston');

winston.log('info', 'Hello distributed log files!');
winston.info('Hello again distributed logs');
</pre>
```

By default, only the Console transport is set on the default logger. You can add or remove transports via the add() and remove() methods:
<pre>

``` js
winston.add(winston.transports.File, { filename: 'somefile.log' });
winston.remove(winston.transports.Console);
</pre>
```

For more documenation about working with each individual transport supported by Winston see the "Working with Transports" section below.

### Instantiating your own Logger
If you would prefer to manage the object lifetime of loggers you are free to instantiate them yourself:
<pre>

``` js
var logger = new (winston.Logger)({
transports: [
new (winston.transports.Console)(),
new (winston.transports.File)({ filename: 'somefile.log' })
]
});
</pre>
```

You can work with this logger in the same way that you work with the default logger:
<pre>

``` js
//
// Logging
//
Expand All @@ -64,11 +68,12 @@ You can work with this logger in the same way that you work with the default log
//
logger.add(winston.transports.File)
.remove(winston.transports.Console);
</pre>
```

### Using Logging Levels
Setting the level for your logging message can be accomplished in one of two ways. You can pass a string representing the logging level to the log() method or use the level specified methods defined on every winston Logger.
<pre>

``` js
//
// Any logger instance
//
Expand All @@ -80,10 +85,11 @@ Setting the level for your logging message can be accomplished in one of two way
//
winston.log('info', '127.0.0.1 - there's no place like home');
winston.info('127.0.0.1 - there's no place like home');
</pre>
```

As of 0.2.0, winston supports customizable logging levels, defaulting to [npm][0] style logging levels. Changing logging levels is easy:
<pre>

``` js
//
// Change levels on the default winston logger
//
Expand All @@ -93,21 +99,21 @@ As of 0.2.0, winston supports customizable logging levels, defaulting to [npm][0
// Change levels on an instance of a logger
//
logger.setLevels(winston.config.syslog.levels);
</pre>
```

Calling `.setLevels` on a logger will remove all of the previous helper methods for the old levels and define helper methods for the new levels. Thus, you should be careful about the logging statements you use when changing levels. For example, if you ran this code after changing to the syslog levels:

<pre>
``` js
//
// Logger does not have 'silly' defined since that level is not in the syslog levels
//
logger.silly('some silly message');
</pre>
```

### Using Custom Logging Levels
In addition to the predefined `npm` and `syslog` levels available in Winston, you can also choose to define your own:

<pre>
``` js
var myCustomLevels = {
levels: {
foo: 0,
Expand All @@ -125,31 +131,33 @@ In addition to the predefined `npm` and `syslog` levels available in Winston, yo

var customLevelLogger = new (winston.Logger)({ levels: myCustomLevels.levels });
customLevelLogger.foobar('some foobar level-ed message');
</pre>
```

Although there is slight repetition in this data structure, it enables simple encapsulation if you not to have colors. If you do wish to have colors, in addition to passing the levels to the Logger itself, you must make winston aware of them:

<pre>
``` js
//
// Make winston aware of these colors
//
winston.addColors(myCustomLevels.colors);
</pre>
```

This enables transports with the 'colorize' option set to appropriately color the output of custom levels.

### Events and Callbacks in Winston
Each instance of winston.Logger is also an instance of an [EventEmitter][1]. A log event will be raised each time a transport successfully logs a message:
<pre>

``` js
logger.on('log', function (transport, level, msg, meta) {
// [msg] and [meta] have now been logged at [level] to [transport]
});

logger.info('CHILL WINSTON!', { seriously: true });
</pre>
```

It is also worth mentioning that the logger also emits an 'error' event which you should handle or suppress if you don't want unhandled exceptions:
<pre>

``` js
//
// Handle errors
//
Expand All @@ -159,20 +167,22 @@ It is also worth mentioning that the logger also emits an 'error' event which yo
// Or just suppress them.
//
logger.emitErrs = false;
</pre>
```

Every logging method described in the previous section also takes an optional callback which will be called only when all of the transports have logged the specified message.
<pre>

``` js
logger.info('CHILL WINSTON!', { seriously: true }, function (err, level, msg, meta) {
// [msg] and [meta] have now been logged at [level] to **every** transport.
});
</pre>
```

### Logging with Metadata
In addition to logging string messages, winston will also optionally log additional JSON metadata objects. Adding metadata is simple:
<pre>

``` js
winston.log('info', 'Test Log Message', { anything: 'This is metadata' });
</pre>
```

The way these objects is stored varies from transport to transport (to best support the storage mechanisms offered). Here's a quick summary of how each transports handles metadata:

Expand All @@ -182,7 +192,8 @@ The way these objects is stored varies from transport to transport (to best supp

### Profiling with Winston
In addition to logging messages and metadata, winston also has a simple profiling mechanism implemented for any logger:
<pre>

``` js
//
// Start profile of 'test'
// Remark: Consider using Date.now() with async operations
Expand All @@ -196,14 +207,57 @@ In addition to logging messages and metadata, winston also has a simple profilin
//
winston.profile('test');
}, 1000);
</pre>
```

All profile messages are set to the 'info' by default and both message and metadata are optional There are no plans in the Roadmap to make this configurable, but I'm open to suggestions / issues.

### Using winston in a CLI tool
A common use-case for logging is output to a CLI tool. Winston has a special helper method which will pretty print output from your CLI tool. Here's an example from the [require-analyzer][15] written by [Nodejitsu][5]:

```
info: require-analyzer starting in /Users/Charlie/Nodejitsu/require-analyzer
info: Found existing dependencies
data: {
data: colors: '0.x.x',
data: eyes: '0.1.x',
data: findit: '0.0.x',
data: npm: '1.0.x',
data: optimist: '0.2.x',
data: semver: '1.0.x',
data: winston: '0.2.x'
data: }
info: Analyzing dependencies...
info: Done analyzing raw dependencies
info: Retrieved packages from npm
warn: No additional dependencies found
```

Configuring output for this style is easy, just use the `.cli()` method on `winston` or an instance of `winston.Logger`:

``` js
var winston = require('winston');

//
// Configure CLI output on the default logger
//
winston.cli();

//
// Configure CLI on an instance of winston.Logger
//
var logger = new winston.Logger({
transports: [
new (winston.transports.Console)()
]
});

logger.cli();
```

### Extending another object with Logging functionality
Often in a given code base with lots of Loggers it is useful to add logging methods a different object so that these methods can be called with less syntax. Winston exposes this functionality via the 'extend' method:

<pre>
``` js
var myObject = {};

logger.extend(myObject);
Expand All @@ -212,7 +266,7 @@ Often in a given code base with lots of Loggers it is useful to add logging meth
// You can now call logger methods on 'myObject'
//
myObject.info('127.0.0.1 - there's no place like home');
</pre>
```
## Working with Transports
Right now there are four transports supported by winston core. If you have a transport you would like to add either open an issue or fork and submit a pull request. Commits are welcome, but I'll give you extra street cred if you __add tests too :D__
Expand All @@ -222,9 +276,9 @@ Right now there are four transports supported by winston core. If you have a tra
3. __Loggly:__ Log to Logging-as-a-Service platform Loggly

### Console Transport
<pre>
``` js
winston.add(winston.transports.Console, options)
</pre>
```

The Console transport takes two simple options:

Expand All @@ -235,9 +289,9 @@ The Console transport takes two simple options:
*Metadata:* Logged via util.inspect(meta);

### File Transport
<pre>
``` js
winston.add(winston.transports.File, options)
</pre>
```

The File transport should really be the 'Stream' transport since it will accept any [WritableStream][14]. It is named such because it will also accept filenames via the 'filename' option:

Expand All @@ -250,9 +304,9 @@ The File transport should really be the 'Stream' transport since it will accept
*Metadata:* Logged via util.inspect(meta);

### Loggly Transport
<pre>
``` js
winston.add(winston.transports.Loggly, options);
</pre>
```

The Loggly transport is based on [Nodejitsu's][5] [node-loggly][6] implementation of the [Loggly][7] API. If you haven't heard of Loggly before, you should probably read their [value proposition][8]. The Loggly transport takes the following options. Either 'inputToken' or 'inputName' is required:

Expand All @@ -266,7 +320,8 @@ The Loggly transport is based on [Nodejitsu's][5] [node-loggly][6] implementatio

### Adding Custom Transports
Adding a custom transport (say for one of the datastore on the Roadmap) is actually pretty easy. All you need to do is accept a couple of options, set a name, implement a log() method, and add it to the set of transports exposed by winston.
<pre>

``` js
var winston = require('winston');
var CustomLogger = winston.transports.CustomerLogger = function (options) {
Expand All @@ -292,7 +347,7 @@ Adding a custom transport (say for one of the datastore on the Roadmap) is actua
//
callback(null, true);
};
</pre>
```

## What's Next?
Winston is stable and under active development. It is supported by and used at [Nodejitsu][5].
Expand All @@ -313,7 +368,8 @@ Winston is stable and under active development. It is supported by and used at [
## Run Tests
All of the winston tests are written in [vows][13], and cover all of the use cases described above. You will need to add valid credentials for the various transports included to test/test-config.json before running tests:
<pre>
``` js
{
"transports": {
"loggly": {
Expand All @@ -326,12 +382,13 @@ All of the winston tests are written in [vows][13], and cover all of the use cas
}
}
}
</pre>
```
Once you have valid configuration and credentials you can run tests with [vows][13]:
<pre>
```
vows test/*-test.js --spec
</pre>
```
#### Author: [Charlie Robbins](http://twitter.com/indexzero)
#### Contributors: [Matthew Bergman](http://github.com/fotoverite)
Expand All @@ -350,4 +407,5 @@ Once you have valid configuration and credentials you can run tests with [vows][
[11]: https://github.com/jbrisbin/node-rlog
[12]: https://github.com/feisty/BigBrother
[13]: http://vowsjs.org
[14]: http://nodejs.org/docs/v0.3.5/api/streams.html#writable_Stream
[14]: http://nodejs.org/docs/v0.3.5/api/streams.html#writable_Stream
[15]: http://github.com/nodejitsu/require-analyzer

0 comments on commit 5d584fb

Please sign in to comment.