Skip to content

Commit 1b8087c

Browse files
author
Olivier Van den Mooter
committed
Improve backwards compatibility, changelog
1 parent c5f5148 commit 1b8087c

File tree

4 files changed

+148
-128
lines changed

4 files changed

+148
-128
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212
runs-on: ubuntu-latest
1313
strategy:
1414
matrix:
15-
node-version: [20.x, 21.x, 22.x, 23.x, 24.x]
15+
node-version: [18.x, 20.x, 22.x, 23.x, 24.x]
1616
steps:
1717
- uses: actions/checkout@v2
1818
- name: Use Node.js ${{ matrix.node-version }}

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
77
[Unreleased]: https://github.com/digipolisantwerp/request_log_module_nodejs/compare/v0.0.1...HEAD
88
## [Unreleased] - yyyy-mm-dd
99

10+
[0.7.0]: https://github.com/digipolisantwerp/request_log_module_nodejs/tree/v0.7.0
11+
## [0.7.0] - 2025-05-07
12+
13+
- Add support for fetch requests
14+
- node 24 tests
15+
- remove node 14.x, 16.x compatibility is kept but not new fetch features
16+
1017
[0.6.4]: https://github.com/digipolisantwerp/request_log_module_nodejs/tree/v0.6.0
1118
## [0.6.0] - 2023-12-01
1219

lib/request.logger.js

Lines changed: 53 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -13,59 +13,61 @@ module.exports = (config) => {
1313
const validatedConfig = validateConfig(config);
1414
const logger = createLogger(validatedConfig);
1515
let original = global.fetch;
16-
global.fetch = async (requestUrl, options) => {
17-
const parsedUrl = url.parse(requestUrl);
18-
let correlationId;
19-
if (options && options.headers) {
20-
correlationId = options.headers['Dgp-Correlation'] || options.headers['dgp-correlation'] || validatedConfig.correlationIdfallback;
21-
}
16+
if(original) {
17+
global.fetch = async (requestUrl, options) => {
18+
const parsedUrl = url.parse(requestUrl);
19+
let correlationId;
20+
if (options && options.headers) {
21+
correlationId = options.headers['Dgp-Correlation'] || options.headers['dgp-correlation'] || validatedConfig.correlationIdfallback;
22+
}
2223

23-
const timer = startTimer();
24-
const response = await original(requestUrl, options)
25-
const duration = timer.getDuration();
26-
const req = {
27-
headers: options?.headers || undefined,
28-
host: parsedUrl.host,
29-
path: parsedUrl.path,
30-
method: options?.method || 'GET',
31-
payload: options?.body || undefined,
32-
search: parsedUrl.search,
33-
};
34-
const res = {
35-
status: response.status,
36-
duration,
37-
};
38-
const log = logRequest(logger, correlationId, req, res, parsedUrl.protocol );
39-
let logged = false;
40-
if (validatedConfig.logResponsePayload) {
41-
const json = () =>
42-
response
43-
.clone()
44-
.json()
45-
.then((data) => {
46-
log(data);
47-
logged = true;
48-
return (data)
49-
});
50-
const text = () =>
51-
response
52-
.clone()
53-
.text()
54-
.then((data) => {
55-
log(data);
56-
logged = true;
57-
return (data)
58-
});
59-
// Response is not parsed json/text
60-
setTimeout(() => {
61-
if(!logged) log();
62-
}, 1)
63-
response.json = json;
64-
response.text = text;
65-
} else {
66-
log();
24+
const timer = startTimer();
25+
const response = await original(requestUrl, options)
26+
const duration = timer.getDuration();
27+
const req = {
28+
headers: options?.headers || undefined,
29+
host: parsedUrl.host,
30+
path: parsedUrl.path,
31+
method: options?.method || 'GET',
32+
payload: options?.body || undefined,
33+
search: parsedUrl.search,
34+
};
35+
const res = {
36+
status: response.status,
37+
duration,
38+
};
39+
const log = logRequest(logger, correlationId, req, res, parsedUrl.protocol );
40+
let logged = false;
41+
if (validatedConfig.logResponsePayload) {
42+
const json = () =>
43+
response
44+
.clone()
45+
.json()
46+
.then((data) => {
47+
log(data);
48+
logged = true;
49+
return (data)
50+
});
51+
const text = () =>
52+
response
53+
.clone()
54+
.text()
55+
.then((data) => {
56+
log(data);
57+
logged = true;
58+
return (data)
59+
});
60+
// Response is not parsed json/text
61+
setTimeout(() => {
62+
if(!logged) log();
63+
}, 1)
64+
response.json = json;
65+
response.text = text;
66+
} else {
67+
log();
68+
}
69+
return response;
6770
}
68-
return response;
6971
}
7072

7173
httpModules.forEach((httpModule) => {

test/request.logger.test.js

Lines changed: 87 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const { expect } = chai;
99

1010
const { requestlogger } = require('../lib');
1111
const app = require('./helpers/server');
12+
const fetchTest = parseInt( process.version.split('.')[0].split('v')[1], 10) >= 20;
1213

1314
chai.use(require('chai-json-schema'));
1415

@@ -46,87 +47,93 @@ describe('Requestlog:', () => {
4647
it('GET /externalcall {} fetch 200', async () => {
4748
const logger = requestlogger();
4849
const logspy = sandbox.spy(logger, 'log');
49-
await global.fetch(
50-
`http://localhost:${server.address().port}/externalcall`,
51-
{
52-
headers: {
53-
testheader: "testvalue"
50+
if(fetchTest) {
51+
await global.fetch(
52+
`http://localhost:${server.address().port}/externalcall`,
53+
{
54+
headers: {
55+
testheader: "testvalue"
56+
}
5457
}
55-
}
56-
);
57-
return new Promise((resolve) => {
58-
setTimeout(() => {
59-
sinon.assert.calledWith(logspy, {
60-
request: {
61-
host: sinon.match(/localhost:[0-9]+/gm),
62-
path: '/externalcall',
63-
method: 'GET',
64-
},
65-
response: { status: 200, duration: sinon.match.number },
66-
protocol: 'http:',
67-
type: ['application'],
68-
});
69-
resolve()
70-
}, 1);
71-
});
58+
);
59+
return new Promise((resolve) => {
60+
setTimeout(() => {
61+
sinon.assert.calledWith(logspy, {
62+
request: {
63+
host: sinon.match(/localhost:[0-9]+/gm),
64+
path: '/externalcall',
65+
method: 'GET',
66+
},
67+
response: { status: 200, duration: sinon.match.number },
68+
protocol: 'http:',
69+
type: ['application'],
70+
});
71+
resolve()
72+
}, 1);
73+
});
74+
}
7275
})
7376
it('GET /externalcall {} fetch 200 json', async () => {
7477
const logger = requestlogger();
7578
const logspy = sandbox.spy(logger, 'log');
76-
const request = await global.fetch(
77-
`http://localhost:${server.address().port}/externalcall`,
78-
{
79-
headers: {
80-
testheader: "testvalue"
79+
if(fetchTest) {
80+
const request = await global.fetch(
81+
`http://localhost:${server.address().port}/externalcall`,
82+
{
83+
headers: {
84+
testheader: "testvalue"
85+
}
8186
}
82-
}
83-
);
84-
const body = await request.json();
85-
expect(body).to.eql({ ok: 'ok' })
86-
return new Promise((resolve) => {
87-
setTimeout(() => {
88-
sinon.assert.calledWith(logspy, {
89-
request: {
90-
host: sinon.match(/localhost:[0-9]+/gm),
91-
path: '/externalcall',
92-
method: 'GET',
93-
},
94-
response: { status: 200, duration: sinon.match.number },
95-
protocol: 'http:',
96-
type: ['application'],
97-
});
98-
resolve()
99-
}, 1);
100-
});
87+
);
88+
const body = await request.json();
89+
expect(body).to.eql({ ok: 'ok' })
90+
return new Promise((resolve) => {
91+
setTimeout(() => {
92+
sinon.assert.calledWith(logspy, {
93+
request: {
94+
host: sinon.match(/localhost:[0-9]+/gm),
95+
path: '/externalcall',
96+
method: 'GET',
97+
},
98+
response: { status: 200, duration: sinon.match.number },
99+
protocol: 'http:',
100+
type: ['application'],
101+
});
102+
resolve()
103+
}, 1);
104+
});
105+
}
101106
})
102107
it('GET /externalcall {} fetch 200 text', async () => {
103108
const logger = requestlogger();
104109
const logspy = sandbox.spy(logger, 'log');
105-
const request = await global.fetch(
106-
`http://localhost:${server.address().port}/externalcall`,
107-
{
108-
headers: {
109-
testheader: "testvalue"
110+
if(fetchTest) {
111+
const request = await global.fetch(
112+
`http://localhost:${server.address().port}/externalcall`,
113+
{
114+
headers: {
115+
testheader: "testvalue"
116+
}
110117
}
111-
}
112-
);
113-
const body = await request.text();
114-
expect(body).to.eql('{"ok":"ok"}')
115-
return new Promise((resolve) => {
116-
setTimeout(() => {
117-
sinon.assert.calledWith(logspy, {
118-
request: {
119-
host: sinon.match(/localhost:[0-9]+/gm),
120-
path: '/externalcall',
121-
method: 'GET',
122-
},
123-
response: { status: 200, duration: sinon.match.number },
124-
protocol: 'http:',
125-
type: ['application'],
126-
});
127-
resolve()
128-
}, 1);
129-
});
118+
);
119+
const body = await request.text();
120+
expect(body).to.eql('{"ok":"ok"}')
121+
return new Promise((resolve) => {
122+
setTimeout(() => {
123+
sinon.assert.calledWith(logspy, {
124+
request: {
125+
host: sinon.match(/localhost:[0-9]+/gm),
126+
path: '/externalcall',
127+
method: 'GET',
128+
},
129+
response: { status: 200, duration: sinon.match.number },
130+
protocol: 'http:',
131+
type: ['application'],
132+
});
133+
resolve()
134+
}, 1);
135+
});
136+
}
130137
})
131138
it('no callback return res', async () => {
132139
const options = {
@@ -396,9 +403,10 @@ describe('Requestlog:', () => {
396403
it('GET /externalcall fetch { logResponsePayload: true } 200', async () => {
397404
const logger = requestlogger({ logResponsePayload: true });
398405
const logspy = sandbox.spy(logger, 'log');
399-
const response = await global.fetch(`http://localhost:${server.address().port}/externalcall`);
400-
await response.json();
401-
return sinon.assert.calledWith(logspy, {
406+
if(fetchTest) {
407+
const response = await global.fetch(`http://localhost:${server.address().port}/externalcall`);
408+
await response.json();
409+
return sinon.assert.calledWith(logspy, {
402410
type: ['application'],
403411
request: {
404412
host: sinon.match(/localhost:[0-9]+/gm),
@@ -412,13 +420,15 @@ describe('Requestlog:', () => {
412420
},
413421
protocol: 'http:',
414422
});
423+
}
415424
});
416425
it('GET /externalcall fetch text { logResponsePayload: true } 200', async () => {
417426
const logger = requestlogger({ logResponsePayload: true });
418427
const logspy = sandbox.spy(logger, 'log');
419-
const response = await global.fetch(`http://localhost:${server.address().port}/externalcall`);
420-
await response.text();
421-
return sinon.assert.calledWith(logspy, {
428+
if(fetchTest) {
429+
const response = await global.fetch(`http://localhost:${server.address().port}/externalcall`);
430+
await response.text();
431+
return sinon.assert.calledWith(logspy, {
422432
type: ['application'],
423433
request: {
424434
host: sinon.match(/localhost:[0-9]+/gm),
@@ -432,6 +442,7 @@ describe('Requestlog:', () => {
432442
},
433443
protocol: 'http:',
434444
});
445+
}
435446
});
436447
it('POST /externalcall {} 200', async () => {
437448
const logger = requestlogger();

0 commit comments

Comments
 (0)