UNPKG

6.58 kBMarkdownView Raw
1# Logger for Redux
2[![Build Status](https://travis-ci.org/fcomb/redux-logger.svg?branch=master)](https://travis-ci.org/fcomb/redux-logger)
3
4![redux-logger](http://i.imgur.com/LDgv4tp.png)
5
6## Install
7`npm i --save redux-logger`
8
9## Usage
10```javascript
11import { applyMiddleware, createStore } from 'redux';
12import thunk from 'redux-thunk';
13import promise from 'redux-promise';
14import createLogger from 'redux-logger';
15
16const logger = createLogger();
17const store = createStore(
18 reducer,
19 applyMiddleware(thunk, promise, logger)
20);
21
22// Note passing middleware as the third argument requires redux@>=3.1.0
23```
24Logger **must be** last middleware in chain, otherwise it will log thunk and promise, not actual actions ([#20](https://github.com/fcomb/redux-logger/issues/20)).
25
26## API
27
28`redux-logger` exposes single constructor function for creating logger middleware.
29
30```
31createLogger(options?: Object) => LoggerMiddleware
32```
33
34### Options
35```js
36{
37 level = 'log': 'log' | 'console' | 'warn' | 'error' | 'info', // console's level
38 duration = false: Boolean, // Print the duration of each action?
39 timestamp = true: Boolean, // Print the timestamp with each action?
40 colors: ColorsObject, // Object with color getters. See the ColorsObject interface.
41 logger = window.console: LoggerObject, // Implementation of the `console` API.
42 logErrors = true: Boolean, // Should the logger catch, log, and re-throw errors?
43 collapsed, // Takes a boolean or optionally a function that receives `getState` function for accessing current store state and `action` object as parameters. Returns `true` if the log group should be collapsed, `false` otherwise.
44 predicate, // If specified this function will be called before each action is processed with this middleware.
45 stateTransformer, // Transform state before print. Eg. convert Immutable object to plain JSON.
46 actionTransformer, // Transform state before print. Eg. convert Immutable object to plain JSON.
47 errorTransformer // Transform state before print. Eg. convert Immutable object to plain JSON.
48}
49```
50
51### Options
52
53#### __level (String)__
54Level of `console`. `warn`, `error`, `info` or [else](https://developer.mozilla.org/en/docs/Web/API/console).
55
56*Default: `log`*
57
58#### __duration (Boolean)__
59Print duration of each action?
60
61*Default: `false`*
62
63#### __timestamp (Boolean)__
64Print timestamp with each action?
65
66*Default: `true`*
67
68#### __colors (Object)__
69Object with color getter functions: `title`, `prevState`, `action`, `nextState`, `error`. Useful if you want to paint
70message based on specific state or action. Set any of them to `false` if you want to show plain message without colors.
71
72* `title(action: Object) => color: String`
73* `prevState(prevState: Object) => color: String`
74* `action(action: Object) => color: String`
75* `nextState(nextState: Object) => color: String`
76* `error(error: Any, prevState: Object) => color: String`
77
78#### __logger (Object)__
79Implementation of the `console` API. Useful if you are using a custom, wrapped version of `console`.
80
81*Default: `window.console`*
82
83#### __logErrors (Boolean)__
84Should the logger catch, log, and re-throw errors? This makes it clear which action triggered the error but makes "break
85on error" in dev tools harder to use, as it breaks on re-throw rather than the original throw location.
86
87*Default: `true`*
88
89#### __collapsed = (getState: Function, action: Object) => Boolean__
90Takes a boolean or optionally a function that receives `getState` function for accessing current store state and `action` object as parameters. Returns `true` if the log group should be collapsed, `false` otherwise.
91
92*Default: `false`*
93
94#### __predicate = (getState: Function, action: Object) => Boolean__
95If specified this function will be called before each action is processed with this middleware.
96Receives `getState` function for accessing current store state and `action` object as parameters. Returns `true` if action should be logged, `false` otherwise.
97
98*Default: `null` (always log)*
99
100#### __stateTransformer = (state: Object) => state__
101Transform state before print. Eg. convert Immutable object to plain JSON.
102
103*Default: identity function*
104
105#### __actionTransformer = (action: Object) => action__
106Transform action before print. Eg. convert Immutable object to plain JSON.
107
108*Default: identity function*
109
110#### __errorTransformer = (error: Any) => error__
111Transform error before print.
112
113*Default: identity function*
114
115### Recipes
116#### log only in dev mode
117```javascript
118import thunk from 'redux-thunk';
119
120const middlewares = [thunk];
121
122if (process.env.NODE_ENV === `development`) {
123 const createLogger = require(`redux-logger`);
124 const logger = createLogger();
125 middlewares.push(logger);
126}
127
128const store = compose(applyMiddleware(...middlewares))(createStore)(reducer);
129```
130
131#### transform `Symbol()` action type to string
132```javascript
133import createLogger from 'redux-logger';
134
135const logger = createLogger({
136 actionTransformer: (action) => ({
137 ...action,
138 type: String(action.type),
139 });
140});
141```
142
143#### log everything except actions with type `AUTH_REMOVE_TOKEN`
144```javascript
145createLogger({
146 predicate: (getState, action) => action.type !== AUTH_REMOVE_TOKEN
147});
148```
149
150#### collapse actions with type `FORM_CHANGE`
151```javascript
152createLogger({
153 collapsed: (getState, action) => action.type === FORM_CHANGE
154});
155```
156
157#### transform Immutable objects into JSON
158```javascript
159import {Iterable} from 'immutable';
160
161const stateTransformer = (state) => {
162 if (Iterable.isIterable(state)) return state.toJS();
163 else return state;
164};
165
166const logger = createLogger({
167 stateTransformer,
168});
169```
170
171#### log batched actions
172Thanks to [@smashercosmo](https://github.com/smashercosmo)
173```javascript
174import createLogger from 'redux-logger';
175
176const actionTransformer = action => {
177 if (action.type === 'BATCHING_REDUCER.BATCH') {
178 action.payload.type = action.payload.reduce((result, next) => {
179 const prefix = result ? result + ' => ' : '';
180 return prefix + next.type;
181 }, '');
182
183 return action.payload;
184 }
185
186 return action;
187};
188
189const level = 'info';
190
191const logger = {};
192
193for (const method in console) {
194 if (typeof console[method] === 'function') {
195 logger[method] = console[method].bind(console);
196 }
197}
198
199logger[level] = function levelFn(...args) {
200 const lastArg = args.pop();
201
202 if (Array.isArray(lastArg)) {
203 return lastArg.forEach(item => {
204 console[level].apply(console, [...args, item]);
205 });
206 }
207
208 console[level].apply(console, arguments);
209};
210
211export default createLogger({
212 level,
213 actionTransformer,
214 logger
215});
216```
217
218### License
219MIT