@opentelemetry/instrumentation-http 0.219.0 → 0.221.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -15
- package/build/src/http.d.ts +3 -7
- package/build/src/http.js +49 -80
- package/build/src/http.js.map +1 -1
- package/build/src/semconv.d.ts +0 -222
- package/build/src/semconv.js +1 -223
- package/build/src/semconv.js.map +1 -1
- package/build/src/types.d.ts +5 -1
- package/build/src/types.js.map +1 -1
- package/build/src/utils.d.ts +6 -49
- package/build/src/utils.js +74 -284
- package/build/src/utils.js.map +1 -1
- package/build/src/version.d.ts +1 -1
- package/build/src/version.js +1 -1
- package/build/src/version.js.map +1 -1
- package/package.json +15 -16
- package/build/src/enums/AttributeNames.d.ts +0 -9
- package/build/src/enums/AttributeNames.js +0 -17
- package/build/src/enums/AttributeNames.js.map +0 -1
package/build/src/utils.js
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.headerCapture = exports.getIncomingStableRequestMetricAttributesOnResponse = exports.
|
|
3
|
+
exports.headerCapture = exports.getIncomingStableRequestMetricAttributesOnResponse = exports.getIncomingRequestAttributesOnResponse = exports.getIncomingRequestAttributes = exports.getRemoteClientAddress = exports.getOutgoingStableRequestMetricAttributesOnResponse = exports.getOutgoingRequestAttributesOnResponse = exports.getOutgoingRequestAttributes = exports.extractHostnameAndPort = exports.isValidOptionsType = exports.getRequestInfo = exports.isCompressed = exports.setSpanWithError = exports.satisfiesPattern = exports.parseResponseStatus = exports.getAbsoluteUrl = void 0;
|
|
4
4
|
const api_1 = require("@opentelemetry/api");
|
|
5
5
|
const semantic_conventions_1 = require("@opentelemetry/semantic-conventions");
|
|
6
6
|
const semconv_1 = require("./semconv");
|
|
7
7
|
const core_1 = require("@opentelemetry/core");
|
|
8
|
-
const instrumentation_1 = require("@opentelemetry/instrumentation");
|
|
9
8
|
const url = require("url");
|
|
10
|
-
const AttributeNames_1 = require("./enums/AttributeNames");
|
|
11
9
|
const internal_types_1 = require("./internal-types");
|
|
12
10
|
const internal_types_2 = require("./internal-types");
|
|
13
11
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
@@ -87,66 +85,14 @@ exports.satisfiesPattern = satisfiesPattern;
|
|
|
87
85
|
* Sets the span with the error passed in params
|
|
88
86
|
* @param {Span} span the span that need to be set
|
|
89
87
|
* @param {Error} error error that will be set to span
|
|
90
|
-
* @param {SemconvStability} semconvStability determines which semconv version to use
|
|
91
88
|
*/
|
|
92
|
-
const setSpanWithError = (span, error
|
|
89
|
+
const setSpanWithError = (span, error) => {
|
|
93
90
|
const message = error.message;
|
|
94
|
-
|
|
95
|
-
span.setAttribute(AttributeNames_1.AttributeNames.HTTP_ERROR_NAME, error.name);
|
|
96
|
-
span.setAttribute(AttributeNames_1.AttributeNames.HTTP_ERROR_MESSAGE, message);
|
|
97
|
-
}
|
|
98
|
-
if (semconvStability & instrumentation_1.SemconvStability.STABLE) {
|
|
99
|
-
span.setAttribute(semantic_conventions_1.ATTR_ERROR_TYPE, error.name);
|
|
100
|
-
}
|
|
91
|
+
span.setAttribute(semantic_conventions_1.ATTR_ERROR_TYPE, error.name);
|
|
101
92
|
span.setStatus({ code: api_1.SpanStatusCode.ERROR, message });
|
|
102
93
|
span.recordException(error);
|
|
103
94
|
};
|
|
104
95
|
exports.setSpanWithError = setSpanWithError;
|
|
105
|
-
/**
|
|
106
|
-
* Adds attributes for request content-length and content-encoding HTTP headers
|
|
107
|
-
* @param { IncomingMessage } Request object whose headers will be analyzed
|
|
108
|
-
* @param { Attributes } Attributes object to be modified
|
|
109
|
-
*/
|
|
110
|
-
const setRequestContentLengthAttribute = (request, attributes) => {
|
|
111
|
-
const length = getContentLength(request.headers);
|
|
112
|
-
if (length === null)
|
|
113
|
-
return;
|
|
114
|
-
if ((0, exports.isCompressed)(request.headers)) {
|
|
115
|
-
attributes[semconv_1.ATTR_HTTP_REQUEST_CONTENT_LENGTH] = length;
|
|
116
|
-
}
|
|
117
|
-
else {
|
|
118
|
-
attributes[semconv_1.ATTR_HTTP_REQUEST_CONTENT_LENGTH_UNCOMPRESSED] = length;
|
|
119
|
-
}
|
|
120
|
-
};
|
|
121
|
-
exports.setRequestContentLengthAttribute = setRequestContentLengthAttribute;
|
|
122
|
-
/**
|
|
123
|
-
* Adds attributes for response content-length and content-encoding HTTP headers
|
|
124
|
-
* @param { IncomingMessage } Response object whose headers will be analyzed
|
|
125
|
-
* @param { Attributes } Attributes object to be modified
|
|
126
|
-
*
|
|
127
|
-
* @deprecated this is for an older version of semconv. It is retained for compatibility using OTEL_SEMCONV_STABILITY_OPT_IN
|
|
128
|
-
*/
|
|
129
|
-
const setResponseContentLengthAttribute = (response, attributes) => {
|
|
130
|
-
const length = getContentLength(response.headers);
|
|
131
|
-
if (length === null)
|
|
132
|
-
return;
|
|
133
|
-
if ((0, exports.isCompressed)(response.headers)) {
|
|
134
|
-
attributes[semconv_1.ATTR_HTTP_RESPONSE_CONTENT_LENGTH] = length;
|
|
135
|
-
}
|
|
136
|
-
else {
|
|
137
|
-
attributes[semconv_1.ATTR_HTTP_RESPONSE_CONTENT_LENGTH_UNCOMPRESSED] = length;
|
|
138
|
-
}
|
|
139
|
-
};
|
|
140
|
-
exports.setResponseContentLengthAttribute = setResponseContentLengthAttribute;
|
|
141
|
-
function getContentLength(headers) {
|
|
142
|
-
const contentLengthHeader = headers['content-length'];
|
|
143
|
-
if (contentLengthHeader === undefined)
|
|
144
|
-
return null;
|
|
145
|
-
const contentLength = parseInt(contentLengthHeader, 10);
|
|
146
|
-
if (isNaN(contentLength))
|
|
147
|
-
return null;
|
|
148
|
-
return contentLength;
|
|
149
|
-
}
|
|
150
96
|
const isCompressed = (headers) => {
|
|
151
97
|
const encoding = headers['content-encoding'];
|
|
152
98
|
return !!encoding && encoding !== 'identity';
|
|
@@ -298,9 +244,8 @@ exports.extractHostnameAndPort = extractHostnameAndPort;
|
|
|
298
244
|
* Returns outgoing request attributes scoped to the options passed to the request
|
|
299
245
|
* @param {ParsedRequestOptions} requestOptions the same options used to make the request
|
|
300
246
|
* @param {{ component: string, hostname: string, hookAttributes?: Attributes }} options used to pass data needed to create attributes
|
|
301
|
-
* @param {SemconvStability} semconvStability determines which semconv version to use
|
|
302
247
|
*/
|
|
303
|
-
const getOutgoingRequestAttributes = (requestOptions, options,
|
|
248
|
+
const getOutgoingRequestAttributes = (requestOptions, options, enableSyntheticSourceDetection) => {
|
|
304
249
|
const hostname = options.hostname;
|
|
305
250
|
const port = options.port;
|
|
306
251
|
const method = requestOptions.method ?? 'GET';
|
|
@@ -308,14 +253,7 @@ const getOutgoingRequestAttributes = (requestOptions, options, semconvStability,
|
|
|
308
253
|
const headers = (requestOptions.headers || {});
|
|
309
254
|
const userAgent = headers['user-agent'];
|
|
310
255
|
const urlFull = (0, exports.getAbsoluteUrl)(requestOptions, headers, `${options.component}:`, options.redactedQueryParams);
|
|
311
|
-
const
|
|
312
|
-
[semconv_1.ATTR_HTTP_URL]: urlFull,
|
|
313
|
-
[semconv_1.ATTR_HTTP_METHOD]: method,
|
|
314
|
-
[semconv_1.ATTR_HTTP_TARGET]: requestOptions.path || '/',
|
|
315
|
-
[semconv_1.ATTR_NET_PEER_NAME]: hostname,
|
|
316
|
-
[semconv_1.ATTR_HTTP_HOST]: headers.host ?? `${hostname}:${port}`,
|
|
317
|
-
};
|
|
318
|
-
const newAttributes = {
|
|
256
|
+
const attributes = {
|
|
319
257
|
// Required attributes
|
|
320
258
|
[semantic_conventions_1.ATTR_HTTP_REQUEST_METHOD]: normalizedMethod,
|
|
321
259
|
[semantic_conventions_1.ATTR_SERVER_ADDRESS]: hostname,
|
|
@@ -329,51 +267,14 @@ const getOutgoingRequestAttributes = (requestOptions, options, semconvStability,
|
|
|
329
267
|
};
|
|
330
268
|
// conditionally required if request method required case normalization
|
|
331
269
|
if (method !== normalizedMethod) {
|
|
332
|
-
|
|
270
|
+
attributes[semantic_conventions_1.ATTR_HTTP_REQUEST_METHOD_ORIGINAL] = method;
|
|
333
271
|
}
|
|
334
272
|
if (enableSyntheticSourceDetection && userAgent) {
|
|
335
|
-
|
|
336
|
-
}
|
|
337
|
-
if (userAgent !== undefined) {
|
|
338
|
-
oldAttributes[semconv_1.ATTR_HTTP_USER_AGENT] = userAgent;
|
|
339
|
-
}
|
|
340
|
-
switch (semconvStability) {
|
|
341
|
-
case instrumentation_1.SemconvStability.STABLE:
|
|
342
|
-
return Object.assign(newAttributes, options.hookAttributes);
|
|
343
|
-
case instrumentation_1.SemconvStability.OLD:
|
|
344
|
-
return Object.assign(oldAttributes, options.hookAttributes);
|
|
273
|
+
attributes[semconv_1.ATTR_USER_AGENT_SYNTHETIC_TYPE] = getSyntheticType(userAgent);
|
|
345
274
|
}
|
|
346
|
-
return Object.assign(
|
|
275
|
+
return Object.assign(attributes, options.hookAttributes);
|
|
347
276
|
};
|
|
348
277
|
exports.getOutgoingRequestAttributes = getOutgoingRequestAttributes;
|
|
349
|
-
/**
|
|
350
|
-
* Returns outgoing request Metric attributes scoped to the request data
|
|
351
|
-
* @param {Attributes} spanAttributes the span attributes
|
|
352
|
-
*/
|
|
353
|
-
const getOutgoingRequestMetricAttributes = (spanAttributes) => {
|
|
354
|
-
const metricAttributes = {};
|
|
355
|
-
metricAttributes[semconv_1.ATTR_HTTP_METHOD] = spanAttributes[semconv_1.ATTR_HTTP_METHOD];
|
|
356
|
-
metricAttributes[semconv_1.ATTR_NET_PEER_NAME] = spanAttributes[semconv_1.ATTR_NET_PEER_NAME];
|
|
357
|
-
//TODO: http.url attribute, it should substitute any parameters to avoid high cardinality.
|
|
358
|
-
return metricAttributes;
|
|
359
|
-
};
|
|
360
|
-
exports.getOutgoingRequestMetricAttributes = getOutgoingRequestMetricAttributes;
|
|
361
|
-
/**
|
|
362
|
-
* Returns attributes related to the kind of HTTP protocol used
|
|
363
|
-
* @param {string} [kind] Kind of HTTP protocol used: "1.0", "1.1", "2", "SPDY" or "QUIC".
|
|
364
|
-
*/
|
|
365
|
-
const setAttributesFromHttpKind = (kind, attributes) => {
|
|
366
|
-
if (kind) {
|
|
367
|
-
attributes[semconv_1.ATTR_HTTP_FLAVOR] = kind;
|
|
368
|
-
if (kind.toUpperCase() !== 'QUIC') {
|
|
369
|
-
attributes[semconv_1.ATTR_NET_TRANSPORT] = semconv_1.NET_TRANSPORT_VALUE_IP_TCP;
|
|
370
|
-
}
|
|
371
|
-
else {
|
|
372
|
-
attributes[semconv_1.ATTR_NET_TRANSPORT] = semconv_1.NET_TRANSPORT_VALUE_IP_UDP;
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
};
|
|
376
|
-
exports.setAttributesFromHttpKind = setAttributesFromHttpKind;
|
|
377
278
|
/**
|
|
378
279
|
* Returns the type of synthetic source based on the user agent
|
|
379
280
|
* @param {OutgoingHttpHeader} userAgent the user agent string
|
|
@@ -395,61 +296,41 @@ const getSyntheticType = (userAgent) => {
|
|
|
395
296
|
/**
|
|
396
297
|
* Returns outgoing request attributes scoped to the response data
|
|
397
298
|
* @param {IncomingMessage} response the response object
|
|
398
|
-
* @param {SemconvStability} semconvStability determines which semconv version to use
|
|
399
299
|
*/
|
|
400
|
-
const getOutgoingRequestAttributesOnResponse = (response
|
|
401
|
-
const { statusCode,
|
|
402
|
-
const
|
|
403
|
-
const stableAttributes = {};
|
|
300
|
+
const getOutgoingRequestAttributesOnResponse = (response) => {
|
|
301
|
+
const { statusCode, socket } = response;
|
|
302
|
+
const attributes = {};
|
|
404
303
|
if (statusCode != null) {
|
|
405
|
-
|
|
304
|
+
attributes[semantic_conventions_1.ATTR_HTTP_RESPONSE_STATUS_CODE] = statusCode;
|
|
406
305
|
}
|
|
407
306
|
if (socket) {
|
|
408
307
|
const { remoteAddress, remotePort } = socket;
|
|
409
|
-
oldAttributes[semconv_1.ATTR_NET_PEER_IP] = remoteAddress;
|
|
410
|
-
oldAttributes[semconv_1.ATTR_NET_PEER_PORT] = remotePort;
|
|
411
308
|
// Recommended
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
309
|
+
attributes[semantic_conventions_1.ATTR_NETWORK_PEER_ADDRESS] = remoteAddress;
|
|
310
|
+
attributes[semantic_conventions_1.ATTR_NETWORK_PEER_PORT] = remotePort;
|
|
311
|
+
attributes[semantic_conventions_1.ATTR_NETWORK_PROTOCOL_VERSION] = response.httpVersion;
|
|
415
312
|
}
|
|
416
|
-
|
|
417
|
-
if (statusCode) {
|
|
418
|
-
oldAttributes[semconv_1.ATTR_HTTP_STATUS_CODE] = statusCode;
|
|
419
|
-
oldAttributes[AttributeNames_1.AttributeNames.HTTP_STATUS_TEXT] = (statusMessage || '').toUpperCase();
|
|
420
|
-
}
|
|
421
|
-
(0, exports.setAttributesFromHttpKind)(httpVersion, oldAttributes);
|
|
422
|
-
switch (semconvStability) {
|
|
423
|
-
case instrumentation_1.SemconvStability.STABLE:
|
|
424
|
-
return stableAttributes;
|
|
425
|
-
case instrumentation_1.SemconvStability.OLD:
|
|
426
|
-
return oldAttributes;
|
|
427
|
-
}
|
|
428
|
-
return Object.assign(oldAttributes, stableAttributes);
|
|
313
|
+
return attributes;
|
|
429
314
|
};
|
|
430
315
|
exports.getOutgoingRequestAttributesOnResponse = getOutgoingRequestAttributesOnResponse;
|
|
431
316
|
/**
|
|
432
317
|
* Returns outgoing request Metric attributes scoped to the response data
|
|
433
318
|
* @param {Attributes} spanAttributes the span attributes
|
|
434
319
|
*/
|
|
435
|
-
const getOutgoingRequestMetricAttributesOnResponse = (spanAttributes) => {
|
|
436
|
-
const metricAttributes = {};
|
|
437
|
-
metricAttributes[semconv_1.ATTR_NET_PEER_PORT] = spanAttributes[semconv_1.ATTR_NET_PEER_PORT];
|
|
438
|
-
metricAttributes[semconv_1.ATTR_HTTP_STATUS_CODE] =
|
|
439
|
-
spanAttributes[semconv_1.ATTR_HTTP_STATUS_CODE];
|
|
440
|
-
metricAttributes[semconv_1.ATTR_HTTP_FLAVOR] = spanAttributes[semconv_1.ATTR_HTTP_FLAVOR];
|
|
441
|
-
return metricAttributes;
|
|
442
|
-
};
|
|
443
|
-
exports.getOutgoingRequestMetricAttributesOnResponse = getOutgoingRequestMetricAttributesOnResponse;
|
|
444
320
|
const getOutgoingStableRequestMetricAttributesOnResponse = (spanAttributes) => {
|
|
445
321
|
const metricAttributes = {};
|
|
446
322
|
if (spanAttributes[semantic_conventions_1.ATTR_NETWORK_PROTOCOL_VERSION]) {
|
|
447
323
|
metricAttributes[semantic_conventions_1.ATTR_NETWORK_PROTOCOL_VERSION] =
|
|
448
324
|
spanAttributes[semantic_conventions_1.ATTR_NETWORK_PROTOCOL_VERSION];
|
|
449
325
|
}
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
326
|
+
const statusCode = spanAttributes[semantic_conventions_1.ATTR_HTTP_RESPONSE_STATUS_CODE];
|
|
327
|
+
if (statusCode) {
|
|
328
|
+
metricAttributes[semantic_conventions_1.ATTR_HTTP_RESPONSE_STATUS_CODE] = statusCode;
|
|
329
|
+
if (typeof statusCode === 'number' &&
|
|
330
|
+
statusCode >= 400 &&
|
|
331
|
+
statusCode < 600) {
|
|
332
|
+
metricAttributes[semantic_conventions_1.ATTR_ERROR_TYPE] ??= String(statusCode);
|
|
333
|
+
}
|
|
453
334
|
}
|
|
454
335
|
return metricAttributes;
|
|
455
336
|
};
|
|
@@ -618,154 +499,65 @@ function getInfoFromIncomingMessage(component, request, logger) {
|
|
|
618
499
|
/**
|
|
619
500
|
* Returns incoming request attributes scoped to the request data
|
|
620
501
|
* @param {IncomingMessage} request the request object
|
|
621
|
-
* @param {{ component: string,
|
|
622
|
-
* @param {SemconvStability} semconvStability determines which semconv version to use
|
|
502
|
+
* @param {{ component: string, hookAttributes?: Attributes, enableSyntheticSourceDetection: boolean }} options used to pass data needed to create attributes
|
|
623
503
|
*/
|
|
624
504
|
const getIncomingRequestAttributes = (request, options, logger) => {
|
|
625
|
-
const { component, enableSyntheticSourceDetection, hookAttributes
|
|
626
|
-
const { headers,
|
|
627
|
-
const {
|
|
505
|
+
const { component, enableSyntheticSourceDetection, hookAttributes } = options;
|
|
506
|
+
const { headers, method } = request;
|
|
507
|
+
const { 'user-agent': userAgent } = headers;
|
|
628
508
|
const parsedUrl = getInfoFromIncomingMessage(component, request, logger);
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
};
|
|
645
|
-
if (parsedUrl.pathname != null) {
|
|
646
|
-
newAttributes[semantic_conventions_1.ATTR_URL_PATH] = parsedUrl.pathname;
|
|
647
|
-
}
|
|
648
|
-
if (parsedUrl.search) {
|
|
649
|
-
// Remove leading '?' from URL search (https://developer.mozilla.org/en-US/docs/Web/API/URL/search).
|
|
650
|
-
newAttributes[semantic_conventions_1.ATTR_URL_QUERY] = parsedUrl.search.slice(1);
|
|
651
|
-
}
|
|
652
|
-
if (remoteClientAddress != null) {
|
|
653
|
-
newAttributes[semantic_conventions_1.ATTR_CLIENT_ADDRESS] = remoteClientAddress;
|
|
654
|
-
}
|
|
655
|
-
if (serverAddress?.port != null) {
|
|
656
|
-
newAttributes[semantic_conventions_1.ATTR_SERVER_PORT] = Number(serverAddress.port);
|
|
657
|
-
}
|
|
658
|
-
// Conditionally required if request method required case normalization.
|
|
659
|
-
if (method !== normalizedMethod) {
|
|
660
|
-
newAttributes[semantic_conventions_1.ATTR_HTTP_REQUEST_METHOD_ORIGINAL] = method;
|
|
661
|
-
}
|
|
662
|
-
if (enableSyntheticSourceDetection && userAgent) {
|
|
663
|
-
newAttributes[semconv_1.ATTR_USER_AGENT_SYNTHETIC_TYPE] =
|
|
664
|
-
getSyntheticType(userAgent);
|
|
665
|
-
}
|
|
509
|
+
// Stable attributes are used.
|
|
510
|
+
const normalizedMethod = normalizeMethod(method);
|
|
511
|
+
const serverAddress = getServerAddress(request, component);
|
|
512
|
+
const remoteClientAddress = getRemoteClientAddress(request);
|
|
513
|
+
const attributes = {
|
|
514
|
+
[semantic_conventions_1.ATTR_HTTP_REQUEST_METHOD]: normalizedMethod,
|
|
515
|
+
[semantic_conventions_1.ATTR_URL_SCHEME]: component,
|
|
516
|
+
[semantic_conventions_1.ATTR_SERVER_ADDRESS]: serverAddress?.host,
|
|
517
|
+
[semantic_conventions_1.ATTR_NETWORK_PEER_ADDRESS]: request.socket.remoteAddress,
|
|
518
|
+
[semantic_conventions_1.ATTR_NETWORK_PEER_PORT]: request.socket.remotePort,
|
|
519
|
+
[semantic_conventions_1.ATTR_NETWORK_PROTOCOL_VERSION]: request.httpVersion,
|
|
520
|
+
[semantic_conventions_1.ATTR_USER_AGENT_ORIGINAL]: userAgent,
|
|
521
|
+
};
|
|
522
|
+
if (parsedUrl.pathname != null) {
|
|
523
|
+
attributes[semantic_conventions_1.ATTR_URL_PATH] = parsedUrl.pathname;
|
|
666
524
|
}
|
|
667
|
-
if (
|
|
668
|
-
//
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
};
|
|
677
|
-
if (typeof ips === 'string') {
|
|
678
|
-
oldAttributes[semconv_1.ATTR_HTTP_CLIENT_IP] = ips.split(',')[0];
|
|
679
|
-
}
|
|
680
|
-
if (typeof serverName === 'string') {
|
|
681
|
-
oldAttributes[semconv_1.ATTR_HTTP_SERVER_NAME] = serverName;
|
|
682
|
-
}
|
|
683
|
-
if (parsedUrl.pathname) {
|
|
684
|
-
oldAttributes[semconv_1.ATTR_HTTP_TARGET] =
|
|
685
|
-
parsedUrl.pathname + parsedUrl.search || '/';
|
|
686
|
-
}
|
|
687
|
-
if (userAgent !== undefined) {
|
|
688
|
-
oldAttributes[semconv_1.ATTR_HTTP_USER_AGENT] = userAgent;
|
|
689
|
-
}
|
|
690
|
-
(0, exports.setRequestContentLengthAttribute)(request, oldAttributes);
|
|
691
|
-
(0, exports.setAttributesFromHttpKind)(httpVersion, oldAttributes);
|
|
525
|
+
if (parsedUrl.search) {
|
|
526
|
+
// Remove leading '?' from URL search (https://developer.mozilla.org/en-US/docs/Web/API/URL/search).
|
|
527
|
+
attributes[semantic_conventions_1.ATTR_URL_QUERY] = parsedUrl.search.slice(1);
|
|
528
|
+
}
|
|
529
|
+
if (remoteClientAddress != null) {
|
|
530
|
+
attributes[semantic_conventions_1.ATTR_CLIENT_ADDRESS] = remoteClientAddress;
|
|
531
|
+
}
|
|
532
|
+
if (serverAddress?.port != null) {
|
|
533
|
+
attributes[semantic_conventions_1.ATTR_SERVER_PORT] = Number(serverAddress.port);
|
|
692
534
|
}
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
return Object.assign(oldAttributes, newAttributes, hookAttributes);
|
|
535
|
+
// Conditionally required if request method required case normalization.
|
|
536
|
+
if (method !== normalizedMethod) {
|
|
537
|
+
attributes[semantic_conventions_1.ATTR_HTTP_REQUEST_METHOD_ORIGINAL] = method;
|
|
538
|
+
}
|
|
539
|
+
if (enableSyntheticSourceDetection && userAgent) {
|
|
540
|
+
attributes[semconv_1.ATTR_USER_AGENT_SYNTHETIC_TYPE] = getSyntheticType(userAgent);
|
|
700
541
|
}
|
|
542
|
+
return Object.assign(attributes, hookAttributes);
|
|
701
543
|
};
|
|
702
544
|
exports.getIncomingRequestAttributes = getIncomingRequestAttributes;
|
|
703
|
-
/**
|
|
704
|
-
* Returns incoming request Metric attributes scoped to the request data
|
|
705
|
-
* @param {Attributes} spanAttributes the span attributes
|
|
706
|
-
* @param {{ component: string }} options used to pass data needed to create attributes
|
|
707
|
-
*/
|
|
708
|
-
const getIncomingRequestMetricAttributes = (spanAttributes) => {
|
|
709
|
-
const metricAttributes = {};
|
|
710
|
-
metricAttributes[semconv_1.ATTR_HTTP_SCHEME] = spanAttributes[semconv_1.ATTR_HTTP_SCHEME];
|
|
711
|
-
metricAttributes[semconv_1.ATTR_HTTP_METHOD] = spanAttributes[semconv_1.ATTR_HTTP_METHOD];
|
|
712
|
-
metricAttributes[semconv_1.ATTR_NET_HOST_NAME] = spanAttributes[semconv_1.ATTR_NET_HOST_NAME];
|
|
713
|
-
metricAttributes[semconv_1.ATTR_HTTP_FLAVOR] = spanAttributes[semconv_1.ATTR_HTTP_FLAVOR];
|
|
714
|
-
//TODO: http.target attribute, it should substitute any parameters to avoid high cardinality.
|
|
715
|
-
return metricAttributes;
|
|
716
|
-
};
|
|
717
|
-
exports.getIncomingRequestMetricAttributes = getIncomingRequestMetricAttributes;
|
|
718
545
|
/**
|
|
719
546
|
* Returns incoming request attributes scoped to the response data
|
|
720
547
|
* @param {(ServerResponse & { socket: Socket; })} response the response object
|
|
721
548
|
*/
|
|
722
|
-
const getIncomingRequestAttributesOnResponse = (
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
const { socket } = request;
|
|
726
|
-
const { statusCode, statusMessage } = response;
|
|
727
|
-
const newAttributes = {
|
|
549
|
+
const getIncomingRequestAttributesOnResponse = (response) => {
|
|
550
|
+
const { statusCode } = response;
|
|
551
|
+
const attributes = {
|
|
728
552
|
[semantic_conventions_1.ATTR_HTTP_RESPONSE_STATUS_CODE]: statusCode,
|
|
729
553
|
};
|
|
730
554
|
const rpcMetadata = (0, core_1.getRPCMetadata)(api_1.context.active());
|
|
731
|
-
const oldAttributes = {};
|
|
732
|
-
if (socket) {
|
|
733
|
-
const { localAddress, localPort, remoteAddress, remotePort } = socket;
|
|
734
|
-
oldAttributes[semconv_1.ATTR_NET_HOST_IP] = localAddress;
|
|
735
|
-
oldAttributes[semconv_1.ATTR_NET_HOST_PORT] = localPort;
|
|
736
|
-
oldAttributes[semconv_1.ATTR_NET_PEER_IP] = remoteAddress;
|
|
737
|
-
oldAttributes[semconv_1.ATTR_NET_PEER_PORT] = remotePort;
|
|
738
|
-
}
|
|
739
|
-
oldAttributes[semconv_1.ATTR_HTTP_STATUS_CODE] = statusCode;
|
|
740
|
-
oldAttributes[AttributeNames_1.AttributeNames.HTTP_STATUS_TEXT] = (statusMessage || '').toUpperCase();
|
|
741
555
|
if (rpcMetadata?.type === core_1.RPCType.HTTP && rpcMetadata.route !== undefined) {
|
|
742
|
-
|
|
743
|
-
newAttributes[semantic_conventions_1.ATTR_HTTP_ROUTE] = rpcMetadata.route;
|
|
556
|
+
attributes[semantic_conventions_1.ATTR_HTTP_ROUTE] = rpcMetadata.route;
|
|
744
557
|
}
|
|
745
|
-
|
|
746
|
-
case instrumentation_1.SemconvStability.STABLE:
|
|
747
|
-
return newAttributes;
|
|
748
|
-
case instrumentation_1.SemconvStability.OLD:
|
|
749
|
-
return oldAttributes;
|
|
750
|
-
}
|
|
751
|
-
return Object.assign(oldAttributes, newAttributes);
|
|
558
|
+
return attributes;
|
|
752
559
|
};
|
|
753
560
|
exports.getIncomingRequestAttributesOnResponse = getIncomingRequestAttributesOnResponse;
|
|
754
|
-
/**
|
|
755
|
-
* Returns incoming request Metric attributes scoped to the request data
|
|
756
|
-
* @param {Attributes} spanAttributes the span attributes
|
|
757
|
-
*/
|
|
758
|
-
const getIncomingRequestMetricAttributesOnResponse = (spanAttributes) => {
|
|
759
|
-
const metricAttributes = {};
|
|
760
|
-
metricAttributes[semconv_1.ATTR_HTTP_STATUS_CODE] =
|
|
761
|
-
spanAttributes[semconv_1.ATTR_HTTP_STATUS_CODE];
|
|
762
|
-
metricAttributes[semconv_1.ATTR_NET_HOST_PORT] = spanAttributes[semconv_1.ATTR_NET_HOST_PORT];
|
|
763
|
-
if (spanAttributes[semantic_conventions_1.ATTR_HTTP_ROUTE] !== undefined) {
|
|
764
|
-
metricAttributes[semantic_conventions_1.ATTR_HTTP_ROUTE] = spanAttributes[semantic_conventions_1.ATTR_HTTP_ROUTE];
|
|
765
|
-
}
|
|
766
|
-
return metricAttributes;
|
|
767
|
-
};
|
|
768
|
-
exports.getIncomingRequestMetricAttributesOnResponse = getIncomingRequestMetricAttributesOnResponse;
|
|
769
561
|
/**
|
|
770
562
|
* Returns incoming stable request Metric attributes scoped to the request data
|
|
771
563
|
* @param {Attributes} spanAttributes the span attributes
|
|
@@ -776,25 +568,23 @@ const getIncomingStableRequestMetricAttributesOnResponse = (spanAttributes) => {
|
|
|
776
568
|
metricAttributes[semantic_conventions_1.ATTR_HTTP_ROUTE] = spanAttributes[semantic_conventions_1.ATTR_HTTP_ROUTE];
|
|
777
569
|
}
|
|
778
570
|
// required if and only if one was sent, same as span requirement
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
571
|
+
const statusCode = spanAttributes[semantic_conventions_1.ATTR_HTTP_RESPONSE_STATUS_CODE];
|
|
572
|
+
if (statusCode) {
|
|
573
|
+
metricAttributes[semantic_conventions_1.ATTR_HTTP_RESPONSE_STATUS_CODE] = statusCode;
|
|
574
|
+
if (typeof statusCode === 'number' &&
|
|
575
|
+
statusCode >= 500 &&
|
|
576
|
+
statusCode < 600) {
|
|
577
|
+
metricAttributes[semantic_conventions_1.ATTR_ERROR_TYPE] ??= String(statusCode);
|
|
578
|
+
}
|
|
782
579
|
}
|
|
783
580
|
return metricAttributes;
|
|
784
581
|
};
|
|
785
582
|
exports.getIncomingStableRequestMetricAttributesOnResponse = getIncomingStableRequestMetricAttributesOnResponse;
|
|
786
|
-
function headerCapture(type, headers
|
|
583
|
+
function headerCapture(type, headers) {
|
|
787
584
|
const normalizedHeaders = new Map();
|
|
788
585
|
for (let i = 0, len = headers.length; i < len; i++) {
|
|
789
586
|
const capturedHeader = headers[i].toLowerCase();
|
|
790
|
-
|
|
791
|
-
normalizedHeaders.set(capturedHeader, capturedHeader);
|
|
792
|
-
}
|
|
793
|
-
else {
|
|
794
|
-
// In old semconv, the header name converted hypen to underscore, e.g.:
|
|
795
|
-
// `http.request.header.content_length`.
|
|
796
|
-
normalizedHeaders.set(capturedHeader, capturedHeader.replaceAll('-', '_'));
|
|
797
|
-
}
|
|
587
|
+
normalizedHeaders.set(capturedHeader, capturedHeader);
|
|
798
588
|
}
|
|
799
589
|
return (getHeader) => {
|
|
800
590
|
const attributes = {};
|