X-Git-Url: https://git.r.bdr.sh/rbdr/cologne/blobdiff_plain/57c44bcddcbdb267bcf39550d9b8b19ebfdc4a51..ae85c067634676251e812765c81adfdef8f85f9d:/README.md diff --git a/README.md b/README.md index 2b372f7..bf2ae2d 100644 --- a/README.md +++ b/README.md @@ -1,212 +1,300 @@ -# Cobalt # +# Cologne -Cobalt is a simple logger multiplexer that works with a JSON based format. -You can instantiate it with a set of loggers or add them later -(see API reference below). When logging anything, Cobalt will attempt to -generate an Object that conforms to the Cobalt Log Format Definition -(if required) and passes it to every logger it has by calling their `log` -method. +![https://david-dm.org/rbdr/cologne.svg][dependencies-shield] +![https://circleci.com/gh/rbdr/cologne.svg?style=shield][circle-ci-shield] -Example of instantiating a cobalt logger: +Cologne is a logger multiplexer that works mainly with a JSON format. It +can be instantiated with several loggers, or they can be changed after +the fact. + +## Usage + +Install from npm or add to your package.json: -In node: ``` -require('cobalt-log'); +$ npm install cologne ``` -In the browser just require the files. Then: +Create an instance: -``` -this.logger = new Cobalt.Console({ - from : "Breezi Client", - loggers : [ new Cobalt.Logger.JsConsole({ - formatter : Cobalt.Formatter.Token, - formatterOpts : { - formatString : "{{_from}}: {{message}}", - ansiColor : true - } - })] +```javascript +require('cologne'); + +let co = new Cologne({ + from: "Special Worker Logger", + loggers: [ + new Cologne.Logger.Console({ + formatter: new Cologne.Formatter.Token({ + formatString: '[{{_timestamp}}]{{_from}}: {{message}}' + }) + }) + ] }); ``` -This code will create an instance with a JsConsole logger that uses the -Token formatter (See loggers and formatters below). +This example would create a cologne instance with a console logger that +uses a Token formatter. (More on loggers and formatters below.); -Cobalt works in a browser or inside node, so feel free to use cobalt all -over! (Also, see the socket logger below for info on connecting cobalt -loggers) +## Do I need anything special? -## Quick API Reference ## +Node 4.0+ -* **addLogger(logger)**: Adds a logger to the cobalt instance. -* **removeLogger(logger)**: Removes a logger from the cobalt instance. -* **buildLog(item, level=7)**: Generates a cobalt log object as if you had - logged item (it will do this automatically when you log anything) -* **extendLog(object)**: Creates a dummy log object and extends it with - object. -* **buildSeparator**: Generates a cobalt log object that defines a separator +## 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. -* **separator()**: Generates a separator log object and sends it to all - loggers. -* **space(lines)**: Logs an empty string `lines` times -* **indent()**: Increases the indent level globally. -* **indent(callback)**: Increases the indent level for anything logged - from inside the callback. -* **outdent()/outdent(callback)**: Same as indent, but decreases indent level. -* **color()**: Changes the color globally. † -* **color(callback)**: Changes the color for anything logged from inside the - callback. † -* **now()**: Returns the current time in microseconds, using performance.now() - or process.hrtime() if available. If not, falls back to miliseconds. - -† Cobalt doesn't really care about formatting or colors, but it allows you -to set the `_color` property in the generated object. In the end, it's up to -the formatter to decide if it will use this property. However, this maintains -the old cobalt API and gives you flexibility in how you color your logs. - - -## Loggers ## - -Cobalt doesn't depend on any particular logger, and the loggers it expects -to receive is any object that responds to the log method. However, since it -would pass a JSON object instead of a string, this may result in unexpected -behavior for loggers that don't expect it. To ease the use of Cobalt with -existing loggers, cobalt includes a couple of loggers that you can use out -of the box. - - -### Cobalt.Logger.JsConsole ### - -This logger communicates the Javascript console present in web browsers or -node with cobalt. It uses the logLevel to trigger the appropriate method -(e.g. info vs warn vs error). You can also initialize it with a formatter, -to convert the log object to a string: +## 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 JS console. + +`#log()` will receive any number of `Cologne Log Objects`. To see what +this format includes, check further below. + +We include two loggers out of the box: + +* `Cologne.Logger.Console` logs to the JS console +* `Cologne.Logger.File` appends to a file + +### Cologne.Logger.Console + +This logger communicates 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 get a cologne log object and respond +with a string. + +```javascript +new Cologne.Logger.Console({ + formatter : new Cologne.Formatter.Token({ + formatString: '[{{_timestamp}}]{{_from}}: {{message}}' + }) +}); ``` - new Cobalt.Logger.JsConsole({ - formatter : Cobalt.Formatter.Token, - formatterOpts : { - formatString : "[{{_timestamp}}] {{message}} (@{{_from}})" - } - }) -``` -What this does is: it will trigger the method `format` on `formatter` -passing the `logObject` and `formatterOpts`. This means that a formatter is -any object that responds to `format(logObject, formatterOpts)`. It expects -a string to be returned. +### Cologne.Logger.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 won't +know where to write and you'll get an exception and be sad. + +```javascript +new Cologne.Logger.File({ + file: '/var/log/server_log.log', + formatter : new Cologne.Formatter.Token({ + formatString: '[{{_timestamp}}]{{_from}}: {{message}}' + }) +}); +``` -### Cobalt.Logger.Socket ### +### More Loggers? -This logger sends the log object to a socket using Socket.IO. It does not -format the output. To catch the log from the recipient, you have to listen -for the `log` event, and from there you can pass it to another Cobalt -instance or do whatever you want with it. +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. -### More Loggers? ### +If you need to, you can roll your own. Check info on the interfaces +below. 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(logObject)` is a valid logger: +to `#log()` is a valid logger: ```javascript // A valid, very minimalistic logger -var simpleLogger = { - log : function (logObject) { - console.log(logObject.message); +let simpleLogger = { + log : function () { + for (let logObject of arguments) { + this._doSomeMagic(logObject); + } + }, + + _doSomeMagic : function (logObject) { + console.log(logObject + "... but magical!"); } -} +}; logger.addLogger(simpleLogger); ``` -## Formatters ## -Cobalt itself makes no assumptions about the output of the logger and just -passes the object to every logger it has. However, it is clear that loggers -may want to manipulate this object. As shown in the JsConsole, a formatter -should respond to the format method and receive a `logObject` and an -`optsObject`. However, as this is not a core part of Cobalt, this is only a -recommendation (as this is the way the included JsConsole logger does it) -and it is up to the logger on how to transform the object it receives. -Cobalt includes a very simple formatter that works well in conjuction -with JsConsole. +## Formatters + +Cologne doesn't need formatters to work, and in fact they're optional in +the included workers. 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. That's all there is to it. + +We include some formatters so you can get running real quicklike: + +* `Cologne.Formatter.Simple` a simple predefined formatter +* `Cologne.Formatter.Token` a formatter that lets you define format + strings that it will use to build your final log. + +### Cologne.Formatter.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 bad, +yellow for warn, blue for info, and white for everything else. + +#### Usage + +```javascript +new Cologne.Formatter.Simple({ + colorize: true +}); +``` + +### Example Output + +``` +co.log("hello world"); +// -> [2016-01-21T05:50:36.505Z][INFO] Server Logger: hello world +``` -### Cobalt.Formatter.Token ### +### Cologne.Formatter.Token -The Token formatter is a very simple formatter that uses a formatString to -extract values from the log object and interpolate them in a string. +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. -#### Options #### +#### Accepted Options -* **formatString**: A string that defines the format of the output. It is a - string with double curly braces denoting fields. For example: - `"[{{_timestamp}}] {{message}} (@{{_from}})"` would attempt to extract the - \_timestamp, message and \_from fields to create a string similar to this: - `"[124896126491.123] Testing the logger (@Client Application)"` - (defaults to `"{{message}}"`) -* **ansiColor**: A boolean value, when `true` will output the string in ANSI - color depending on the severity level (defaults to `false`) +* `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. -### More Formatters? ### +#### Usage + +```javascript +new Cologne.Formatter.Token({ + formatString: '[{{_timestamp}}]{{_from}}: {{message}}' +}); +``` -As with loggers, cobalt itself does not worry about these things. However, -if you wish to make a formatter that is exchangable with Token, you just -need to create an object that responds to the`format(logObject, optionsObject)` -method: +#### 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 -// A valid, very minimalistic formatter var simpleFormatter = { - format : function (logObject, options) { - if (options.showDate) { - return "[" + Date(logObject._timeStamp) + "] " + logObject.message - } else { - return logObject.message; - } + format : function (logObject) { + return '✨' + logObject.message + '✨'; } } -logger.addLogger(new Cobalt.Logger.JsConsole({ - formatter: simpleFormatter, - formatterOpts : { - showDate : true - } +logger.addLogger(new Cologne.Logger.Console({ + formatter: simpleFormatter })); ``` -## The Cobalt Log Format ## +## The Cologne Log Format -The Cobalt Log (CoLog) format is a JSON based log format used with cobalt. -It is partly inspired in Greylog's GELF format, but with very notorious -differences. The CoLog requires a header with certain fields that allow -cobalt and its pieces to handle it. All header fields are prefixed with -an underscore. Other than those fields, you can put whatever you want in -the object; It's up to the loggers to make sense of the structure and -display it in a way that makes sense. +The cologne log format is a JSON based log format, based on the cobalt +log format, which is inturn 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. Besides, we'll probably write the +default keys automatically so you shouldn't have to do that extra work. -You can attempt to build this structure on your own, or let cobalt build it for -you. Any object you pass for logging will be converted. However, if you -build it on your own you have two options: The first one is use buildLog -to create a log object for "item" as if you had logged "item" or you can -use extendLog that will create a dummy log object and extends it with -whatever object you pass to it. +You could try to build it on your own, but you can use `#buildLog()` +to build it without logging. -### Required Fields ### +### Fields -* **_version** : The version of cobalt this is designed to work with -* **_timestamp** : A timestamp in microseconds. -* **_cobaltLog** [true] : Cobalt will check for the \_cobaltLog to decide if -transformation will happen or not. +* **\_timestamp** : A timestamp in miliseconds with fractions of a second + in the floating point area. +* **\_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 `1.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) -### Optional Fields ### +### A word on Log Levels -* **\_from**: The sender of the log (Defaults to Generic Cobalt Logger) -* **\_level**: The level of the log (Defaults to 7) -* **\_levelString**: The string corresponding to the log level (e.g. 7 -> - DEBUG, 3 -> ERROR, 0 -> CRIT) -* **\_indentLevel**: The indent level of the log -* **\_color**: The color of the log -* **\_separator**: If true, indicates that this is a separator and holds no - valuable information. +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 + +[dependencies-shield]: https://david-dm.org/rbdr/cologne.svg +[circle-ci-shield]: https://circleci.com/gh/rbdr/cologne.svg?style=shield