twitch-toolkit
Version:
A set of tools to integrate with Twitch API, Twitch Chat and Twitch WebHooks.
171 lines (128 loc) • 5.21 kB
Markdown
# logform
An mutable object-based log format designed for chaining & objectMode streams.
``` js
const { format } = require('logform');
const alignedWithColorsAndTime = format.combine(
format.colorize(),
format.timestamp(),
format.align(),
format.printf(info => `${info.timestamp} ${info.level}: ${info.message}`)
);
```
- [`info` Objects](#info-objects)
- [Understanding formats](#understanding-formats)
- [Combining formats](#combining-formats)
- [Filtering `info` objects](#filtering-info-objects)
## `info` Objects
The `info` parameter provided to a given format represents a single log message. The object itself is mutable. Every `info` must have at least the `level` and `message` properties:
``` js
{
level: 'info', // Level of the logging message
message: 'Hey! Log something?' // Descriptive message being logged.
}
```
`logform` itself exposes several additional properties:
- `splat`: string interpolation splat for `%d %s`-style messages.
- `timestamp`: timestamp the message was received.
- `label`: custom label associated with each message.
As a consumer you may add whatever properties you wish – _internal state is maintained by `Symbol` properties:_
- `Symbol.for('level')` _**(READ-ONLY)**:_ equal to `level` property. Is treated as immutable by all code.
- `Symbol.for('message'):` complete string message set by "finalizing formats": `json`, `logstash`, `printf`, `prettyPrint`, and `simple`.
## Understanding formats
Formats are prototypal objects (i.e. class instances) that define a single method: `transform(info, opts)` and return the mutated `info`
- `info`: an object representing the log message.
- `opts`: setting specific to the current instance of the format.
They are expected to return one of two things:
- **An `info` Object** representing the modified `info` argument. Object references need not be preserved if immutability is preferred. All current built-in formats consider `info` mutable, but [immutablejs] is being considered for future releases.
- **A falsey value** indicating that the `info` argument should be ignored by the caller. (See: [Filtering `info` Objects](#filtering-info-objects)) below.
`logform.format` is designed to be as simple as possible. To define a new format simple pass it a `transform(info, opts)` function to get a new `Format`.
The named `Format` returned can be used to create as many copies of the given `Format` as desired:
``` js
const { format } = require('logform');
const volume = format((info, opts) => {
if (opts.yell) {
info.message = info.message.toUpperCase();
} else if (opts.whisper) {
info.message = info.message.toLowerCase();
}
return info;
});
// `volume` is now a function that returns instances of the format.
const scream = volume({ yell: true });
console.dir(scream.transform({
level: 'info',
message: `sorry for making you YELL in your head!`
}, scream.options));
// {
// level: 'info'
// message: 'SORRY FOR MAKING YOU YELL IN YOUR HEAD!'
// }
// `volume` can be used multiple times to create different formats.
const whisper = volume({ whisper: true });
console.dir(whisper.transform({
level: 'info',
message: `WHY ARE THEY MAKING US YELL SO MUCH!`
}), whisper.options);
// {
// level: 'info'
// message: 'why are they making us yell so much!'
// }
```
### Combining formats
Any number of formats may be combined into a single format using `format.combine`. Since `format.combine` takes no `opts`, as a convenience it returns pre-created instance of the combined format.
``` js
const { format } = require('logform');
const { combine, timestamp, label } = format;
const labelTimestamp = combine(
label({ label: 'right meow!' }),
timestamp()
);
const info = labelTimestamp.transform({
level: 'info',
message: 'What time is the testing at?'
});
console.dir(info);
// { level: 'info',
// message: 'What time is the testing at?',
// label: 'right meow!',
// timestamp: '2017-09-30T03:57:26.875Z' }
```
### Filtering `info` Objects
If you wish to filter out a given `info` Object completely then simply return a falsey value.
``` js
const ignorePrivate = format((info, opts) => {
if (info.private) { return false; }
return info;
});
console.dir(ignorePrivate.transform({
level: 'error',
message: 'Public error to share'
}));
// { level: 'error', message: 'Public error to share' }
console.dir(ignorePrivate.transform({
level: 'error',
private: true,
message: 'This is super secret - hide it.'
}));
// false
```
Use of `format.combine` will respect any falsey values return and stop evaluation of later formats in the series. For example:
``` js
const { format } = require('logform');
const { combine, timestamp, label } = format;
const willNeverThrow = format.combine(
format(info => { return false })(), // Ignores everything
format(info => { throw new Error('Never reached') })()
);
console.dir(willNeverThrow.transform({
level: 'info',
message: 'wow such testing'
}))
```
## Tests
Tests are written with `mocha`, `assume`, and `nyc`. They can be run with `npm`:
```
npm test
```
##### LICENSE: MIT
##### AUTHOR: [Charlie Robbins](https://github.com/indexzero)