Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit da42ffb

Browse filesBrowse files
theanarkhbengl
authored andcommitted
http: trace http client by perf_hooks
PR-URL: #42345 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: Ricky Zhou <0x19951125@gmail.com>
1 parent 229fb40 commit da42ffb
Copy full SHA for da42ffb

File tree

Expand file treeCollapse file tree

5 files changed

+66
-9
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

5 files changed

+66
-9
lines changed
Open diff view settings
Collapse file

‎doc/api/perf_hooks.md‎

Copy file name to clipboardExpand all lines: doc/api/perf_hooks.md
+30Lines changed: 30 additions & 0 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -1254,6 +1254,36 @@ obs.observe({ entryTypes: ['function'], buffered: true });
12541254
require('some-module');
12551255
```
12561256

1257+
### Measuring how long one HTTP round-trip takes
1258+
1259+
The following example is used to trace the time spent by HTTP client
1260+
(`OutgoingMessage`) and HTTP request (`IncomingMessage`). For HTTP client,
1261+
it means the time interval between starting the request and receiving the
1262+
response, and for HTTP request, it means the time interval between receiving
1263+
the request and sending the response:
1264+
1265+
```js
1266+
'use strict';
1267+
const { PerformanceObserver } = require('perf_hooks');
1268+
const http = require('http');
1269+
1270+
const obs = new PerformanceObserver((items) => {
1271+
items.getEntries().forEach((item) => {
1272+
console.log(item);
1273+
});
1274+
});
1275+
1276+
obs.observe({ entryTypes: ['http'] });
1277+
1278+
const PORT = 8080;
1279+
1280+
http.createServer((req, res) => {
1281+
res.end('ok');
1282+
}).listen(PORT, () => {
1283+
http.get(`http://127.0.0.1:${PORT}`);
1284+
});
1285+
```
1286+
12571287
[Async Hooks]: async_hooks.md
12581288
[High Resolution Time]: https://www.w3.org/TR/hr-time-2
12591289
[Performance Timeline]: https://w3c.github.io/performance-timeline/
Collapse file

‎lib/_http_client.js‎

Copy file name to clipboardExpand all lines: lib/_http_client.js
+14-1Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ const Agent = require('_http_agent');
5757
const { Buffer } = require('buffer');
5858
const { defaultTriggerAsyncIdScope } = require('internal/async_hooks');
5959
const { URL, urlToHttpOptions, searchParamsSymbol } = require('internal/url');
60-
const { kOutHeaders, kNeedDrain } = require('internal/http');
60+
const { kOutHeaders, kNeedDrain, emitStatistics } = require('internal/http');
6161
const { connResetException, codes } = require('internal/errors');
6262
const {
6363
ERR_HTTP_HEADERS_SENT,
@@ -75,6 +75,12 @@ const {
7575
DTRACE_HTTP_CLIENT_RESPONSE
7676
} = require('internal/dtrace');
7777

78+
const {
79+
hasObserver,
80+
} = require('internal/perf/observe');
81+
82+
const kClientRequestStatistics = Symbol('ClientRequestStatistics');
83+
7884
const { addAbortSignal, finished } = require('stream');
7985

8086
let debug = require('internal/util/debuglog').debuglog('http', (fn) => {
@@ -337,6 +343,12 @@ ObjectSetPrototypeOf(ClientRequest, OutgoingMessage);
337343
ClientRequest.prototype._finish = function _finish() {
338344
DTRACE_HTTP_CLIENT_REQUEST(this, this.socket);
339345
FunctionPrototypeCall(OutgoingMessage.prototype._finish, this);
346+
if (hasObserver('http')) {
347+
this[kClientRequestStatistics] = {
348+
startTime: process.hrtime(),
349+
type: 'HttpClient',
350+
};
351+
}
340352
};
341353

342354
ClientRequest.prototype._implicitHeader = function _implicitHeader() {
@@ -604,6 +616,7 @@ function parserOnIncomingClient(res, shouldKeepAlive) {
604616
}
605617

606618
DTRACE_HTTP_CLIENT_RESPONSE(socket, req);
619+
emitStatistics(req[kClientRequestStatistics]);
607620
req.res = res;
608621
res.req = req;
609622

Collapse file

‎lib/_http_server.js‎

Copy file name to clipboardExpand all lines: lib/_http_server.js
+2-1Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,8 @@ function ServerResponse(req) {
193193

194194
if (hasObserver('http')) {
195195
this[kServerResponseStatistics] = {
196-
startTime: process.hrtime()
196+
startTime: process.hrtime(),
197+
type: 'HttpRequest',
197198
};
198199
}
199200
}
Collapse file

‎lib/internal/http.js‎

Copy file name to clipboardExpand all lines: lib/internal/http.js
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ function emitStatistics(statistics) {
3838
const startTime = statistics.startTime;
3939
const diff = process.hrtime(startTime);
4040
const entry = new InternalPerformanceEntry(
41-
'HttpRequest',
41+
statistics.type,
4242
'http',
4343
startTime[0] * 1000 + startTime[1] / 1e6,
4444
diff[0] * 1000 + diff[1] / 1e6,
Collapse file

‎test/parallel/test-http-perf_hooks.js‎

Copy file name to clipboardExpand all lines: test/parallel/test-http-perf_hooks.js
+19-6Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,9 @@ const assert = require('assert');
55
const http = require('http');
66

77
const { PerformanceObserver } = require('perf_hooks');
8-
8+
const entries = [];
99
const obs = new PerformanceObserver(common.mustCallAtLeast((items) => {
10-
items.getEntries().forEach((entry) => {
11-
assert.strictEqual(entry.entryType, 'http');
12-
assert.strictEqual(typeof entry.startTime, 'number');
13-
assert.strictEqual(typeof entry.duration, 'number');
14-
});
10+
entries.push(...items.getEntries());
1511
}));
1612

1713
obs.observe({ type: 'http' });
@@ -57,3 +53,20 @@ server.listen(0, common.mustCall(async () => {
5753
]);
5854
server.close();
5955
}));
56+
57+
process.on('exit', () => {
58+
let numberOfHttpClients = 0;
59+
let numberOfHttpRequests = 0;
60+
entries.forEach((entry) => {
61+
assert.strictEqual(entry.entryType, 'http');
62+
assert.strictEqual(typeof entry.startTime, 'number');
63+
assert.strictEqual(typeof entry.duration, 'number');
64+
if (entry.name === 'HttpClient') {
65+
numberOfHttpClients++;
66+
} else if (entry.name === 'HttpRequest') {
67+
numberOfHttpRequests++;
68+
}
69+
});
70+
assert.strictEqual(numberOfHttpClients, 2);
71+
assert.strictEqual(numberOfHttpRequests, 2);
72+
});

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.