jack-logs
v0.3.0
Published
Contextual application logging
Downloads
33
Readme
jack
Contextual application logging
jack
is a lumberjack who logs your application. He's designed for logging to
an external logging service, and getting a standardised context from Redux.
Installation
yarn add jack-logs
is enough to get you going.
Set Up
Get started by adding the store enhancer to redux.
import { createStore } from redux;
import jack from 'jack-logs/enhancer';
createStore(
reducer,
// initialState, if necessary,
jack({ contextBuilder }),
);
If you've got another enhancer (such as applyMiddleware
from redux
),
import { compose, applyMiddleware, createStore } from 'redux';
import jack from 'jack-logs/enhancer';
createStore(
reducer,
// initialState, if necessary,
compose(
applyMiddleware(/* all your middleware goes here */),
jack({ contextBuilder }),
),
);
contextBuilder
is a function that accepts your state, and returns back the
'context' to include with the log.
For example, to include your entire state with every log (probably a bad idea, but hey...):
const contextBuilder = state => state;
Keep in mind that the state you return must be serializable (or at least
have a .toString()
method. If you're storing anything grimey in redux
, it
will probably not show up as expected in your logs.
Using jack
- Once everything is set up, you can just import
jack
wherever you need
import jack from 'jack-logs';
jack.log('Up and running!');
A level is a method on jack
, and is also provided to the
Services to be displayed in your logging application.
jack
provides the following 'levels'.
log
info
debug
warn
error
During development, jack
will try and log these using the relevant console
method, should it exist. If it doesn't exist, jack
will prepend your log line
with [LEVEL]
, where 'LEVEL' is the method used.
Example:
import jack from 'jack-logs';
jack.log('A standard log line'); // => 'A standard log line'
console.debug = null;
jack.debug('A debug log line'); // => '[DEBUG] A debug log line'
Services
jack
can send your logs to any number of services. Below are the included services:
To use services, import + instantiate them, and then pass them to your enhancer.
import { createStore } from 'redux';
import enhancer from 'jack-logs/enhancer';
import LogEntries from 'jack-logs/services/LogEntries';
const le = new LogEntries('your-token-here');
const store = createStore(
reducer,
enhancer({ services: [le], contextBuilder: state => state }),
);
Creating your own service
A service is a class that has, at minimum, a log
method. This function takes
3 arguments (with a 4th optional):
level
: the 'severity' of the log linedata
: the actual message to be logged. This is the exact item that was passed tojack
, so you need to expect/handle any data type.context
: the context received fromcontextBuilder
additional
: this is an object that will containlocation
if the babel plugin is in use.
There is a base class you can extend:
import Service from 'jack-logs/services';
, which will provide only one helper
right now - this.stringify
, which you can use to intelligently stringify any
JSON. If you're using flow, you'll want to extend this class to take advantage
of static analysis - services
in the enhancer must be Service
class
instances.
Babel Plugin
jack
comes bundled with a babel plugin that, at this stage, provides jack
with an accurate call-site. jack
, unlike console.log
in the Chrome console,
does not get the line number of where it was called 😢.
Caveat - this babel plugin requires you to call the logger jack
. You
can pass a name
option to the plugin to provide it with a new name, but you
must use the same name in all locations.
The default is a short-format like file.js:line:column
.
Add the plugin last in your list of plugins (to make sure the line numbers are correct) like this:
// .babelrc
{
// ...config,
plugins: [
// my other plugins,
"jack-logs/babel-plugin-jack"
]
}
Options
There are 2 options you can pass to the plugin.
// .babelrc
{
// ...config,
plugins: [
// my other plugins,
["jack-logs/babel-plugin-jack", {
long: false, // default to false
name: 'jack', // defaults to jack
}]
]
}
long: true
results in the followinglocation
output
{
filename: 'file.js',
start: {
line: '<line number>',
column: '<column number>',
},
end: {
line: '<line number>',
column: '<column number>',
}
}
name: something
allows you to call methods fromsomething
import something from 'jack-logs';
something.log('Hey!') // gets a location
jack.log('Hey!') // doesn't get a location (if `name: something` is set)
Helpers
If you have some places you'd like to see a logline in development, but
don't really need a production log line, you can put dev
in your call to
jack
.
import jack from 'jack-logs';
jack.log('Production log line'); // gets logged during development to the console and production to LogEntries
jack.dev.log('Dev log line'); // Only gets logged during development