New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add request/response logging middleware #322
Merged
Merged
Changes from 9 commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
9d1a447
feat: add request/response logging middleware
bkeepers 1c7a7c1
Move req/res serializers
bkeepers 8943297
Include request in response log
bkeepers 75f1974
Fix linting
bkeepers 83f64dc
Load serializers for tests
bkeepers a61bec1
Round response time to 2 digits
bkeepers caf21dc
Merge remote-tracking branch 'origin/master' into request-logging
bkeepers c48e024
Merge branch 'request-logging' of https://github.com/probot/probot in…
bkeepers 621e732
Fix test when they run slower
bkeepers 90e4752
Switch default log level to `info`
bkeepers 72b7daf
Wrap req.log so it can be called directly
bkeepers b92716c
Fix one more test when they run slower
bkeepers 85cf35e
Tweak req/res logging
bkeepers 68fcaf9
Tweak webhook logging
bkeepers 8cd68aa
Remove suprious types
bkeepers 125dab3
Get X-Request-ID from X-GitHub-Delivery if present
bkeepers 4812134
Fix event serializer
bkeepers f5d481f
Move docs
bkeepers fd725ca
Set id on context logger for consistency
bkeepers File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// Borrowed from https://github.com/vvo/bunyan-request | ||
// Copyright (c) Christian Tellnes <christian@tellnes.no> | ||
var uuid = require('uuid') | ||
|
||
module.exports = function logRequest ({logger}) { | ||
return function (req, res, next) { | ||
// Use X-Request-ID from request if it is set, otherwise generate a uuid | ||
req.id = req.headers['x-request-id'] || uuid.v4() | ||
res.setHeader('x-request-id', req.id) | ||
|
||
// Make a logger available on the request | ||
req.log = logger.child({id: req.id}, true) | ||
|
||
// Request started | ||
req.log.debug({req}, `${req.method} ${req.url}`) | ||
|
||
// Start the request timer | ||
const time = process.hrtime() | ||
|
||
res.on('finish', () => { | ||
// Calculate how long the request took | ||
const [seconds, nanoseconds] = process.hrtime(time) | ||
const duration = (seconds * 1e3 + nanoseconds * 1e-6).toFixed(2) | ||
|
||
const message = `${req.method} ${req.url} ${res.statusCode} - ${duration} ms` | ||
|
||
req.log.info({req, res, duration}, message) | ||
}) | ||
|
||
next() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
const request = require('supertest') | ||
const express = require('express') | ||
const bunyan = require('bunyan') | ||
const serializers = require('../../lib/serializers') | ||
const logging = require('../../lib/middleware/logging') | ||
|
||
describe('logging', () => { | ||
let server, logger, output | ||
|
||
beforeEach(() => { | ||
server = express() | ||
output = [] | ||
logger = bunyan({ | ||
name: 'test', | ||
level: 'trace', | ||
streams: [{type: 'raw', stream: {write: msg => output.push(msg)}}], | ||
serializers | ||
}) | ||
|
||
server.use(express.json()) | ||
server.use(logging({logger})) | ||
server.get('/', (req, res) => { | ||
res.set('X-Test-Header', 'testing') | ||
res.send('OK') | ||
}) | ||
server.post('/', (req, res) => res.send('OK')) | ||
}) | ||
|
||
test('logs requests and responses', () => { | ||
return request(server).get('/').expect(200).expect(res => { | ||
var requestLog = output[0] | ||
var responseLog = output[1] | ||
|
||
// logs id with request and response | ||
expect(requestLog.id).toBeTruthy() | ||
expect(responseLog.id).toEqual(requestLog.id) | ||
expect(res.headers['x-request-id']).toEqual(requestLog.id) | ||
|
||
expect(requestLog).toEqual(expect.objectContaining({ | ||
msg: 'GET /', | ||
req: expect.objectContaining({ | ||
method: 'GET', | ||
url: '/', | ||
remoteAddress: '::ffff:127.0.0.1', | ||
headers: expect.objectContaining({ | ||
'accept-encoding': 'gzip, deflate', | ||
'user-agent': expect.stringMatching(/^node-superagent/), | ||
'connection': 'close' | ||
}) | ||
}) | ||
})) | ||
|
||
expect(responseLog).toEqual(expect.objectContaining({ | ||
id: requestLog.id, | ||
msg: expect.stringMatching(/^GET \/ 200 - \d+.\d\d+ ms$/), | ||
duration: expect.anything(), | ||
res: expect.objectContaining({ | ||
headers: expect.objectContaining({ | ||
'x-request-id': requestLog.id, | ||
'x-test-header': 'testing' | ||
}) | ||
}) | ||
})) | ||
|
||
expect(responseLog.duration).toMatch(/^\d\.\d\d$/) | ||
}) | ||
}) | ||
|
||
test('uses supplied X-Request-ID', () => { | ||
return request(server).get('/').set('X-Request-ID', '42').expect(200).expect(res => { | ||
expect(res.header['x-request-id']).toEqual('42') | ||
expect(output[0].id).toEqual('42') | ||
}) | ||
}) | ||
|
||
test('request body', () => { | ||
return request(server).post('/').send({foo: 'bar'}).expect(200).expect(res => { | ||
expect(output[0].req.body).toEqual({foo: 'bar'}) | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suuuuuper nitpicky, but there's an extra space here 😎