Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 826ce2e

Browse files
committedJun 14, 2022
http: add perf_hooks detail for http request and client
1 parent 595ce9d commit 826ce2e

File tree

5 files changed

+71
-39
lines changed

5 files changed

+71
-39
lines changed
 

‎doc/api/perf_hooks.md

+16
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,22 @@ property will be an {Object} with two properties:
521521
* `perf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_ALL_EXTERNAL_MEMORY`
522522
* `perf_hooks.constants.NODE_PERFORMANCE_GC_FLAGS_SCHEDULE_IDLE`
523523

524+
### HTTP ('http') Details
525+
526+
When `performanceEntry.type` is equal to `'http'`, the
527+
`performanceEntry.detail` property will be an {Object} containing
528+
additional information.
529+
530+
If `performanceEntry.name` is equal to `HttpClient`, the `detail`
531+
will contain the following properties: `req`, `res`. And the `req` property
532+
will be an {Object} containing `method`, `url`, `headers`, the `res` property
533+
will be an {Object} containing `statusCode`, `statusMessage`, `headers`.
534+
535+
If `performanceEntry.name` is equal to `HttpRequest`, the `detail`
536+
will contain the following properties: `req`, `res`. And the `req` property
537+
will be an {Object} containing `method`, `url`, `headers`, the `res` property
538+
will be an {Object} containing `statusCode`, `statusMessage`, `headers`.
539+
524540
### HTTP/2 ('http2') Details
525541

526542
When `performanceEntry.type` is equal to `'http2'`, the

‎lib/_http_client.js

+25-8
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ const Agent = require('_http_agent');
6161
const { Buffer } = require('buffer');
6262
const { defaultTriggerAsyncIdScope } = require('internal/async_hooks');
6363
const { URL, urlToHttpOptions, searchParamsSymbol } = require('internal/url');
64-
const { kOutHeaders, kNeedDrain, emitStatistics } = require('internal/http');
64+
const { kOutHeaders, kNeedDrain } = require('internal/http');
6565
const { connResetException, codes } = require('internal/errors');
6666
const {
6767
ERR_HTTP_HEADERS_SENT,
@@ -81,10 +81,10 @@ const {
8181

8282
const {
8383
hasObserver,
84+
startPerf,
85+
stopPerf,
8486
} = require('internal/perf/observe');
8587

86-
const { now } = require('internal/perf/utils');
87-
8888
const kClientRequestStatistics = Symbol('ClientRequestStatistics');
8989

9090
const { addAbortSignal, finished } = require('stream');
@@ -352,10 +352,17 @@ ClientRequest.prototype._finish = function _finish() {
352352
DTRACE_HTTP_CLIENT_REQUEST(this, this.socket);
353353
FunctionPrototypeCall(OutgoingMessage.prototype._finish, this);
354354
if (hasObserver('http')) {
355-
this[kClientRequestStatistics] = {
356-
startTime: now(),
357-
type: 'HttpClient',
358-
};
355+
startPerf(this, kClientRequestStatistics, {
356+
type: 'http',
357+
name: 'HttpClient',
358+
detail: {
359+
req: {
360+
method: this.method,
361+
url: `${this.protocol}//${this.host}${this.path}`,
362+
headers: typeof this.getHeaders === 'function' ? this.getHeaders() : {},
363+
},
364+
},
365+
});
359366
}
360367
};
361368

@@ -624,7 +631,17 @@ function parserOnIncomingClient(res, shouldKeepAlive) {
624631
}
625632

626633
DTRACE_HTTP_CLIENT_RESPONSE(socket, req);
627-
emitStatistics(req[kClientRequestStatistics]);
634+
if (req[kClientRequestStatistics] && hasObserver('http')) {
635+
stopPerf(req, kClientRequestStatistics, {
636+
detail: {
637+
res: {
638+
statusCode: res.statusCode,
639+
statusMessage: res.statusMessage,
640+
headers: res.headers,
641+
},
642+
},
643+
});
644+
}
628645
req.res = res;
629646
res.req = req;
630647

‎lib/_http_server.js

+24-8
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ const {
5555
const {
5656
kOutHeaders,
5757
kNeedDrain,
58-
emitStatistics
5958
} = require('internal/http');
6059
const {
6160
defaultTriggerAsyncIdScope,
@@ -98,10 +97,10 @@ const kServerResponseStatistics = Symbol('ServerResponseStatistics');
9897

9998
const {
10099
hasObserver,
100+
startPerf,
101+
stopPerf,
101102
} = require('internal/perf/observe');
102103

103-
const { now } = require('internal/perf/utils');
104-
105104
const STATUS_CODES = {
106105
100: 'Continue', // RFC 7231 6.2.1
107106
101: 'Switching Protocols', // RFC 7231 6.2.2
@@ -199,18 +198,35 @@ function ServerResponse(req) {
199198
}
200199

201200
if (hasObserver('http')) {
202-
this[kServerResponseStatistics] = {
203-
startTime: now(),
204-
type: 'HttpRequest',
205-
};
201+
startPerf(this, kServerResponseStatistics, {
202+
type: 'http',
203+
name: 'HttpRequest',
204+
detail: {
205+
req: {
206+
method: req.method,
207+
url: req.url,
208+
headers: req.headers,
209+
},
210+
},
211+
});
206212
}
207213
}
208214
ObjectSetPrototypeOf(ServerResponse.prototype, OutgoingMessage.prototype);
209215
ObjectSetPrototypeOf(ServerResponse, OutgoingMessage);
210216

211217
ServerResponse.prototype._finish = function _finish() {
212218
DTRACE_HTTP_SERVER_RESPONSE(this.socket);
213-
emitStatistics(this[kServerResponseStatistics]);
219+
if (this[kServerResponseStatistics] && hasObserver('http')) {
220+
stopPerf(this, kServerResponseStatistics, {
221+
detail: {
222+
res: {
223+
statusCode: this.statusCode,
224+
statusMessage: this.statusMessage,
225+
headers: typeof this.getHeaders === 'function' ? this.getHeaders() : {},
226+
},
227+
},
228+
});
229+
}
214230
OutgoingMessage.prototype._finish.call(this);
215231
};
216232

‎lib/internal/http.js

-23
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,6 @@ const {
99

1010
const { setUnrefTimeout } = require('internal/timers');
1111

12-
const { InternalPerformanceEntry } = require('internal/perf/performance_entry');
13-
14-
const {
15-
enqueue,
16-
hasObserver,
17-
} = require('internal/perf/observe');
18-
19-
const { now } = require('internal/perf/utils');
20-
2112
let utcCache;
2213

2314
function utcDate() {
@@ -35,22 +26,8 @@ function resetCache() {
3526
utcCache = undefined;
3627
}
3728

38-
function emitStatistics(statistics) {
39-
if (!hasObserver('http') || statistics == null) return;
40-
const startTime = statistics.startTime;
41-
const entry = new InternalPerformanceEntry(
42-
statistics.type,
43-
'http',
44-
startTime,
45-
now() - startTime,
46-
undefined,
47-
);
48-
enqueue(entry);
49-
}
50-
5129
module.exports = {
5230
kOutHeaders: Symbol('kOutHeaders'),
5331
kNeedDrain: Symbol('kNeedDrain'),
5432
utcDate,
55-
emitStatistics,
5633
};

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

+6
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,12 @@ process.on('exit', () => {
6666
} else if (entry.name === 'HttpRequest') {
6767
numberOfHttpRequests++;
6868
}
69+
assert.strictEqual(typeof entry.detail.req.method, 'string');
70+
assert.strictEqual(typeof entry.detail.req.url, 'string');
71+
assert.strictEqual(typeof entry.detail.req.headers, 'object');
72+
assert.strictEqual(typeof entry.detail.res.statusCode, 'number');
73+
assert.strictEqual(typeof entry.detail.res.statusMessage, 'string');
74+
assert.strictEqual(typeof entry.detail.res.headers, 'object');
6975
});
7076
assert.strictEqual(numberOfHttpClients, 2);
7177
assert.strictEqual(numberOfHttpRequests, 2);

0 commit comments

Comments
 (0)
Please sign in to comment.