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/pMR3OAv.png)
|
5 |
|
6 | ## Install
|
7 | `npm i --save redux-logger`
|
8 |
|
9 | ## Usage
|
10 | ```javascript
|
11 | import { applyMiddleware, createStore } from 'redux';
|
12 | import thunk from 'redux-thunk';
|
13 | import promise from 'redux-promise';
|
14 | import createLogger from 'redux-logger';
|
15 |
|
16 | const logger = createLogger();
|
17 | const 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 | ```
|
24 | Logger **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 | ```
|
31 | createLogger(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 = 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 | Function | Object)__
|
54 | Level of `console`. `warn`, `error`, `info` or [else](https://developer.mozilla.org/en/docs/Web/API/console).
|
55 |
|
56 | It can be a function `(action: Object) => level: String`.
|
57 |
|
58 | It can be an object with level string for: `prevState`, `action`, `nextState`, `error`
|
59 |
|
60 | It can be an object with getter functions: `prevState`, `action`, `nextState`, `error`. Useful if you want to print
|
61 | message based on specific state or action. Set any of them to `false` if you want to hide it.
|
62 |
|
63 | * `prevState(prevState: Object) => level: String`
|
64 | * `action(action: Object) => level: String`
|
65 | * `nextState(nextState: Object) => level: String`
|
66 | * `error(error: Any, prevState: Object) => level: String`
|
67 |
|
68 | *Default: `log`*
|
69 |
|
70 | #### __duration (Boolean)__
|
71 | Print duration of each action?
|
72 |
|
73 | *Default: `false`*
|
74 |
|
75 | #### __timestamp (Boolean)__
|
76 | Print timestamp with each action?
|
77 |
|
78 | *Default: `true`*
|
79 |
|
80 | #### __colors (Object)__
|
81 | Object with color getter functions: `title`, `prevState`, `action`, `nextState`, `error`. Useful if you want to paint
|
82 | message based on specific state or action. Set any of them to `false` if you want to show plain message without colors.
|
83 |
|
84 | * `title(action: Object) => color: String`
|
85 | * `prevState(prevState: Object) => color: String`
|
86 | * `action(action: Object) => color: String`
|
87 | * `nextState(nextState: Object) => color: String`
|
88 | * `error(error: Any, prevState: Object) => color: String`
|
89 |
|
90 | #### __logger (Object)__
|
91 | Implementation of the `console` API. Useful if you are using a custom, wrapped version of `console`.
|
92 |
|
93 | *Default: `console`*
|
94 |
|
95 | #### __logErrors (Boolean)__
|
96 | Should the logger catch, log, and re-throw errors? This makes it clear which action triggered the error but makes "break
|
97 | on error" in dev tools harder to use, as it breaks on re-throw rather than the original throw location.
|
98 |
|
99 | *Default: `true`*
|
100 |
|
101 | #### __collapsed = (getState: Function, action: Object) => Boolean__
|
102 | 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.
|
103 |
|
104 | *Default: `false`*
|
105 |
|
106 | #### __predicate = (getState: Function, action: Object) => Boolean__
|
107 | If specified this function will be called before each action is processed with this middleware.
|
108 | Receives `getState` function for accessing current store state and `action` object as parameters. Returns `true` if action should be logged, `false` otherwise.
|
109 |
|
110 | *Default: `null` (always log)*
|
111 |
|
112 | #### __stateTransformer = (state: Object) => state__
|
113 | Transform state before print. Eg. convert Immutable object to plain JSON.
|
114 |
|
115 | *Default: identity function*
|
116 |
|
117 | #### __actionTransformer = (action: Object) => action__
|
118 | Transform action before print. Eg. convert Immutable object to plain JSON.
|
119 |
|
120 | *Default: identity function*
|
121 |
|
122 | #### __errorTransformer = (error: Any) => error__
|
123 | Transform error before print.
|
124 |
|
125 | *Default: identity function*
|
126 |
|
127 | ### Recipes
|
128 | #### log only in dev mode
|
129 | ```javascript
|
130 | import thunk from 'redux-thunk';
|
131 |
|
132 | const middlewares = [thunk];
|
133 |
|
134 | if (process.env.NODE_ENV === `development`) {
|
135 | const createLogger = require(`redux-logger`);
|
136 | const logger = createLogger();
|
137 | middlewares.push(logger);
|
138 | }
|
139 |
|
140 | const store = compose(applyMiddleware(...middlewares))(createStore)(reducer);
|
141 | ```
|
142 |
|
143 | #### transform `Symbol()` action type to string
|
144 | ```javascript
|
145 | import createLogger from 'redux-logger';
|
146 |
|
147 | const logger = createLogger({
|
148 | actionTransformer: (action) => ({
|
149 | ...action,
|
150 | type: String(action.type),
|
151 | });
|
152 | });
|
153 | ```
|
154 |
|
155 | #### log everything except actions with type `AUTH_REMOVE_TOKEN`
|
156 | ```javascript
|
157 | createLogger({
|
158 | predicate: (getState, action) => action.type !== AUTH_REMOVE_TOKEN
|
159 | });
|
160 | ```
|
161 |
|
162 | #### collapse actions with type `FORM_CHANGE`
|
163 | ```javascript
|
164 | createLogger({
|
165 | collapsed: (getState, action) => action.type === FORM_CHANGE
|
166 | });
|
167 | ```
|
168 |
|
169 | #### transform Immutable objects into JSON
|
170 | ```javascript
|
171 | import {Iterable} from 'immutable';
|
172 |
|
173 | const stateTransformer = (state) => {
|
174 | if (Iterable.isIterable(state)) return state.toJS();
|
175 | else return state;
|
176 | };
|
177 |
|
178 | const logger = createLogger({
|
179 | stateTransformer,
|
180 | });
|
181 | ```
|
182 |
|
183 | #### log batched actions
|
184 | Thanks to [@smashercosmo](https://github.com/smashercosmo)
|
185 | ```javascript
|
186 | import createLogger from 'redux-logger';
|
187 |
|
188 | const actionTransformer = action => {
|
189 | if (action.type === 'BATCHING_REDUCER.BATCH') {
|
190 | action.payload.type = action.payload.reduce((result, next) => {
|
191 | const prefix = result ? result + ' => ' : '';
|
192 | return prefix + next.type;
|
193 | }, '');
|
194 |
|
195 | return action.payload;
|
196 | }
|
197 |
|
198 | return action;
|
199 | };
|
200 |
|
201 | const level = 'info';
|
202 |
|
203 | const logger = {};
|
204 |
|
205 | for (const method in console) {
|
206 | if (typeof console[method] === 'function') {
|
207 | logger[method] = console[method].bind(console);
|
208 | }
|
209 | }
|
210 |
|
211 | logger[level] = function levelFn(...args) {
|
212 | const lastArg = args.pop();
|
213 |
|
214 | if (Array.isArray(lastArg)) {
|
215 | return lastArg.forEach(item => {
|
216 | console[level].apply(console, [...args, item]);
|
217 | });
|
218 | }
|
219 |
|
220 | console[level].apply(console, arguments);
|
221 | };
|
222 |
|
223 | export default createLogger({
|
224 | level,
|
225 | actionTransformer,
|
226 | logger
|
227 | });
|
228 | ```
|
229 |
|
230 | ### License
|
231 | MIT
|