Skip to content
This repository was archived by the owner on Jun 21, 2023. It is now read-only.

Commit 484fe03

Browse files
committed
Merge branch 'change/better-format' into 'master'
Change express format See merge request Backend/ackee-node-logger!11
2 parents 9b46f3e + 597feff commit 484fe03

7 files changed

Lines changed: 146 additions & 16 deletions

File tree

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
## [0.2.8] - 2018-10-15
2+
3+
### Changed
4+
- output format of express middleware logging
5+
6+
### Fixed
7+
- bug in `enableFields` options
8+
19
## [0.2.7] - 2018-10-10
210

311
### Changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ If you use it together with logger's error express middleware, it will also log
8080
app.use(logger.expressError)
8181
```
8282

83-
All those log messages will contain request and possibly response, error, time from request to response and status code.
83+
All those log messages will contain request and possibly response, error, time from request to response, status code and `user-agent`, `x-deviceid` and `authorization` request headers.
8484

8585
## Environment-specific behavior
8686
`ackee-node-logger` is meant to be used throughout different environments (development, testing, production) and some of its configuration is setup differently based on the environment it runs in.

express.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ const onFinished = require('on-finished');
22
const onHeaders = require('on-headers');
33

44
const expressMiddleware = function(req, response, next) {
5-
const reqInfo = `${req.method} ${req.originalUrl} HTTP/${req.httpVersion}`;
6-
this.debug({ req, ackId: req.ackId }, `${reqInfo} - Request accepted`);
5+
const reqIn = `--- ${req.method} ${req.originalUrl} ${req.headers['user-agent']}`;
6+
this.debug({ req, ackId: req.ackId }, `${reqIn} - Request accepted`);
77
req._startAt = process.hrtime();
88
onHeaders(response, () => {
99
response._startAt = process.hrtime();
@@ -14,15 +14,16 @@ const expressMiddleware = function(req, response, next) {
1414
});
1515
onFinished(response, (err, res) => {
1616
const error = res[Symbol.for('error')];
17+
const reqOut = `${res.statusCode} ${req.method} ${req.originalUrl} ${res.time} ms ${req.headers['user-agent']}`;
1718
if (this.options.ignoredHttpMethods.includes(req.method)) {
1819
return;
1920
}
2021
if (error) {
21-
this.error({ error, req, res, ackId: req.ackId }, `${reqInfo} - Error handler at the end of app`);
22+
this.error({ error, req, res, ackId: req.ackId }, `${reqOut} - Error handler at the end of app`);
2223
} else if (res.out) {
23-
this.debug({ req, res, ackId: req.ackId }, `${reqInfo} - Standard output [${res.statusCode}]`);
24+
this.debug({ req, res, ackId: req.ackId }, `${reqOut} - Standard output`);
2425
} else {
25-
this.info({ req, res, ackId: req.ackId }, `${reqInfo} - Standard output [${res.statusCode}]`);
26+
this.info({ req, res, ackId: req.ackId }, `${reqOut} - Standard output`);
2627
}
2728
});
2829
next();

package-lock.json

Lines changed: 26 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ackee-node-logger",
3-
"version": "0.2.7",
3+
"version": "0.2.8",
44
"description": "Ackee Node Logger",
55
"main": "index.js",
66
"scripts": {
@@ -23,10 +23,10 @@
2323
"lodash.isempty": "^4.4.0",
2424
"lodash.isobject": "^3.0.2",
2525
"lodash.isstring": "^4.0.1",
26-
"lodash.pick": "^4.4.0",
2726
"omit-deep": "^0.3.0",
2827
"on-finished": "^2.3.0",
2928
"on-headers": "^1.0.1",
29+
"pick-deep": "^1.0.0",
3030
"pino": "^4.13.0",
3131
"pino-multi-stream": "3.1.2"
3232
},
@@ -37,10 +37,14 @@
3737
"flush-write-stream": "^1.0.2",
3838
"husky": "^0.14.3",
3939
"jest": "^22.4.2",
40+
"jest-expect-message": "^1.0.1",
4041
"lint-staged": "^7.0.0",
4142
"npm-check": "^5.5.2",
4243
"prettier": "^1.11.0",
4344
"split2": "^2.2.0",
4445
"supertest": "^3.1.0"
46+
},
47+
"jest": {
48+
"setupTestFrameworkScriptFile": "jest-expect-message"
4549
}
4650
}

serializers.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
const forEach = require('lodash.foreach');
2-
const pick = require('lodash.pick');
2+
const pick = require('pick-deep');
33
const { removeEmpty } = require('./utils');
44
const omit = require('omit-deep');
55

@@ -24,6 +24,7 @@ const serializers = {
2424
return removeEmpty(Object.assign({}, filteredEnv, rest));
2525
},
2626
req(obj) {
27+
const pickHeaders = ['x-deviceid', 'authorization', 'user-agent'];
2728
const [body, query] = ['body', 'query'].map(name => {
2829
const source = obj[name];
2930
if (source) {
@@ -39,6 +40,7 @@ const serializers = {
3940
query,
4041
url: obj.originalUrl || obj.url,
4142
method: obj.method,
43+
headers: pick(obj.headers, pickHeaders),
4244
});
4345
},
4446
res(obj) {

tests/serializers.test.js

Lines changed: 96 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
const pick = require('lodash.pick');
1+
const pick = require('pick-deep');
22
const omitDeep = require('omit-deep');
33
const stream = require('stream');
4+
const express = require('express');
5+
const supertest = require('supertest');
46

57
let loggerFactory;
68

@@ -172,3 +174,96 @@ test('Enable custom path', () => {
172174
logger.info({ req });
173175
expect(loggerWrites).toBeCalled();
174176
});
177+
178+
test('Some express headers are enabled by default', () => {
179+
const loggerWrites = jest.fn();
180+
const logger = loggerFactory({
181+
streams: [
182+
{
183+
stream: new stream.Writable({
184+
write: (chunk, encoding, next) => {
185+
const json = JSON.parse(chunk);
186+
const validHeaders = ['x-deviceid', 'authorization', 'user-agent'];
187+
validHeaders.forEach(header =>
188+
expect(json.req.headers[header], `${header} header should be defined`).toBeDefined()
189+
);
190+
Object.keys(json.req.headers).forEach(header =>
191+
expect(validHeaders.includes(header), `${header} header should not be defined`).toBe(true)
192+
);
193+
loggerWrites();
194+
next();
195+
},
196+
}),
197+
},
198+
],
199+
});
200+
const app = express();
201+
const request = supertest(app);
202+
app.use(logger.express);
203+
return request
204+
.get('/')
205+
.set('x-deviceid', '12345abcde')
206+
.set('Authorization', 'Basic pass')
207+
.set('User-Agent', 'Jest tests')
208+
.set('Age', 100)
209+
.then(() => {
210+
expect(loggerWrites).toBeCalled();
211+
});
212+
});
213+
214+
test('Express fields and headers can be enabled', () => {
215+
const loggerWrites = jest.fn();
216+
const logger = loggerFactory({
217+
enableFields: ['req.protocol', 'req.headers.host'],
218+
streams: [
219+
{
220+
stream: new stream.Writable({
221+
write: (chunk, encoding, next) => {
222+
const json = JSON.parse(chunk);
223+
expect(json.req.protocol).toBe('http');
224+
expect(json.req.headers.host).toBe('localhost');
225+
loggerWrites();
226+
next();
227+
},
228+
}),
229+
},
230+
],
231+
});
232+
const app = express();
233+
const request = supertest(app);
234+
app.use(logger.express);
235+
return request
236+
.get('/')
237+
.set('host', 'localhost')
238+
.then(() => {
239+
expect(loggerWrites).toBeCalled();
240+
});
241+
});
242+
243+
test('Default express headers can be disabled', () => {
244+
const loggerWrites = jest.fn();
245+
const logger = loggerFactory({
246+
disableFields: ['req.headers.user-agent'],
247+
streams: [
248+
{
249+
stream: new stream.Writable({
250+
write: (chunk, encoding, next) => {
251+
const json = JSON.parse(chunk);
252+
expect(json.req.headers['user-agent']).toBeUndefined();
253+
loggerWrites();
254+
next();
255+
},
256+
}),
257+
},
258+
],
259+
});
260+
const app = express();
261+
const request = supertest(app);
262+
app.use(logger.express);
263+
return request
264+
.get('/')
265+
.set('x-deviceid', '1234')
266+
.then(() => {
267+
expect(loggerWrites).toBeCalled();
268+
});
269+
});

0 commit comments

Comments
 (0)