generated from VilledeMontreal/repository-template
-
Notifications
You must be signed in to change notification settings - Fork 1
/
requestLogger.ts
86 lines (84 loc) · 3.29 KB
/
requestLogger.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
/*!
* Copyright (c) 2020 Ville de Montreal. All rights reserved.
* Licensed under the MIT license.
* See LICENSE file in the project root for full license information.
*/
import {
Stopwatch,
ILogger,
extractMessageFromError,
TypedProperty,
} from '@villedemontreal/auth-core';
import { Request, Response } from 'request';
import { makeRequestPlugin } from './makeRequestPlugin';
import { getRequestInfo } from './requestUtils';
const watchProperty = new TypedProperty<Stopwatch, Request>(Symbol('watch'));
/**
* plugin that will log a message before and after the execution of request,
* and provide additional information such as status code, elapsed time, error...
* @param logger the logger
* @example
* const config: request.CoreOptions = {
* url: 'http://localhost:4004/secured/profile'
* };
* requestLogger(new ConsoleLogger()).bind(config);
* const response = await request(config);
* @example
* const correlator = new HttpRequestCorrelator();
* const config: request.CoreOptions = {
* url: 'http://localhost:4004/secured/profile'
* };
* requestCorrelator(correlator).bind(config);
* requestLogger(new ConsoleLogger(() => correlator.getId())).bind(config);
* const response = await request(config);
* @example
* const defaultConfig: request.CoreOptions = {};
* requestLogger(new ConsoleLogger()).bind(defaultConfig);
* const config: request.CoreOptions = {
* ...defaultConfig,
* baseUrl: 'http://localhost:4004',
* };
* const response = await request.get('/secured/profile', config);
* @example
* const config: request.CoreOptions = {};
* authenticator(session, authenticatorConfig).bind(config);
* requestLogger(session.logger).bind(config);
* const response = await request.get('http://localhost:4004/secured/profile', config);
*/
export function requestLogger(logger: ILogger) {
return makeRequestPlugin({
//--------------------------------------------------------------------
onStart(req: Request): Promise<void> {
req.on('request', () => {
watchProperty.set(req, Stopwatch.startNew());
const { method, url } = getRequestInfo(req);
logger.debug({ method, url }, `Start of ${method} ${url}`);
});
return Promise.resolve();
},
//--------------------------------------------------------------------
onComplete(req: Request, res: Response): Promise<void> {
const { method, url } = getRequestInfo(req);
const watch = watchProperty.getOrSet(req, Stopwatch.startNew);
const elapsedTimeInMS = watch.elapsedTimeInMS();
const { statusCode } = res;
logger.debug(
{ method, url, elapsedTimeInMS, statusCode },
`End of ${method} ${url} => ${statusCode} in ${elapsedTimeInMS} ms`,
);
return Promise.resolve();
},
//--------------------------------------------------------------------
onError(error: Error, req: Request, res?: Response): Promise<void> {
const { method, url } = getRequestInfo(req);
const watch = watchProperty.getOrSet(req, Stopwatch.startNew);
const elapsedTimeInMS = watch.elapsedTimeInMS();
const errorMessage = extractMessageFromError(error);
logger.error(
{ method, url, elapsedTimeInMS, error },
`${method} ${url} failed in ${elapsedTimeInMS} ms: ${errorMessage}`,
);
return Promise.resolve();
},
});
}