Utilities for aggregating frontend logs
- Automatically send logs to syslogs/rsyslog
- Redux middlewares for logging actions and crashes
- Highly customizable
npm install web-central-logging
or
yarn add web-central-logging
import { applyMiddleware, createStore, compose } from 'redux';
import WebCLS, { crashReporter, actionLogger } from 'web-central-logging';
const logger = new WebCLS({ url: '/logs', maxBufferLength: 10 });
const store = createStore(
reducer,
initialState,
applyMiddleware([
crashReporter(logger),
// ...
actionLogger(logger)
])
);
import WebCLS from 'web-central-logging';
const logger = new WebCLS({ url: '/logs', maxBufferLength: 10 });
logger.info({ message: 'User has logged in' });
someCallback((err) => {
if(err) {
logger.error(err);
}
});
WebCLS will send the buffered logs in a POST request to the backend.
check server config for more details.
actionLogger(logger [, options])
is a redux middleware that adds redux actions into the WebCLS's buffer as info
level logs.
Property | Required | Type | Default | Description |
---|---|---|---|---|
actionFilter | No | Function | f => f |
function to filter actions See more |
stateFilter | No | Function | () => null |
function to filter state See more |
level | No | String | info |
syslog level |
actionFilters and stateFilters can be applied to filter out what is logged. see more
crashReporter(logger [, options])
is a redux middleware which reports any crash, uncaught errors & uncaught promises to WebCLS.
Property | Required | Type | Default | Description |
---|---|---|---|---|
stateFilter | No | Function | () => null |
function to filter state See more |
level | No | String | info |
syslog level |
Property | Required | Type | Default | Description |
---|---|---|---|---|
url | Yes | String | _ | Url at with logs should be sent |
maxBufferLength | No | Number | 100 | size of buffer after which logs will be flushed to the server |
sessionIdRequired | No | Bool | true |
Logs will only be sent if a session has been made by setting a sessionId using logger.setSessionId |
interval | No | Number | none | Logs will be sent if Buffer is full or Timer has passed the interval |
overwriteBuffer | No | Bool | true |
if set false old logs will not be overwritten unless logs are flushed explicitly using logger.flush() |
automaticFlush | No | Bool | flush |
automatically flushes logs if buffer is full or interval has passed |
fetchConfig | No | Object | {} |
send extra fetch parameters like headers, cookies etc. This follows TC39 standard |
extraParams | No | Object | {} |
send extra fields with each log |
fireOnGlobalErrors | No | Bool | true |
This will flush all the logs to the server if there is an uncaught error |
__send__ | No | Function | _ | Setting this will overwrite the default Flushing behaviour. |
NOTE: state can be anything that represents the state of application at time of log
Calling flush will flush all the current logs to the server.
return
a fetch promise.
Hooks are functions that receives the Buffered logs and sessionId
Note: Hooks are automatically called before flush
so mutating the logs array will result in mutation in subsequent hooks call and flush call as well.
Register WebCLS's sessionId with Sentry
logger.addHook((logs, sessionId) => {
if (typeof Raven !== 'undefined') {
Raven.setDataCallback((data) => {
data.extra.sessionURL = sessionId;
return data;
});
}
});
It is used to set session Id.
eg: when a user logs in, logger.setSessionId(string)
can be called inside a reducer to create a session
This can be used to pass extra fields to every single log line.
It is called before every logging.
Filters are pure functions which filters the data to be logged. They are highly useful when you want to hide sensitive data in logs or reduce the payload size. Filters should be pure functions.
There are two types of Filters
This is used to filter Actions. By default everything in action is logged
// Filter.js
function actionFilter(action) {
switch (action.type) {
// do not log actions that starts with @@
case /^@@/.test(action.type):
return null; // return null to Skip logging
case action.type === 'PAYMENT_INIT':
// trim userCardInfo field from action
const newAction = JSON.parse(JSON.stringify(action)); // As filters are pure
delete newAction.userCardInfo;
return newAction;
default:
return action;
}
}
This is used to filter state. By default state is not logged but if you want to log state this filter can be used.
// Filter.js
function stateFilter(state, action) {
const newState = JSON.parse(JSON.stringify(state));
switch (action.type) {
case 'ADD_TO_CART':
return {
products: newState.products
};
case 'USER_LOGGED_IN':
// let's say we don't want to log access token
newState.user.accessToken = null;
return {
user: state.user
};
default:
return null; // don't log state
}
}
By default WebCLS will send a fetch request to url
field provided in the config.
WebCLS comes with a middleware for express that send logs to syslogs
// app.js
const express = require('express');
const bodyparser = require('body-parser');
const syslogsLogger = require('web-central-logging/lib/syslogsLogger');
const app = express();
app.use(bodyParser.json());
app.use('/logs', syslogsLogger({ name: 'myApp' }));
//...
module.exports = app;
Property | Required | Type | Default | Description |
---|---|---|---|---|
name | Yes | String | _ | Your app's name which will be reflected in syslogs |
level | No | String | debug |
Minimum allowed Stream level. eg: if level is error then only error or higher level logs will pass through and lower level logs like info , debug will not appear in syslogs |
facility | No | bsyslog facility |
bsyslog.local4 |
see here |
streams | No | [bunyan stream] |
_ | see here |
In case you are not using express as backend or want to do something different with logs, you can easily do that as WebCLS sends a POST request to provided url
.
{
"message": [{
"timestamp": 1514311801722,
"action" : {
"type": "MY_FIRST_ACTION",
"payload": "Some payload",
},
"level": "info",
"extra" : {},
"state": {
"before": {
"key": "i am the filtered state before action"
},
"after": {
"key": "i am the filtered state after action"
}
},
}],
"sessionId": "ua78bxj34",
}
message
is an Array of logssessionId
can be set usinglogger.setSessionId(id)
, if not set this field will be undefined.timestamp
is the time at which log was registered.action
is a filtered or default redux action.state
is a filtered or default redux state. By default it is{}
extra
this field can be used to send extra params with each logs by settingextraParams
object in WebCLS configlevel
is syslog level, actionLogger sets levelinfo
for each log and crashReporter setserror
level for each log.
yarn
ornpm install
to install npm development dependencies.yarn build
ornpm run build
will compile the source into dist.yarn test
ornpm run test
will run the unit test suit.