X-Git-Url: https://git.r.bdr.sh/rbdr/cologne/blobdiff_plain/08ce17a6d30a2f40459a4eecc7db20e1931046f9..9c978f93eb12706510bdb070b4e6e9cff4036b43:/README.md diff --git a/README.md b/README.md index 618bae4..6772648 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,289 @@ -# cobalt.js # +# Cologne -Experiments with cobalt in javascript. +Cologne is a logger multiplexer that uses a JSON log format inspired in gelf. +It can be instantiated with several loggers, or they can be changed after +the fact. + +## Usage + +Install from npm + +``` +$ npm install --save cologne +``` + +Create an instance + +```javascript +const { Cologne, Loggers, Formatters } = require('cologne'); + +const co = new Cologne({ + from: 'Special Worker Logger', + loggers: [ + new Loggers.Console({ + formatter: new Formatters.Token({ + formatString: '[{{_timestamp}}]{{_from}}: {{message}}' + }) + }) + ] +}); +``` + +This example would create a cologne instance with a console logger that +uses a Token formatter. (More on loggers and formatters below.); + +## Quick API Reference + +* **addLogger(logger)**: Adds a logger to the cologne instance. +* **removeLogger(logger)**: Removes a logger from the cologne instance. +* **buildLog(item, level, [meta])**: Generates a cologne log object as if you had + logged an item (it will do this automatically when you log anything.) + level defaults to 6. You can optionally send it an object to extend + the object with. +* **log, info, notice, warn, error**: Generates a log object with the + appropriate severity level and sends it to all loggers. + +## Loggers + +Cologne loggers are any object that responds to the `#log()` method. +This methoud should be able to receive any number of arguments and +log them independently. Similar to how you can send multiple arguments +to the browser console. + +`#log()` will receive any number of `Cologne Log Objects`. For a detailed +reference of this format, see further below. + +Cologne includes two loggers out of the box: + +* `Loggers.Console` logs to the JS console +* `Loggers.File` appends to a file + +### Loggers.Console + +This logger communicates with the Javascript console. It uses the log level +to trigger the appropriate method, so `error` logs would go to stderr +as expected when calling `console.error`. + +This logger can be sent a `formatter`, which is an object that responds +to the `#format()` method: it should receive a cologne log object and respond +with a string. + +```javascript +new Loggers.Console({ + formatter : new Formatters.Token({ + formatString: '[{{_timestamp}}]{{_from}}: {{message}}' + }) +}); +``` + +### Loggers.File + +This logger opens a writable stream to a file, to which it will append +everything. Like the Console logger it supports a `formatter` property +that will respond to the `#format()` method. + +It MUST include a `file` property on initialization, otherwise it will throw +an exception. + +```javascript +new Loggers.File({ + file: '/var/log/server_log.log', + formatter : new Formatters.Token({ + formatString: '[{{_ansi:_level}}{{_timestamp}}{{_ansi:reset}}]{{_from}}: {{message}}' + }) +}); +``` + +### More Loggers? + +We're working on a socket logger. It's separate so you don't have to +install the socket dependencies if you don't want to. + +You can build your own logger easily for any method of transport you find +necessary (e.g. mail, database, twitter, etc). Any object that responds +to `#log()` is a valid logger: + +```javascript +// A valid, very minimalistic logger +const simpleLogger = { + log: function(...logs) { + + for (const log of logs) { + this._doSomeMagic(logs); + } + }, + + _doSomeMagic: function(log) { + + console.log(log + "... but magical!"); + } +}; + +logger.addLogger(simpleLogger); +``` + + +## Formatters + +Cologne doesn't need formatters to work, and in fact they're optional in +the included loggers. But if you would like to make your logs prettier, +then you can use one of the included formatters or roll your own. + +Formatters are objects that respond to the `#format()` method. It will +receive a single cologne log object (see fields it includes below), and +it should return a string. + +We include some formatters so you can get running real quicklike: + +* `Formatters.Simple` a simple predefined formatter +* `Formatters.Token` a formatter that lets you define format + strings that it will use to build your final log. + +### Formatters.Simple + +This is the lazy formatter, it just outputs the string in the following +format: + +``` +'[{{_timestamp}}][{{_levelString}}]{{_from}}: {{message}}' +``` + +Where `_timestamp` is converted to ISO. + +#### Accepted Options + +* `colorize` : whether or not to add color. False by default. + +By default we don't colorize the output, but if you enable the flag this +formatter will add a bit of color in the level string. Red for error, crit, +alert, and emerg; yellow for warn; blue for info; green for debug; and white +for everything else. + +#### Usage + +```javascript +new Formatters.Simple({ + colorize: true +}); +``` + +### Example Output + +``` +co.log("hello world"); +// -> [2016-01-21T05:50:36.505Z][INFO] Server Logger: hello world +``` + +### Formatters.Token + +The token formatter lets you build strings with simple tokens. When +instantiating, you can specify a `formatString` to interpolate +properties from the logObject. The default version looks for tokens +inside double curly braces like `{{message}}` or `{{_level}}`. If +you don't like it, you can specify your own. + +#### Accepted Options + +* `formatString` : The string used to replace. Defaults to `"{{message}}"` +* `replaceRule` : The regex rule to use for replacement of tokens in the + formatString. Defaults to `/{{(.*?)}}/g` +* `isoDate` : Whether or not to convert `_timestamp` to ISO + date. Defaults to true. Otherwise it'll use the raw timestamp. + +#### Usage + +```javascript +new Formatters.Token({ + formatString: '[{{_timestamp}}]{{_from}}: {{message}}' +}); +``` + +#### ANSI tokens + +If you want to add color to your logs, you can use the special \_ansi +token. It has several options which you can call like `{{_ansi:red}}` +and `{{_ansi:reset}}`. Here's a list of all the ansi stuff you can use: + +* `bold`: makes text bold +* `italics`: makes text italics +* `underline`: makes text underlined +* `inverse`: inverts foreground and background +* `strikethrough`: strikethrough text +* `bold_off`, `italics_off`, `underline_off`, `inverse_off`, and + `strikethrough_off`: turn off the specified effect. +* `black`, `red`, `green`, `yellow`, `blue`, `magenta`, `cyan`, `white`, + and `default`: change the foreground color of your text. +* `black_bg`, `red_bg`, `green_bg`, `yellow_bg`, `blue_bg`, `magenta_bg`, + `cyan_bg`, `white_bg`, and `default_bg`: change the background color of your + text. +* `reset`: makes everything normal again. +* `_level`: this is a special code that will set a color depending on + the level of the log: debug gets green, info and notice blue, warn is + yellow, and anything worse is red. + +### More Formatters? + +You can create your own formatters by creating an object that responds +to the `#format()` method, knows how to handle cologne log objects and +returns a string. + +Here's an example of a logger that surrounds a log with sparkles: + +```javascript +const sparkleFormatter = { + format: function(logObject) { + + return `✨${logObject.message}✨`; + } +} + +logger.addLogger(new Loggers.Console({ + formatter: sparkleFormatter +})); +``` + +## The Cologne Log Format + +The cologne log format is a JSON based log format, based on the cobalt +log format, which is in turn based on Graylog's GELF. However, where GELF +treats all internal fields without a prefix, and all user fields with a +prefix, we do it backwards so it's easier to extend the object with +metadata from existing objects. + +You could try to build it on your own, but you can use `#buildLog()` +to build it without logging. + +### Fields + +* **\_timestamp** : A bigint timestamp in nanoseconds +* **\_cologneLog** : This is how we know if the log is already + formatted and ready to go. This field is a string containing the + version of cologne log format it's using. It's `2.0.0` right now. +* **\_from**: The sender of the log (Defaults to Generic Cologne Logger) +* **\_level**: The level of the log (Defaults to 6) +* **\_levelString**: The string corresponding to the log level (e.g. 7 -> + debug, 3 -> error, 0 -> emerg) + +### A word on Log Levels + +The log levels in cologne correspond to the syslog levels, and the +levelStrings correspond to the priority keywords: + +* `0 -> emerg` +* `1 -> alert` +* `2 -> crit` +* `3 -> error` +* `4 -> warning` +* `5 -> notice` +* `6 -> info` +* `7 -> debug` + +This is useful when deciding how to log. You could even have a logger +filter out unnecessary levels (eg. If you have a reporting logger that +only reports error or worse.) + +## Further Improvements + +* Improve the API for buildLog +* More loggers & formatters (will not be distributed in core cologne) +* Improve tests