@opentelemetry/instrumentation-http 0.200.0 → 0.201.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 +57 -71
- package/build/src/http.js +9 -21
- package/build/src/http.js.map +1 -1
- package/build/src/internal-types.d.ts +6 -12
- package/build/src/internal-types.js +9 -0
- package/build/src/internal-types.js.map +1 -1
- package/build/src/semconv.d.ts +239 -0
- package/build/src/semconv.js +262 -0
- package/build/src/semconv.js.map +1 -0
- package/build/src/types.d.ts +5 -0
- package/build/src/types.js.map +1 -1
- package/build/src/utils.d.ts +9 -2
- package/build/src/utils.js +100 -57
- 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 +9 -9
package/build/src/utils.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.headerCapture = exports.getIncomingStableRequestMetricAttributesOnResponse = exports.getIncomingRequestMetricAttributesOnResponse = exports.getIncomingRequestAttributesOnResponse = exports.getIncomingRequestMetricAttributes = exports.getIncomingRequestAttributes = exports.getRemoteClientAddress = exports.getOutgoingRequestMetricAttributesOnResponse = exports.getOutgoingRequestAttributesOnResponse = exports.setAttributesFromHttpKind = exports.getOutgoingRequestMetricAttributes = exports.getOutgoingRequestAttributes = exports.extractHostnameAndPort = exports.isValidOptionsType = exports.getRequestInfo = exports.isCompressed = exports.setResponseContentLengthAttribute = exports.setRequestContentLengthAttribute = exports.setSpanWithError = exports.satisfiesPattern = exports.parseResponseStatus = exports.getAbsoluteUrl = void 0;
|
|
3
|
+
exports.headerCapture = exports.getIncomingStableRequestMetricAttributesOnResponse = exports.getIncomingRequestMetricAttributesOnResponse = exports.getIncomingRequestAttributesOnResponse = exports.getIncomingRequestMetricAttributes = exports.getIncomingRequestAttributes = exports.getRemoteClientAddress = exports.getOutgoingStableRequestMetricAttributesOnResponse = exports.getOutgoingRequestMetricAttributesOnResponse = exports.getOutgoingRequestAttributesOnResponse = exports.setAttributesFromHttpKind = exports.getOutgoingRequestMetricAttributes = exports.getOutgoingRequestAttributes = exports.extractHostnameAndPort = exports.isValidOptionsType = exports.getRequestInfo = exports.isCompressed = exports.setResponseContentLengthAttribute = exports.setRequestContentLengthAttribute = exports.setSpanWithError = exports.satisfiesPattern = exports.parseResponseStatus = exports.getAbsoluteUrl = void 0;
|
|
4
4
|
/*
|
|
5
5
|
* Copyright The OpenTelemetry Authors
|
|
6
6
|
*
|
|
@@ -18,9 +18,11 @@ exports.headerCapture = exports.getIncomingStableRequestMetricAttributesOnRespon
|
|
|
18
18
|
*/
|
|
19
19
|
const api_1 = require("@opentelemetry/api");
|
|
20
20
|
const semantic_conventions_1 = require("@opentelemetry/semantic-conventions");
|
|
21
|
+
const semconv_1 = require("./semconv");
|
|
21
22
|
const core_1 = require("@opentelemetry/core");
|
|
22
23
|
const url = require("url");
|
|
23
24
|
const AttributeNames_1 = require("./enums/AttributeNames");
|
|
25
|
+
const internal_types_1 = require("./internal-types");
|
|
24
26
|
const forwardedParse = require("forwarded-parse");
|
|
25
27
|
/**
|
|
26
28
|
* Get an absolute url
|
|
@@ -84,12 +86,11 @@ exports.satisfiesPattern = satisfiesPattern;
|
|
|
84
86
|
*/
|
|
85
87
|
const setSpanWithError = (span, error, semconvStability) => {
|
|
86
88
|
const message = error.message;
|
|
87
|
-
if (
|
|
89
|
+
if (semconvStability & 2 /* SemconvStability.OLD */) {
|
|
88
90
|
span.setAttribute(AttributeNames_1.AttributeNames.HTTP_ERROR_NAME, error.name);
|
|
89
91
|
span.setAttribute(AttributeNames_1.AttributeNames.HTTP_ERROR_MESSAGE, message);
|
|
90
92
|
}
|
|
91
|
-
if (
|
|
92
|
-
1 /* SemconvStability.STABLE */) {
|
|
93
|
+
if (semconvStability & 1 /* SemconvStability.STABLE */) {
|
|
93
94
|
span.setAttribute(semantic_conventions_1.ATTR_ERROR_TYPE, error.name);
|
|
94
95
|
}
|
|
95
96
|
span.setStatus({ code: api_1.SpanStatusCode.ERROR, message });
|
|
@@ -106,10 +107,10 @@ const setRequestContentLengthAttribute = (request, attributes) => {
|
|
|
106
107
|
if (length === null)
|
|
107
108
|
return;
|
|
108
109
|
if ((0, exports.isCompressed)(request.headers)) {
|
|
109
|
-
attributes[
|
|
110
|
+
attributes[semconv_1.ATTR_HTTP_REQUEST_CONTENT_LENGTH] = length;
|
|
110
111
|
}
|
|
111
112
|
else {
|
|
112
|
-
attributes[
|
|
113
|
+
attributes[semconv_1.ATTR_HTTP_REQUEST_CONTENT_LENGTH_UNCOMPRESSED] = length;
|
|
113
114
|
}
|
|
114
115
|
};
|
|
115
116
|
exports.setRequestContentLengthAttribute = setRequestContentLengthAttribute;
|
|
@@ -125,10 +126,10 @@ const setResponseContentLengthAttribute = (response, attributes) => {
|
|
|
125
126
|
if (length === null)
|
|
126
127
|
return;
|
|
127
128
|
if ((0, exports.isCompressed)(response.headers)) {
|
|
128
|
-
attributes[
|
|
129
|
+
attributes[semconv_1.ATTR_HTTP_RESPONSE_CONTENT_LENGTH] = length;
|
|
129
130
|
}
|
|
130
131
|
else {
|
|
131
|
-
attributes[
|
|
132
|
+
attributes[semconv_1.ATTR_HTTP_RESPONSE_CONTENT_LENGTH_UNCOMPRESSED] = length;
|
|
132
133
|
}
|
|
133
134
|
};
|
|
134
135
|
exports.setResponseContentLengthAttribute = setResponseContentLengthAttribute;
|
|
@@ -294,7 +295,7 @@ exports.extractHostnameAndPort = extractHostnameAndPort;
|
|
|
294
295
|
* @param {{ component: string, hostname: string, hookAttributes?: Attributes }} options used to pass data needed to create attributes
|
|
295
296
|
* @param {SemconvStability} semconvStability determines which semconv version to use
|
|
296
297
|
*/
|
|
297
|
-
const getOutgoingRequestAttributes = (requestOptions, options, semconvStability) => {
|
|
298
|
+
const getOutgoingRequestAttributes = (requestOptions, options, semconvStability, enableSyntheticSourceDetection) => {
|
|
298
299
|
const hostname = options.hostname;
|
|
299
300
|
const port = options.port;
|
|
300
301
|
const method = requestOptions.method ?? 'GET';
|
|
@@ -303,11 +304,11 @@ const getOutgoingRequestAttributes = (requestOptions, options, semconvStability)
|
|
|
303
304
|
const userAgent = headers['user-agent'];
|
|
304
305
|
const urlFull = (0, exports.getAbsoluteUrl)(requestOptions, headers, `${options.component}:`);
|
|
305
306
|
const oldAttributes = {
|
|
306
|
-
[
|
|
307
|
-
[
|
|
308
|
-
[
|
|
309
|
-
[
|
|
310
|
-
[
|
|
307
|
+
[semconv_1.ATTR_HTTP_URL]: urlFull,
|
|
308
|
+
[semconv_1.ATTR_HTTP_METHOD]: method,
|
|
309
|
+
[semconv_1.ATTR_HTTP_TARGET]: requestOptions.path || '/',
|
|
310
|
+
[semconv_1.ATTR_NET_PEER_NAME]: hostname,
|
|
311
|
+
[semconv_1.ATTR_HTTP_HOST]: headers.host ?? `${hostname}:${port}`,
|
|
311
312
|
};
|
|
312
313
|
const newAttributes = {
|
|
313
314
|
// Required attributes
|
|
@@ -315,6 +316,7 @@ const getOutgoingRequestAttributes = (requestOptions, options, semconvStability)
|
|
|
315
316
|
[semantic_conventions_1.ATTR_SERVER_ADDRESS]: hostname,
|
|
316
317
|
[semantic_conventions_1.ATTR_SERVER_PORT]: Number(port),
|
|
317
318
|
[semantic_conventions_1.ATTR_URL_FULL]: urlFull,
|
|
319
|
+
[semantic_conventions_1.ATTR_USER_AGENT_ORIGINAL]: userAgent,
|
|
318
320
|
// leaving out protocol version, it is not yet negotiated
|
|
319
321
|
// leaving out protocol name, it is only required when protocol version is set
|
|
320
322
|
// retries and redirects not supported
|
|
@@ -324,8 +326,11 @@ const getOutgoingRequestAttributes = (requestOptions, options, semconvStability)
|
|
|
324
326
|
if (method !== normalizedMethod) {
|
|
325
327
|
newAttributes[semantic_conventions_1.ATTR_HTTP_REQUEST_METHOD_ORIGINAL] = method;
|
|
326
328
|
}
|
|
329
|
+
if (enableSyntheticSourceDetection && userAgent) {
|
|
330
|
+
newAttributes[semconv_1.ATTR_USER_AGENT_SYNTHETIC_TYPE] = getSyntheticType(userAgent);
|
|
331
|
+
}
|
|
327
332
|
if (userAgent !== undefined) {
|
|
328
|
-
oldAttributes[
|
|
333
|
+
oldAttributes[semconv_1.ATTR_HTTP_USER_AGENT] = userAgent;
|
|
329
334
|
}
|
|
330
335
|
switch (semconvStability) {
|
|
331
336
|
case 1 /* SemconvStability.STABLE */:
|
|
@@ -342,9 +347,8 @@ exports.getOutgoingRequestAttributes = getOutgoingRequestAttributes;
|
|
|
342
347
|
*/
|
|
343
348
|
const getOutgoingRequestMetricAttributes = (spanAttributes) => {
|
|
344
349
|
const metricAttributes = {};
|
|
345
|
-
metricAttributes[
|
|
346
|
-
metricAttributes[
|
|
347
|
-
spanAttributes[semantic_conventions_1.SEMATTRS_NET_PEER_NAME];
|
|
350
|
+
metricAttributes[semconv_1.ATTR_HTTP_METHOD] = spanAttributes[semconv_1.ATTR_HTTP_METHOD];
|
|
351
|
+
metricAttributes[semconv_1.ATTR_NET_PEER_NAME] = spanAttributes[semconv_1.ATTR_NET_PEER_NAME];
|
|
348
352
|
//TODO: http.url attribute, it should substitute any parameters to avoid high cardinality.
|
|
349
353
|
return metricAttributes;
|
|
350
354
|
};
|
|
@@ -355,16 +359,34 @@ exports.getOutgoingRequestMetricAttributes = getOutgoingRequestMetricAttributes;
|
|
|
355
359
|
*/
|
|
356
360
|
const setAttributesFromHttpKind = (kind, attributes) => {
|
|
357
361
|
if (kind) {
|
|
358
|
-
attributes[
|
|
362
|
+
attributes[semconv_1.ATTR_HTTP_FLAVOR] = kind;
|
|
359
363
|
if (kind.toUpperCase() !== 'QUIC') {
|
|
360
|
-
attributes[
|
|
364
|
+
attributes[semconv_1.ATTR_NET_TRANSPORT] = semconv_1.NET_TRANSPORT_VALUE_IP_TCP;
|
|
361
365
|
}
|
|
362
366
|
else {
|
|
363
|
-
attributes[
|
|
367
|
+
attributes[semconv_1.ATTR_NET_TRANSPORT] = semconv_1.NET_TRANSPORT_VALUE_IP_UDP;
|
|
364
368
|
}
|
|
365
369
|
}
|
|
366
370
|
};
|
|
367
371
|
exports.setAttributesFromHttpKind = setAttributesFromHttpKind;
|
|
372
|
+
/**
|
|
373
|
+
* Returns the type of synthetic source based on the user agent
|
|
374
|
+
* @param {OutgoingHttpHeader} userAgent the user agent string
|
|
375
|
+
*/
|
|
376
|
+
const getSyntheticType = (userAgent) => {
|
|
377
|
+
const userAgentString = String(userAgent).toLowerCase();
|
|
378
|
+
for (const name of internal_types_1.SYNTHETIC_TEST_NAMES) {
|
|
379
|
+
if (userAgentString.includes(name)) {
|
|
380
|
+
return semconv_1.USER_AGENT_SYNTHETIC_TYPE_VALUE_TEST;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
for (const name of internal_types_1.SYNTHETIC_BOT_NAMES) {
|
|
384
|
+
if (userAgentString.includes(name)) {
|
|
385
|
+
return semconv_1.USER_AGENT_SYNTHETIC_TYPE_VALUE_BOT;
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
return;
|
|
389
|
+
};
|
|
368
390
|
/**
|
|
369
391
|
* Returns outgoing request attributes scoped to the response data
|
|
370
392
|
* @param {IncomingMessage} response the response object
|
|
@@ -379,8 +401,8 @@ const getOutgoingRequestAttributesOnResponse = (response, semconvStability) => {
|
|
|
379
401
|
}
|
|
380
402
|
if (socket) {
|
|
381
403
|
const { remoteAddress, remotePort } = socket;
|
|
382
|
-
oldAttributes[
|
|
383
|
-
oldAttributes[
|
|
404
|
+
oldAttributes[semconv_1.ATTR_NET_PEER_IP] = remoteAddress;
|
|
405
|
+
oldAttributes[semconv_1.ATTR_NET_PEER_PORT] = remotePort;
|
|
384
406
|
// Recommended
|
|
385
407
|
stableAttributes[semantic_conventions_1.ATTR_NETWORK_PEER_ADDRESS] = remoteAddress;
|
|
386
408
|
stableAttributes[semantic_conventions_1.ATTR_NETWORK_PEER_PORT] = remotePort;
|
|
@@ -388,7 +410,7 @@ const getOutgoingRequestAttributesOnResponse = (response, semconvStability) => {
|
|
|
388
410
|
}
|
|
389
411
|
(0, exports.setResponseContentLengthAttribute)(response, oldAttributes);
|
|
390
412
|
if (statusCode) {
|
|
391
|
-
oldAttributes[
|
|
413
|
+
oldAttributes[semconv_1.ATTR_HTTP_STATUS_CODE] = statusCode;
|
|
392
414
|
oldAttributes[AttributeNames_1.AttributeNames.HTTP_STATUS_TEXT] = (statusMessage || '').toUpperCase();
|
|
393
415
|
}
|
|
394
416
|
(0, exports.setAttributesFromHttpKind)(httpVersion, oldAttributes);
|
|
@@ -407,14 +429,26 @@ exports.getOutgoingRequestAttributesOnResponse = getOutgoingRequestAttributesOnR
|
|
|
407
429
|
*/
|
|
408
430
|
const getOutgoingRequestMetricAttributesOnResponse = (spanAttributes) => {
|
|
409
431
|
const metricAttributes = {};
|
|
410
|
-
metricAttributes[
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
metricAttributes[semantic_conventions_1.SEMATTRS_HTTP_FLAVOR] = spanAttributes[semantic_conventions_1.SEMATTRS_HTTP_FLAVOR];
|
|
432
|
+
metricAttributes[semconv_1.ATTR_NET_PEER_PORT] = spanAttributes[semconv_1.ATTR_NET_PEER_PORT];
|
|
433
|
+
metricAttributes[semconv_1.ATTR_HTTP_STATUS_CODE] =
|
|
434
|
+
spanAttributes[semconv_1.ATTR_HTTP_STATUS_CODE];
|
|
435
|
+
metricAttributes[semconv_1.ATTR_HTTP_FLAVOR] = spanAttributes[semconv_1.ATTR_HTTP_FLAVOR];
|
|
415
436
|
return metricAttributes;
|
|
416
437
|
};
|
|
417
438
|
exports.getOutgoingRequestMetricAttributesOnResponse = getOutgoingRequestMetricAttributesOnResponse;
|
|
439
|
+
const getOutgoingStableRequestMetricAttributesOnResponse = (spanAttributes) => {
|
|
440
|
+
const metricAttributes = {};
|
|
441
|
+
if (spanAttributes[semantic_conventions_1.ATTR_NETWORK_PROTOCOL_VERSION]) {
|
|
442
|
+
metricAttributes[semantic_conventions_1.ATTR_NETWORK_PROTOCOL_VERSION] =
|
|
443
|
+
spanAttributes[semantic_conventions_1.ATTR_NETWORK_PROTOCOL_VERSION];
|
|
444
|
+
}
|
|
445
|
+
if (spanAttributes[semantic_conventions_1.ATTR_HTTP_RESPONSE_STATUS_CODE]) {
|
|
446
|
+
metricAttributes[semantic_conventions_1.ATTR_HTTP_RESPONSE_STATUS_CODE] =
|
|
447
|
+
spanAttributes[semantic_conventions_1.ATTR_HTTP_RESPONSE_STATUS_CODE];
|
|
448
|
+
}
|
|
449
|
+
return metricAttributes;
|
|
450
|
+
};
|
|
451
|
+
exports.getOutgoingStableRequestMetricAttributesOnResponse = getOutgoingStableRequestMetricAttributesOnResponse;
|
|
418
452
|
function parseHostHeader(hostHeader, proto) {
|
|
419
453
|
const parts = hostHeader.split(':');
|
|
420
454
|
// no semicolon implies ipv4 dotted syntax or host name without port
|
|
@@ -586,8 +620,12 @@ const getIncomingRequestAttributes = (request, options, logger) => {
|
|
|
586
620
|
if (parsedUrl?.pathname != null) {
|
|
587
621
|
newAttributes[semantic_conventions_1.ATTR_URL_PATH] = parsedUrl.pathname;
|
|
588
622
|
}
|
|
623
|
+
if (parsedUrl.search) {
|
|
624
|
+
// Remove leading '?' from URL search (https://developer.mozilla.org/en-US/docs/Web/API/URL/search).
|
|
625
|
+
newAttributes[semantic_conventions_1.ATTR_URL_QUERY] = parsedUrl.search.slice(1);
|
|
626
|
+
}
|
|
589
627
|
if (remoteClientAddress != null) {
|
|
590
|
-
newAttributes[semantic_conventions_1.ATTR_CLIENT_ADDRESS] = remoteClientAddress;
|
|
628
|
+
newAttributes[semantic_conventions_1.ATTR_CLIENT_ADDRESS] = remoteClientAddress.split(',')[0];
|
|
591
629
|
}
|
|
592
630
|
if (serverAddress?.port != null) {
|
|
593
631
|
newAttributes[semantic_conventions_1.ATTR_SERVER_PORT] = Number(serverAddress.port);
|
|
@@ -596,25 +634,28 @@ const getIncomingRequestAttributes = (request, options, logger) => {
|
|
|
596
634
|
if (method !== normalizedMethod) {
|
|
597
635
|
newAttributes[semantic_conventions_1.ATTR_HTTP_REQUEST_METHOD_ORIGINAL] = method;
|
|
598
636
|
}
|
|
637
|
+
if (options.enableSyntheticSourceDetection && userAgent) {
|
|
638
|
+
newAttributes[semconv_1.ATTR_USER_AGENT_SYNTHETIC_TYPE] = getSyntheticType(userAgent);
|
|
639
|
+
}
|
|
599
640
|
const oldAttributes = {
|
|
600
|
-
[
|
|
601
|
-
[
|
|
602
|
-
[
|
|
603
|
-
[
|
|
604
|
-
[
|
|
641
|
+
[semconv_1.ATTR_HTTP_URL]: parsedUrl.toString(),
|
|
642
|
+
[semconv_1.ATTR_HTTP_HOST]: host,
|
|
643
|
+
[semconv_1.ATTR_NET_HOST_NAME]: hostname,
|
|
644
|
+
[semconv_1.ATTR_HTTP_METHOD]: method,
|
|
645
|
+
[semconv_1.ATTR_HTTP_SCHEME]: options.component,
|
|
605
646
|
};
|
|
606
647
|
if (typeof ips === 'string') {
|
|
607
|
-
oldAttributes[
|
|
648
|
+
oldAttributes[semconv_1.ATTR_HTTP_CLIENT_IP] = ips.split(',')[0];
|
|
608
649
|
}
|
|
609
650
|
if (typeof serverName === 'string') {
|
|
610
|
-
oldAttributes[
|
|
651
|
+
oldAttributes[semconv_1.ATTR_HTTP_SERVER_NAME] = serverName;
|
|
611
652
|
}
|
|
612
653
|
if (parsedUrl?.pathname) {
|
|
613
|
-
oldAttributes[
|
|
654
|
+
oldAttributes[semconv_1.ATTR_HTTP_TARGET] =
|
|
614
655
|
parsedUrl?.pathname + parsedUrl?.search || '/';
|
|
615
656
|
}
|
|
616
657
|
if (userAgent !== undefined) {
|
|
617
|
-
oldAttributes[
|
|
658
|
+
oldAttributes[semconv_1.ATTR_HTTP_USER_AGENT] = userAgent;
|
|
618
659
|
}
|
|
619
660
|
(0, exports.setRequestContentLengthAttribute)(request, oldAttributes);
|
|
620
661
|
(0, exports.setAttributesFromHttpKind)(httpVersion, oldAttributes);
|
|
@@ -634,11 +675,10 @@ exports.getIncomingRequestAttributes = getIncomingRequestAttributes;
|
|
|
634
675
|
*/
|
|
635
676
|
const getIncomingRequestMetricAttributes = (spanAttributes) => {
|
|
636
677
|
const metricAttributes = {};
|
|
637
|
-
metricAttributes[
|
|
638
|
-
metricAttributes[
|
|
639
|
-
metricAttributes[
|
|
640
|
-
|
|
641
|
-
metricAttributes[semantic_conventions_1.SEMATTRS_HTTP_FLAVOR] = spanAttributes[semantic_conventions_1.SEMATTRS_HTTP_FLAVOR];
|
|
678
|
+
metricAttributes[semconv_1.ATTR_HTTP_SCHEME] = spanAttributes[semconv_1.ATTR_HTTP_SCHEME];
|
|
679
|
+
metricAttributes[semconv_1.ATTR_HTTP_METHOD] = spanAttributes[semconv_1.ATTR_HTTP_METHOD];
|
|
680
|
+
metricAttributes[semconv_1.ATTR_NET_HOST_NAME] = spanAttributes[semconv_1.ATTR_NET_HOST_NAME];
|
|
681
|
+
metricAttributes[semconv_1.ATTR_HTTP_FLAVOR] = spanAttributes[semconv_1.ATTR_HTTP_FLAVOR];
|
|
642
682
|
//TODO: http.target attribute, it should substitute any parameters to avoid high cardinality.
|
|
643
683
|
return metricAttributes;
|
|
644
684
|
};
|
|
@@ -659,15 +699,15 @@ const getIncomingRequestAttributesOnResponse = (request, response, semconvStabil
|
|
|
659
699
|
const oldAttributes = {};
|
|
660
700
|
if (socket) {
|
|
661
701
|
const { localAddress, localPort, remoteAddress, remotePort } = socket;
|
|
662
|
-
oldAttributes[
|
|
663
|
-
oldAttributes[
|
|
664
|
-
oldAttributes[
|
|
665
|
-
oldAttributes[
|
|
702
|
+
oldAttributes[semconv_1.ATTR_NET_HOST_IP] = localAddress;
|
|
703
|
+
oldAttributes[semconv_1.ATTR_NET_HOST_PORT] = localPort;
|
|
704
|
+
oldAttributes[semconv_1.ATTR_NET_PEER_IP] = remoteAddress;
|
|
705
|
+
oldAttributes[semconv_1.ATTR_NET_PEER_PORT] = remotePort;
|
|
666
706
|
}
|
|
667
|
-
oldAttributes[
|
|
707
|
+
oldAttributes[semconv_1.ATTR_HTTP_STATUS_CODE] = statusCode;
|
|
668
708
|
oldAttributes[AttributeNames_1.AttributeNames.HTTP_STATUS_TEXT] = (statusMessage || '').toUpperCase();
|
|
669
709
|
if (rpcMetadata?.type === core_1.RPCType.HTTP && rpcMetadata.route !== undefined) {
|
|
670
|
-
oldAttributes[semantic_conventions_1.
|
|
710
|
+
oldAttributes[semantic_conventions_1.ATTR_HTTP_ROUTE] = rpcMetadata.route;
|
|
671
711
|
newAttributes[semantic_conventions_1.ATTR_HTTP_ROUTE] = rpcMetadata.route;
|
|
672
712
|
}
|
|
673
713
|
switch (semconvStability) {
|
|
@@ -685,20 +725,23 @@ exports.getIncomingRequestAttributesOnResponse = getIncomingRequestAttributesOnR
|
|
|
685
725
|
*/
|
|
686
726
|
const getIncomingRequestMetricAttributesOnResponse = (spanAttributes) => {
|
|
687
727
|
const metricAttributes = {};
|
|
688
|
-
metricAttributes[
|
|
689
|
-
spanAttributes[
|
|
690
|
-
metricAttributes[
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
metricAttributes[semantic_conventions_1.SEMATTRS_HTTP_ROUTE] = spanAttributes[semantic_conventions_1.SEMATTRS_HTTP_ROUTE];
|
|
728
|
+
metricAttributes[semconv_1.ATTR_HTTP_STATUS_CODE] =
|
|
729
|
+
spanAttributes[semconv_1.ATTR_HTTP_STATUS_CODE];
|
|
730
|
+
metricAttributes[semconv_1.ATTR_NET_HOST_PORT] = spanAttributes[semconv_1.ATTR_NET_HOST_PORT];
|
|
731
|
+
if (spanAttributes[semantic_conventions_1.ATTR_HTTP_ROUTE] !== undefined) {
|
|
732
|
+
metricAttributes[semantic_conventions_1.ATTR_HTTP_ROUTE] = spanAttributes[semantic_conventions_1.ATTR_HTTP_ROUTE];
|
|
694
733
|
}
|
|
695
734
|
return metricAttributes;
|
|
696
735
|
};
|
|
697
736
|
exports.getIncomingRequestMetricAttributesOnResponse = getIncomingRequestMetricAttributesOnResponse;
|
|
737
|
+
/**
|
|
738
|
+
* Returns incoming stable request Metric attributes scoped to the request data
|
|
739
|
+
* @param {Attributes} spanAttributes the span attributes
|
|
740
|
+
*/
|
|
698
741
|
const getIncomingStableRequestMetricAttributesOnResponse = (spanAttributes) => {
|
|
699
742
|
const metricAttributes = {};
|
|
700
743
|
if (spanAttributes[semantic_conventions_1.ATTR_HTTP_ROUTE] !== undefined) {
|
|
701
|
-
metricAttributes[semantic_conventions_1.ATTR_HTTP_ROUTE] = spanAttributes[semantic_conventions_1.
|
|
744
|
+
metricAttributes[semantic_conventions_1.ATTR_HTTP_ROUTE] = spanAttributes[semantic_conventions_1.ATTR_HTTP_ROUTE];
|
|
702
745
|
}
|
|
703
746
|
// required if and only if one was sent, same as span requirement
|
|
704
747
|
if (spanAttributes[semantic_conventions_1.ATTR_HTTP_RESPONSE_STATUS_CODE]) {
|
package/build/src/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n Attributes,\n SpanStatusCode,\n Span,\n context,\n SpanKind,\n DiagLogger,\n} from '@opentelemetry/api';\nimport {\n ATTR_CLIENT_ADDRESS,\n ATTR_ERROR_TYPE,\n ATTR_HTTP_REQUEST_METHOD,\n ATTR_HTTP_REQUEST_METHOD_ORIGINAL,\n ATTR_HTTP_RESPONSE_STATUS_CODE,\n ATTR_HTTP_ROUTE,\n ATTR_NETWORK_PEER_ADDRESS,\n ATTR_NETWORK_PEER_PORT,\n ATTR_NETWORK_PROTOCOL_VERSION,\n ATTR_SERVER_ADDRESS,\n ATTR_SERVER_PORT,\n ATTR_URL_FULL,\n ATTR_URL_PATH,\n ATTR_URL_SCHEME,\n ATTR_USER_AGENT_ORIGINAL,\n NETTRANSPORTVALUES_IP_TCP,\n NETTRANSPORTVALUES_IP_UDP,\n SEMATTRS_HTTP_CLIENT_IP,\n SEMATTRS_HTTP_FLAVOR,\n SEMATTRS_HTTP_HOST,\n SEMATTRS_HTTP_METHOD,\n SEMATTRS_HTTP_REQUEST_CONTENT_LENGTH,\n SEMATTRS_HTTP_REQUEST_CONTENT_LENGTH_UNCOMPRESSED,\n SEMATTRS_HTTP_RESPONSE_CONTENT_LENGTH,\n SEMATTRS_HTTP_RESPONSE_CONTENT_LENGTH_UNCOMPRESSED,\n SEMATTRS_HTTP_ROUTE,\n SEMATTRS_HTTP_SCHEME,\n SEMATTRS_HTTP_SERVER_NAME,\n SEMATTRS_HTTP_STATUS_CODE,\n SEMATTRS_HTTP_TARGET,\n SEMATTRS_HTTP_URL,\n SEMATTRS_HTTP_USER_AGENT,\n SEMATTRS_NET_HOST_IP,\n SEMATTRS_NET_HOST_NAME,\n SEMATTRS_NET_HOST_PORT,\n SEMATTRS_NET_PEER_IP,\n SEMATTRS_NET_PEER_NAME,\n SEMATTRS_NET_PEER_PORT,\n SEMATTRS_NET_TRANSPORT,\n} from '@opentelemetry/semantic-conventions';\nimport {\n IncomingHttpHeaders,\n IncomingMessage,\n OutgoingHttpHeaders,\n RequestOptions,\n ServerResponse,\n} from 'http';\nimport { getRPCMetadata, RPCType } from '@opentelemetry/core';\nimport * as url from 'url';\nimport { AttributeNames } from './enums/AttributeNames';\nimport {\n Err,\n IgnoreMatcher,\n ParsedRequestOptions,\n SemconvStability,\n} from './internal-types';\nimport forwardedParse = require('forwarded-parse');\n\n/**\n * Get an absolute url\n */\nexport const getAbsoluteUrl = (\n requestUrl: ParsedRequestOptions | null,\n headers: IncomingHttpHeaders | OutgoingHttpHeaders,\n fallbackProtocol = 'http:'\n): string => {\n const reqUrlObject = requestUrl || {};\n const protocol = reqUrlObject.protocol || fallbackProtocol;\n const port = (reqUrlObject.port || '').toString();\n const path = reqUrlObject.path || '/';\n let host =\n reqUrlObject.host || reqUrlObject.hostname || headers.host || 'localhost';\n\n // if there is no port in host and there is a port\n // it should be displayed if it's not 80 and 443 (default ports)\n if (\n (host as string).indexOf(':') === -1 &&\n port &&\n port !== '80' &&\n port !== '443'\n ) {\n host += `:${port}`;\n }\n\n return `${protocol}//${host}${path}`;\n};\n\n/**\n * Parse status code from HTTP response. [More details](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/data-http.md#status)\n */\nexport const parseResponseStatus = (\n kind: SpanKind,\n statusCode?: number\n): SpanStatusCode => {\n const upperBound = kind === SpanKind.CLIENT ? 400 : 500;\n // 1xx, 2xx, 3xx are OK on client and server\n // 4xx is OK on server\n if (statusCode && statusCode >= 100 && statusCode < upperBound) {\n return SpanStatusCode.UNSET;\n }\n\n // All other codes are error\n return SpanStatusCode.ERROR;\n};\n\n/**\n * Check whether the given obj match pattern\n * @param constant e.g URL of request\n * @param pattern Match pattern\n */\nexport const satisfiesPattern = (\n constant: string,\n pattern: IgnoreMatcher\n): boolean => {\n if (typeof pattern === 'string') {\n return pattern === constant;\n } else if (pattern instanceof RegExp) {\n return pattern.test(constant);\n } else if (typeof pattern === 'function') {\n return pattern(constant);\n } else {\n throw new TypeError('Pattern is in unsupported datatype');\n }\n};\n\n/**\n * Sets the span with the error passed in params\n * @param {Span} span the span that need to be set\n * @param {Error} error error that will be set to span\n * @param {SemconvStability} semconvStability determines which semconv version to use\n */\nexport const setSpanWithError = (\n span: Span,\n error: Err,\n semconvStability: SemconvStability\n): void => {\n const message = error.message;\n\n if ((semconvStability & SemconvStability.OLD) === SemconvStability.OLD) {\n span.setAttribute(AttributeNames.HTTP_ERROR_NAME, error.name);\n span.setAttribute(AttributeNames.HTTP_ERROR_MESSAGE, message);\n }\n\n if (\n (semconvStability & SemconvStability.STABLE) ===\n SemconvStability.STABLE\n ) {\n span.setAttribute(ATTR_ERROR_TYPE, error.name);\n }\n\n span.setStatus({ code: SpanStatusCode.ERROR, message });\n span.recordException(error);\n};\n\n/**\n * Adds attributes for request content-length and content-encoding HTTP headers\n * @param { IncomingMessage } Request object whose headers will be analyzed\n * @param { Attributes } Attributes object to be modified\n */\nexport const setRequestContentLengthAttribute = (\n request: IncomingMessage,\n attributes: Attributes\n): void => {\n const length = getContentLength(request.headers);\n if (length === null) return;\n\n if (isCompressed(request.headers)) {\n attributes[SEMATTRS_HTTP_REQUEST_CONTENT_LENGTH] = length;\n } else {\n attributes[SEMATTRS_HTTP_REQUEST_CONTENT_LENGTH_UNCOMPRESSED] = length;\n }\n};\n\n/**\n * Adds attributes for response content-length and content-encoding HTTP headers\n * @param { IncomingMessage } Response object whose headers will be analyzed\n * @param { Attributes } Attributes object to be modified\n *\n * @deprecated this is for an older version of semconv. It is retained for compatibility using OTEL_SEMCONV_STABILITY_OPT_IN\n */\nexport const setResponseContentLengthAttribute = (\n response: IncomingMessage,\n attributes: Attributes\n): void => {\n const length = getContentLength(response.headers);\n if (length === null) return;\n\n if (isCompressed(response.headers)) {\n attributes[SEMATTRS_HTTP_RESPONSE_CONTENT_LENGTH] = length;\n } else {\n attributes[SEMATTRS_HTTP_RESPONSE_CONTENT_LENGTH_UNCOMPRESSED] = length;\n }\n};\n\nfunction getContentLength(\n headers: OutgoingHttpHeaders | IncomingHttpHeaders\n): number | null {\n const contentLengthHeader = headers['content-length'];\n if (contentLengthHeader === undefined) return null;\n\n const contentLength = parseInt(contentLengthHeader as string, 10);\n if (isNaN(contentLength)) return null;\n\n return contentLength;\n}\n\nexport const isCompressed = (\n headers: OutgoingHttpHeaders | IncomingHttpHeaders\n): boolean => {\n const encoding = headers['content-encoding'];\n\n return !!encoding && encoding !== 'identity';\n};\n\n/**\n * Mimics Node.js conversion of URL strings to RequestOptions expected by\n * `http.request` and `https.request` APIs.\n *\n * See https://github.com/nodejs/node/blob/2505e217bba05fc581b572c685c5cf280a16c5a3/lib/internal/url.js#L1415-L1437\n *\n * @param stringUrl\n * @throws TypeError if the URL is not valid.\n */\nfunction stringUrlToHttpOptions(\n stringUrl: string\n): RequestOptions & { pathname: string } {\n // This is heavily inspired by Node.js handling of the same situation, trying\n // to follow it as closely as possible while keeping in mind that we only\n // deal with string URLs, not URL objects.\n const {\n hostname,\n pathname,\n port,\n username,\n password,\n search,\n protocol,\n hash,\n href,\n origin,\n host,\n } = new URL(stringUrl);\n\n const options: RequestOptions & {\n pathname: string;\n hash: string;\n search: string;\n href: string;\n origin: string;\n } = {\n protocol: protocol,\n hostname:\n hostname && hostname[0] === '[' ? hostname.slice(1, -1) : hostname,\n hash: hash,\n search: search,\n pathname: pathname,\n path: `${pathname || ''}${search || ''}`,\n href: href,\n origin: origin,\n host: host,\n };\n if (port !== '') {\n options.port = Number(port);\n }\n if (username || password) {\n options.auth = `${decodeURIComponent(username)}:${decodeURIComponent(\n password\n )}`;\n }\n return options;\n}\n\n/**\n * Makes sure options is an url object\n * return an object with default value and parsed options\n * @param logger component logger\n * @param options original options for the request\n * @param [extraOptions] additional options for the request\n */\nexport const getRequestInfo = (\n logger: DiagLogger,\n options: url.URL | RequestOptions | string,\n extraOptions?: RequestOptions\n): {\n origin: string;\n pathname: string;\n method: string;\n invalidUrl: boolean;\n optionsParsed: RequestOptions;\n} => {\n let pathname: string;\n let origin: string;\n let optionsParsed: RequestOptions;\n let invalidUrl = false;\n if (typeof options === 'string') {\n try {\n const convertedOptions = stringUrlToHttpOptions(options);\n optionsParsed = convertedOptions;\n pathname = convertedOptions.pathname || '/';\n } catch (e) {\n invalidUrl = true;\n logger.verbose(\n 'Unable to parse URL provided to HTTP request, using fallback to determine path. Original error:',\n e\n );\n // for backward compatibility with how url.parse() behaved.\n optionsParsed = {\n path: options,\n };\n pathname = optionsParsed.path || '/';\n }\n\n origin = `${optionsParsed.protocol || 'http:'}//${optionsParsed.host}`;\n if (extraOptions !== undefined) {\n Object.assign(optionsParsed, extraOptions);\n }\n } else if (options instanceof url.URL) {\n optionsParsed = {\n protocol: options.protocol,\n hostname:\n typeof options.hostname === 'string' && options.hostname.startsWith('[')\n ? options.hostname.slice(1, -1)\n : options.hostname,\n path: `${options.pathname || ''}${options.search || ''}`,\n };\n if (options.port !== '') {\n optionsParsed.port = Number(options.port);\n }\n if (options.username || options.password) {\n optionsParsed.auth = `${options.username}:${options.password}`;\n }\n pathname = options.pathname;\n origin = options.origin;\n if (extraOptions !== undefined) {\n Object.assign(optionsParsed, extraOptions);\n }\n } else {\n optionsParsed = Object.assign(\n { protocol: options.host ? 'http:' : undefined },\n options\n );\n\n const hostname =\n optionsParsed.host ||\n (optionsParsed.port != null\n ? `${optionsParsed.hostname}${optionsParsed.port}`\n : optionsParsed.hostname);\n origin = `${optionsParsed.protocol || 'http:'}//${hostname}`;\n\n pathname = (options as url.URL).pathname;\n if (!pathname && optionsParsed.path) {\n try {\n const parsedUrl = new URL(optionsParsed.path, origin);\n pathname = parsedUrl.pathname || '/';\n } catch (e) {\n pathname = '/';\n }\n }\n }\n\n // some packages return method in lowercase..\n // ensure upperCase for consistency\n const method = optionsParsed.method\n ? optionsParsed.method.toUpperCase()\n : 'GET';\n\n return { origin, pathname, method, optionsParsed, invalidUrl };\n};\n\n/**\n * Makes sure options is of type string or object\n * @param options for the request\n */\nexport const isValidOptionsType = (options: unknown): boolean => {\n if (!options) {\n return false;\n }\n\n const type = typeof options;\n return type === 'string' || (type === 'object' && !Array.isArray(options));\n};\n\nexport const extractHostnameAndPort = (\n requestOptions: Pick<\n ParsedRequestOptions,\n 'hostname' | 'host' | 'port' | 'protocol'\n >\n): { hostname: string; port: number | string } => {\n if (requestOptions.hostname && requestOptions.port) {\n return { hostname: requestOptions.hostname, port: requestOptions.port };\n }\n const matches = requestOptions.host?.match(/^([^:/ ]+)(:\\d{1,5})?/) || null;\n const hostname =\n requestOptions.hostname || (matches === null ? 'localhost' : matches[1]);\n let port = requestOptions.port;\n if (!port) {\n if (matches && matches[2]) {\n // remove the leading \":\". The extracted port would be something like \":8080\"\n port = matches[2].substring(1);\n } else {\n port = requestOptions.protocol === 'https:' ? '443' : '80';\n }\n }\n return { hostname, port };\n};\n\n/**\n * Returns outgoing request attributes scoped to the options passed to the request\n * @param {ParsedRequestOptions} requestOptions the same options used to make the request\n * @param {{ component: string, hostname: string, hookAttributes?: Attributes }} options used to pass data needed to create attributes\n * @param {SemconvStability} semconvStability determines which semconv version to use\n */\nexport const getOutgoingRequestAttributes = (\n requestOptions: ParsedRequestOptions,\n options: {\n component: string;\n hostname: string;\n port: string | number;\n hookAttributes?: Attributes;\n },\n semconvStability: SemconvStability\n): Attributes => {\n const hostname = options.hostname;\n const port = options.port;\n const method = requestOptions.method ?? 'GET';\n const normalizedMethod = normalizeMethod(method);\n const headers = requestOptions.headers || {};\n const userAgent = headers['user-agent'];\n const urlFull = getAbsoluteUrl(\n requestOptions,\n headers,\n `${options.component}:`\n );\n const oldAttributes: Attributes = {\n [SEMATTRS_HTTP_URL]: urlFull,\n [SEMATTRS_HTTP_METHOD]: method,\n [SEMATTRS_HTTP_TARGET]: requestOptions.path || '/',\n [SEMATTRS_NET_PEER_NAME]: hostname,\n [SEMATTRS_HTTP_HOST]: headers.host ?? `${hostname}:${port}`,\n };\n\n const newAttributes: Attributes = {\n // Required attributes\n [ATTR_HTTP_REQUEST_METHOD]: normalizedMethod,\n [ATTR_SERVER_ADDRESS]: hostname,\n [ATTR_SERVER_PORT]: Number(port),\n [ATTR_URL_FULL]: urlFull,\n // leaving out protocol version, it is not yet negotiated\n // leaving out protocol name, it is only required when protocol version is set\n // retries and redirects not supported\n\n // Opt-in attributes left off for now\n };\n\n // conditionally required if request method required case normalization\n if (method !== normalizedMethod) {\n newAttributes[ATTR_HTTP_REQUEST_METHOD_ORIGINAL] = method;\n }\n\n if (userAgent !== undefined) {\n oldAttributes[SEMATTRS_HTTP_USER_AGENT] = userAgent;\n }\n\n switch (semconvStability) {\n case SemconvStability.STABLE:\n return Object.assign(newAttributes, options.hookAttributes);\n case SemconvStability.OLD:\n return Object.assign(oldAttributes, options.hookAttributes);\n }\n\n return Object.assign(oldAttributes, newAttributes, options.hookAttributes);\n};\n\n/**\n * Returns outgoing request Metric attributes scoped to the request data\n * @param {Attributes} spanAttributes the span attributes\n */\nexport const getOutgoingRequestMetricAttributes = (\n spanAttributes: Attributes\n): Attributes => {\n const metricAttributes: Attributes = {};\n metricAttributes[SEMATTRS_HTTP_METHOD] = spanAttributes[SEMATTRS_HTTP_METHOD];\n metricAttributes[SEMATTRS_NET_PEER_NAME] =\n spanAttributes[SEMATTRS_NET_PEER_NAME];\n //TODO: http.url attribute, it should substitute any parameters to avoid high cardinality.\n return metricAttributes;\n};\n\n/**\n * Returns attributes related to the kind of HTTP protocol used\n * @param {string} [kind] Kind of HTTP protocol used: \"1.0\", \"1.1\", \"2\", \"SPDY\" or \"QUIC\".\n */\nexport const setAttributesFromHttpKind = (\n kind: string | undefined,\n attributes: Attributes\n): void => {\n if (kind) {\n attributes[SEMATTRS_HTTP_FLAVOR] = kind;\n if (kind.toUpperCase() !== 'QUIC') {\n attributes[SEMATTRS_NET_TRANSPORT] = NETTRANSPORTVALUES_IP_TCP;\n } else {\n attributes[SEMATTRS_NET_TRANSPORT] = NETTRANSPORTVALUES_IP_UDP;\n }\n }\n};\n\n/**\n * Returns outgoing request attributes scoped to the response data\n * @param {IncomingMessage} response the response object\n * @param {SemconvStability} semconvStability determines which semconv version to use\n */\nexport const getOutgoingRequestAttributesOnResponse = (\n response: IncomingMessage,\n semconvStability: SemconvStability\n): Attributes => {\n const { statusCode, statusMessage, httpVersion, socket } = response;\n const oldAttributes: Attributes = {};\n const stableAttributes: Attributes = {};\n\n if (statusCode != null) {\n stableAttributes[ATTR_HTTP_RESPONSE_STATUS_CODE] = statusCode;\n }\n\n if (socket) {\n const { remoteAddress, remotePort } = socket;\n oldAttributes[SEMATTRS_NET_PEER_IP] = remoteAddress;\n oldAttributes[SEMATTRS_NET_PEER_PORT] = remotePort;\n\n // Recommended\n stableAttributes[ATTR_NETWORK_PEER_ADDRESS] = remoteAddress;\n stableAttributes[ATTR_NETWORK_PEER_PORT] = remotePort;\n stableAttributes[ATTR_NETWORK_PROTOCOL_VERSION] = response.httpVersion;\n }\n setResponseContentLengthAttribute(response, oldAttributes);\n\n if (statusCode) {\n oldAttributes[SEMATTRS_HTTP_STATUS_CODE] = statusCode;\n oldAttributes[AttributeNames.HTTP_STATUS_TEXT] = (\n statusMessage || ''\n ).toUpperCase();\n }\n\n setAttributesFromHttpKind(httpVersion, oldAttributes);\n\n switch (semconvStability) {\n case SemconvStability.STABLE:\n return stableAttributes;\n case SemconvStability.OLD:\n return oldAttributes;\n }\n\n return Object.assign(oldAttributes, stableAttributes);\n};\n\n/**\n * Returns outgoing request Metric attributes scoped to the response data\n * @param {Attributes} spanAttributes the span attributes\n */\nexport const getOutgoingRequestMetricAttributesOnResponse = (\n spanAttributes: Attributes\n): Attributes => {\n const metricAttributes: Attributes = {};\n metricAttributes[SEMATTRS_NET_PEER_PORT] =\n spanAttributes[SEMATTRS_NET_PEER_PORT];\n metricAttributes[SEMATTRS_HTTP_STATUS_CODE] =\n spanAttributes[SEMATTRS_HTTP_STATUS_CODE];\n metricAttributes[SEMATTRS_HTTP_FLAVOR] = spanAttributes[SEMATTRS_HTTP_FLAVOR];\n return metricAttributes;\n};\n\nfunction parseHostHeader(\n hostHeader: string,\n proto?: string\n): { host: string; port?: string } {\n const parts = hostHeader.split(':');\n\n // no semicolon implies ipv4 dotted syntax or host name without port\n // x.x.x.x\n // example.com\n if (parts.length === 1) {\n if (proto === 'http') {\n return { host: parts[0], port: '80' };\n }\n\n if (proto === 'https') {\n return { host: parts[0], port: '443' };\n }\n\n return { host: parts[0] };\n }\n\n // single semicolon implies ipv4 dotted syntax or host name with port\n // x.x.x.x:yyyy\n // example.com:yyyy\n if (parts.length === 2) {\n return {\n host: parts[0],\n port: parts[1],\n };\n }\n\n // more than 2 parts implies ipv6 syntax with multiple colons\n // [x:x:x:x:x:x:x:x]\n // [x:x:x:x:x:x:x:x]:yyyy\n if (parts[0].startsWith('[')) {\n if (parts[parts.length - 1].endsWith(']')) {\n if (proto === 'http') {\n return { host: hostHeader, port: '80' };\n }\n\n if (proto === 'https') {\n return { host: hostHeader, port: '443' };\n }\n } else if (parts[parts.length - 2].endsWith(']')) {\n return {\n host: parts.slice(0, -1).join(':'),\n port: parts[parts.length - 1],\n };\n }\n }\n\n // if nothing above matches just return the host header\n return { host: hostHeader };\n}\n\n/**\n * Get server.address and port according to http semconv 1.27\n * https://github.com/open-telemetry/semantic-conventions/blob/bf0a2c1134f206f034408b201dbec37960ed60ec/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes\n */\nfunction getServerAddress(\n request: IncomingMessage,\n component: 'http' | 'https'\n): { host: string; port?: string } | null {\n const forwardedHeader = request.headers['forwarded'];\n if (forwardedHeader) {\n for (const entry of parseForwardedHeader(forwardedHeader)) {\n if (entry.host) {\n return parseHostHeader(entry.host, entry.proto);\n }\n }\n }\n\n const xForwardedHost = request.headers['x-forwarded-host'];\n if (typeof xForwardedHost === 'string') {\n if (typeof request.headers['x-forwarded-proto'] === 'string') {\n return parseHostHeader(\n xForwardedHost,\n request.headers['x-forwarded-proto']\n );\n }\n\n if (Array.isArray(request.headers['x-forwarded-proto'])) {\n return parseHostHeader(\n xForwardedHost,\n request.headers['x-forwarded-proto'][0]\n );\n }\n\n return parseHostHeader(xForwardedHost);\n } else if (\n Array.isArray(xForwardedHost) &&\n typeof xForwardedHost[0] === 'string' &&\n xForwardedHost[0].length > 0\n ) {\n if (typeof request.headers['x-forwarded-proto'] === 'string') {\n return parseHostHeader(\n xForwardedHost[0],\n request.headers['x-forwarded-proto']\n );\n }\n\n if (Array.isArray(request.headers['x-forwarded-proto'])) {\n return parseHostHeader(\n xForwardedHost[0],\n request.headers['x-forwarded-proto'][0]\n );\n }\n\n return parseHostHeader(xForwardedHost[0]);\n }\n\n const host = request.headers['host'];\n if (typeof host === 'string' && host.length > 0) {\n return parseHostHeader(host, component);\n }\n\n return null;\n}\n\n/**\n * Get server.address and port according to http semconv 1.27\n * https://github.com/open-telemetry/semantic-conventions/blob/bf0a2c1134f206f034408b201dbec37960ed60ec/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes\n */\nexport function getRemoteClientAddress(\n request: IncomingMessage\n): string | null {\n const forwardedHeader = request.headers['forwarded'];\n if (forwardedHeader) {\n for (const entry of parseForwardedHeader(forwardedHeader)) {\n if (entry.for) {\n return entry.for;\n }\n }\n }\n\n const xForwardedFor = request.headers['x-forwarded-for'];\n if (typeof xForwardedFor === 'string') {\n return xForwardedFor;\n } else if (Array.isArray(xForwardedFor)) {\n return xForwardedFor[0];\n }\n\n const remote = request.socket.remoteAddress;\n if (remote) {\n return remote;\n }\n\n return null;\n}\n\nfunction getInfoFromIncomingMessage(\n component: 'http' | 'https',\n request: IncomingMessage,\n logger: DiagLogger\n): { pathname?: string; search?: string; toString: () => string } {\n try {\n if (request.headers.host) {\n return new URL(\n request.url ?? '/',\n `${component}://${request.headers.host}`\n );\n } else {\n const unsafeParsedUrl = new URL(\n request.url ?? '/',\n // using localhost as a workaround to still use the URL constructor for parsing\n `${component}://localhost`\n );\n // since we use localhost as a workaround, ensure we hide the rest of the properties to avoid\n // our workaround leaking though.\n return {\n pathname: unsafeParsedUrl.pathname,\n search: unsafeParsedUrl.search,\n toString: function () {\n // we cannot use the result of unsafeParsedUrl.toString as it's potentially wrong.\n return unsafeParsedUrl.pathname + unsafeParsedUrl.search;\n },\n };\n }\n } catch (e) {\n // something is wrong, use undefined - this *should* never happen, logging\n // for troubleshooting in case it does happen.\n logger.verbose('Unable to get URL from request', e);\n return {};\n }\n}\n\n/**\n * Returns incoming request attributes scoped to the request data\n * @param {IncomingMessage} request the request object\n * @param {{ component: string, serverName?: string, hookAttributes?: Attributes }} options used to pass data needed to create attributes\n * @param {SemconvStability} semconvStability determines which semconv version to use\n */\nexport const getIncomingRequestAttributes = (\n request: IncomingMessage,\n options: {\n component: 'http' | 'https';\n serverName?: string;\n hookAttributes?: Attributes;\n semconvStability: SemconvStability;\n },\n logger: DiagLogger\n): Attributes => {\n const headers = request.headers;\n const userAgent = headers['user-agent'];\n const ips = headers['x-forwarded-for'];\n const httpVersion = request.httpVersion;\n const host = headers.host;\n const hostname = host?.replace(/^(.*)(:[0-9]{1,5})/, '$1') || 'localhost';\n\n const method = request.method;\n const normalizedMethod = normalizeMethod(method);\n\n const serverAddress = getServerAddress(request, options.component);\n const serverName = options.serverName;\n\n const remoteClientAddress = getRemoteClientAddress(request);\n\n const newAttributes: Attributes = {\n [ATTR_HTTP_REQUEST_METHOD]: normalizedMethod,\n [ATTR_URL_SCHEME]: options.component,\n [ATTR_SERVER_ADDRESS]: serverAddress?.host,\n [ATTR_NETWORK_PEER_ADDRESS]: request.socket.remoteAddress,\n [ATTR_NETWORK_PEER_PORT]: request.socket.remotePort,\n [ATTR_NETWORK_PROTOCOL_VERSION]: request.httpVersion,\n [ATTR_USER_AGENT_ORIGINAL]: userAgent,\n };\n\n const parsedUrl = getInfoFromIncomingMessage(\n options.component,\n request,\n logger\n );\n\n if (parsedUrl?.pathname != null) {\n newAttributes[ATTR_URL_PATH] = parsedUrl.pathname;\n }\n\n if (remoteClientAddress != null) {\n newAttributes[ATTR_CLIENT_ADDRESS] = remoteClientAddress;\n }\n\n if (serverAddress?.port != null) {\n newAttributes[ATTR_SERVER_PORT] = Number(serverAddress.port);\n }\n\n // conditionally required if request method required case normalization\n if (method !== normalizedMethod) {\n newAttributes[ATTR_HTTP_REQUEST_METHOD_ORIGINAL] = method;\n }\n\n const oldAttributes: Attributes = {\n [SEMATTRS_HTTP_URL]: parsedUrl.toString(),\n [SEMATTRS_HTTP_HOST]: host,\n [SEMATTRS_NET_HOST_NAME]: hostname,\n [SEMATTRS_HTTP_METHOD]: method,\n [SEMATTRS_HTTP_SCHEME]: options.component,\n };\n\n if (typeof ips === 'string') {\n oldAttributes[SEMATTRS_HTTP_CLIENT_IP] = ips.split(',')[0];\n }\n\n if (typeof serverName === 'string') {\n oldAttributes[SEMATTRS_HTTP_SERVER_NAME] = serverName;\n }\n\n if (parsedUrl?.pathname) {\n oldAttributes[SEMATTRS_HTTP_TARGET] =\n parsedUrl?.pathname + parsedUrl?.search || '/';\n }\n\n if (userAgent !== undefined) {\n oldAttributes[SEMATTRS_HTTP_USER_AGENT] = userAgent;\n }\n setRequestContentLengthAttribute(request, oldAttributes);\n setAttributesFromHttpKind(httpVersion, oldAttributes);\n\n switch (options.semconvStability) {\n case SemconvStability.STABLE:\n return Object.assign(newAttributes, options.hookAttributes);\n case SemconvStability.OLD:\n return Object.assign(oldAttributes, options.hookAttributes);\n }\n\n return Object.assign(oldAttributes, newAttributes, options.hookAttributes);\n};\n\n/**\n * Returns incoming request Metric attributes scoped to the request data\n * @param {Attributes} spanAttributes the span attributes\n * @param {{ component: string }} options used to pass data needed to create attributes\n */\nexport const getIncomingRequestMetricAttributes = (\n spanAttributes: Attributes\n): Attributes => {\n const metricAttributes: Attributes = {};\n metricAttributes[SEMATTRS_HTTP_SCHEME] = spanAttributes[SEMATTRS_HTTP_SCHEME];\n metricAttributes[SEMATTRS_HTTP_METHOD] = spanAttributes[SEMATTRS_HTTP_METHOD];\n metricAttributes[SEMATTRS_NET_HOST_NAME] =\n spanAttributes[SEMATTRS_NET_HOST_NAME];\n metricAttributes[SEMATTRS_HTTP_FLAVOR] = spanAttributes[SEMATTRS_HTTP_FLAVOR];\n //TODO: http.target attribute, it should substitute any parameters to avoid high cardinality.\n return metricAttributes;\n};\n\n/**\n * Returns incoming request attributes scoped to the response data\n * @param {(ServerResponse & { socket: Socket; })} response the response object\n */\nexport const getIncomingRequestAttributesOnResponse = (\n request: IncomingMessage,\n response: ServerResponse,\n semconvStability: SemconvStability\n): Attributes => {\n // take socket from the request,\n // since it may be detached from the response object in keep-alive mode\n const { socket } = request;\n const { statusCode, statusMessage } = response;\n\n const newAttributes: Attributes = {\n [ATTR_HTTP_RESPONSE_STATUS_CODE]: statusCode,\n };\n\n const rpcMetadata = getRPCMetadata(context.active());\n const oldAttributes: Attributes = {};\n if (socket) {\n const { localAddress, localPort, remoteAddress, remotePort } = socket;\n oldAttributes[SEMATTRS_NET_HOST_IP] = localAddress;\n oldAttributes[SEMATTRS_NET_HOST_PORT] = localPort;\n oldAttributes[SEMATTRS_NET_PEER_IP] = remoteAddress;\n oldAttributes[SEMATTRS_NET_PEER_PORT] = remotePort;\n }\n oldAttributes[SEMATTRS_HTTP_STATUS_CODE] = statusCode;\n oldAttributes[AttributeNames.HTTP_STATUS_TEXT] = (\n statusMessage || ''\n ).toUpperCase();\n\n if (rpcMetadata?.type === RPCType.HTTP && rpcMetadata.route !== undefined) {\n oldAttributes[SEMATTRS_HTTP_ROUTE] = rpcMetadata.route;\n newAttributes[ATTR_HTTP_ROUTE] = rpcMetadata.route;\n }\n\n switch (semconvStability) {\n case SemconvStability.STABLE:\n return newAttributes;\n case SemconvStability.OLD:\n return oldAttributes;\n }\n\n return Object.assign(oldAttributes, newAttributes);\n};\n\n/**\n * Returns incoming request Metric attributes scoped to the request data\n * @param {Attributes} spanAttributes the span attributes\n */\nexport const getIncomingRequestMetricAttributesOnResponse = (\n spanAttributes: Attributes\n): Attributes => {\n const metricAttributes: Attributes = {};\n metricAttributes[SEMATTRS_HTTP_STATUS_CODE] =\n spanAttributes[SEMATTRS_HTTP_STATUS_CODE];\n metricAttributes[SEMATTRS_NET_HOST_PORT] =\n spanAttributes[SEMATTRS_NET_HOST_PORT];\n if (spanAttributes[SEMATTRS_HTTP_ROUTE] !== undefined) {\n metricAttributes[SEMATTRS_HTTP_ROUTE] = spanAttributes[SEMATTRS_HTTP_ROUTE];\n }\n return metricAttributes;\n};\n\nexport const getIncomingStableRequestMetricAttributesOnResponse = (\n spanAttributes: Attributes\n): Attributes => {\n const metricAttributes: Attributes = {};\n if (spanAttributes[ATTR_HTTP_ROUTE] !== undefined) {\n metricAttributes[ATTR_HTTP_ROUTE] = spanAttributes[SEMATTRS_HTTP_ROUTE];\n }\n\n // required if and only if one was sent, same as span requirement\n if (spanAttributes[ATTR_HTTP_RESPONSE_STATUS_CODE]) {\n metricAttributes[ATTR_HTTP_RESPONSE_STATUS_CODE] =\n spanAttributes[ATTR_HTTP_RESPONSE_STATUS_CODE];\n }\n return metricAttributes;\n};\n\nexport function headerCapture(type: 'request' | 'response', headers: string[]) {\n const normalizedHeaders = new Map<string, string>();\n for (let i = 0, len = headers.length; i < len; i++) {\n const capturedHeader = headers[i].toLowerCase();\n normalizedHeaders.set(capturedHeader, capturedHeader.replace(/-/g, '_'));\n }\n\n return (\n span: Span,\n getHeader: (key: string) => undefined | string | string[] | number\n ) => {\n for (const capturedHeader of normalizedHeaders.keys()) {\n const value = getHeader(capturedHeader);\n\n if (value === undefined) {\n continue;\n }\n\n const normalizedHeader = normalizedHeaders.get(capturedHeader);\n const key = `http.${type}.header.${normalizedHeader}`;\n\n if (typeof value === 'string') {\n span.setAttribute(key, [value]);\n } else if (Array.isArray(value)) {\n span.setAttribute(key, value);\n } else {\n span.setAttribute(key, [value]);\n }\n }\n };\n}\n\nconst KNOWN_METHODS = new Set([\n // methods from https://www.rfc-editor.org/rfc/rfc9110.html#name-methods\n 'GET',\n 'HEAD',\n 'POST',\n 'PUT',\n 'DELETE',\n 'CONNECT',\n 'OPTIONS',\n 'TRACE',\n\n // PATCH from https://www.rfc-editor.org/rfc/rfc5789.html\n 'PATCH',\n]);\n\nfunction normalizeMethod(method?: string | null) {\n if (method == null) {\n return 'GET';\n }\n\n const upper = method.toUpperCase();\n if (KNOWN_METHODS.has(upper)) {\n return upper;\n }\n\n return '_OTHER';\n}\n\nfunction parseForwardedHeader(header: string): Record<string, string>[] {\n try {\n return forwardedParse(header);\n } catch {\n return [];\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n Attributes,\n SpanStatusCode,\n Span,\n context,\n SpanKind,\n DiagLogger,\n AttributeValue,\n} from '@opentelemetry/api';\nimport {\n ATTR_CLIENT_ADDRESS,\n ATTR_ERROR_TYPE,\n ATTR_HTTP_REQUEST_METHOD,\n ATTR_HTTP_REQUEST_METHOD_ORIGINAL,\n ATTR_HTTP_RESPONSE_STATUS_CODE,\n ATTR_HTTP_ROUTE,\n ATTR_NETWORK_PEER_ADDRESS,\n ATTR_NETWORK_PEER_PORT,\n ATTR_NETWORK_PROTOCOL_VERSION,\n ATTR_SERVER_ADDRESS,\n ATTR_SERVER_PORT,\n ATTR_URL_FULL,\n ATTR_URL_PATH,\n ATTR_URL_QUERY,\n ATTR_URL_SCHEME,\n ATTR_USER_AGENT_ORIGINAL,\n} from '@opentelemetry/semantic-conventions';\nimport {\n ATTR_HTTP_CLIENT_IP,\n ATTR_HTTP_FLAVOR,\n ATTR_HTTP_HOST,\n ATTR_HTTP_METHOD,\n ATTR_HTTP_REQUEST_CONTENT_LENGTH,\n ATTR_HTTP_REQUEST_CONTENT_LENGTH_UNCOMPRESSED,\n ATTR_HTTP_RESPONSE_CONTENT_LENGTH,\n ATTR_HTTP_RESPONSE_CONTENT_LENGTH_UNCOMPRESSED,\n ATTR_HTTP_SCHEME,\n ATTR_HTTP_SERVER_NAME,\n ATTR_HTTP_STATUS_CODE,\n ATTR_HTTP_TARGET,\n ATTR_HTTP_URL,\n ATTR_HTTP_USER_AGENT,\n ATTR_NET_HOST_IP,\n ATTR_NET_HOST_NAME,\n ATTR_NET_HOST_PORT,\n ATTR_NET_PEER_IP,\n ATTR_NET_PEER_NAME,\n ATTR_NET_PEER_PORT,\n ATTR_NET_TRANSPORT,\n NET_TRANSPORT_VALUE_IP_TCP,\n NET_TRANSPORT_VALUE_IP_UDP,\n ATTR_USER_AGENT_SYNTHETIC_TYPE,\n USER_AGENT_SYNTHETIC_TYPE_VALUE_BOT,\n USER_AGENT_SYNTHETIC_TYPE_VALUE_TEST,\n} from './semconv';\nimport {\n IncomingHttpHeaders,\n IncomingMessage,\n OutgoingHttpHeader,\n OutgoingHttpHeaders,\n RequestOptions,\n ServerResponse,\n} from 'http';\nimport { getRPCMetadata, RPCType } from '@opentelemetry/core';\nimport { SemconvStability } from '@opentelemetry/instrumentation';\nimport * as url from 'url';\nimport { AttributeNames } from './enums/AttributeNames';\nimport { Err, IgnoreMatcher, ParsedRequestOptions } from './internal-types';\nimport { SYNTHETIC_BOT_NAMES, SYNTHETIC_TEST_NAMES } from './internal-types';\nimport forwardedParse = require('forwarded-parse');\n\n/**\n * Get an absolute url\n */\nexport const getAbsoluteUrl = (\n requestUrl: ParsedRequestOptions | null,\n headers: IncomingHttpHeaders | OutgoingHttpHeaders,\n fallbackProtocol = 'http:'\n): string => {\n const reqUrlObject = requestUrl || {};\n const protocol = reqUrlObject.protocol || fallbackProtocol;\n const port = (reqUrlObject.port || '').toString();\n const path = reqUrlObject.path || '/';\n let host =\n reqUrlObject.host || reqUrlObject.hostname || headers.host || 'localhost';\n\n // if there is no port in host and there is a port\n // it should be displayed if it's not 80 and 443 (default ports)\n if (\n (host as string).indexOf(':') === -1 &&\n port &&\n port !== '80' &&\n port !== '443'\n ) {\n host += `:${port}`;\n }\n\n return `${protocol}//${host}${path}`;\n};\n\n/**\n * Parse status code from HTTP response. [More details](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/data-http.md#status)\n */\nexport const parseResponseStatus = (\n kind: SpanKind,\n statusCode?: number\n): SpanStatusCode => {\n const upperBound = kind === SpanKind.CLIENT ? 400 : 500;\n // 1xx, 2xx, 3xx are OK on client and server\n // 4xx is OK on server\n if (statusCode && statusCode >= 100 && statusCode < upperBound) {\n return SpanStatusCode.UNSET;\n }\n\n // All other codes are error\n return SpanStatusCode.ERROR;\n};\n\n/**\n * Check whether the given obj match pattern\n * @param constant e.g URL of request\n * @param pattern Match pattern\n */\nexport const satisfiesPattern = (\n constant: string,\n pattern: IgnoreMatcher\n): boolean => {\n if (typeof pattern === 'string') {\n return pattern === constant;\n } else if (pattern instanceof RegExp) {\n return pattern.test(constant);\n } else if (typeof pattern === 'function') {\n return pattern(constant);\n } else {\n throw new TypeError('Pattern is in unsupported datatype');\n }\n};\n\n/**\n * Sets the span with the error passed in params\n * @param {Span} span the span that need to be set\n * @param {Error} error error that will be set to span\n * @param {SemconvStability} semconvStability determines which semconv version to use\n */\nexport const setSpanWithError = (\n span: Span,\n error: Err,\n semconvStability: SemconvStability\n): void => {\n const message = error.message;\n\n if (semconvStability & SemconvStability.OLD) {\n span.setAttribute(AttributeNames.HTTP_ERROR_NAME, error.name);\n span.setAttribute(AttributeNames.HTTP_ERROR_MESSAGE, message);\n }\n\n if (semconvStability & SemconvStability.STABLE) {\n span.setAttribute(ATTR_ERROR_TYPE, error.name);\n }\n\n span.setStatus({ code: SpanStatusCode.ERROR, message });\n span.recordException(error);\n};\n/**\n * Adds attributes for request content-length and content-encoding HTTP headers\n * @param { IncomingMessage } Request object whose headers will be analyzed\n * @param { Attributes } Attributes object to be modified\n */\nexport const setRequestContentLengthAttribute = (\n request: IncomingMessage,\n attributes: Attributes\n): void => {\n const length = getContentLength(request.headers);\n if (length === null) return;\n\n if (isCompressed(request.headers)) {\n attributes[ATTR_HTTP_REQUEST_CONTENT_LENGTH] = length;\n } else {\n attributes[ATTR_HTTP_REQUEST_CONTENT_LENGTH_UNCOMPRESSED] = length;\n }\n};\n\n/**\n * Adds attributes for response content-length and content-encoding HTTP headers\n * @param { IncomingMessage } Response object whose headers will be analyzed\n * @param { Attributes } Attributes object to be modified\n *\n * @deprecated this is for an older version of semconv. It is retained for compatibility using OTEL_SEMCONV_STABILITY_OPT_IN\n */\nexport const setResponseContentLengthAttribute = (\n response: IncomingMessage,\n attributes: Attributes\n): void => {\n const length = getContentLength(response.headers);\n if (length === null) return;\n\n if (isCompressed(response.headers)) {\n attributes[ATTR_HTTP_RESPONSE_CONTENT_LENGTH] = length;\n } else {\n attributes[ATTR_HTTP_RESPONSE_CONTENT_LENGTH_UNCOMPRESSED] = length;\n }\n};\n\nfunction getContentLength(\n headers: OutgoingHttpHeaders | IncomingHttpHeaders\n): number | null {\n const contentLengthHeader = headers['content-length'];\n if (contentLengthHeader === undefined) return null;\n\n const contentLength = parseInt(contentLengthHeader as string, 10);\n if (isNaN(contentLength)) return null;\n\n return contentLength;\n}\n\nexport const isCompressed = (\n headers: OutgoingHttpHeaders | IncomingHttpHeaders\n): boolean => {\n const encoding = headers['content-encoding'];\n\n return !!encoding && encoding !== 'identity';\n};\n\n/**\n * Mimics Node.js conversion of URL strings to RequestOptions expected by\n * `http.request` and `https.request` APIs.\n *\n * See https://github.com/nodejs/node/blob/2505e217bba05fc581b572c685c5cf280a16c5a3/lib/internal/url.js#L1415-L1437\n *\n * @param stringUrl\n * @throws TypeError if the URL is not valid.\n */\nfunction stringUrlToHttpOptions(\n stringUrl: string\n): RequestOptions & { pathname: string } {\n // This is heavily inspired by Node.js handling of the same situation, trying\n // to follow it as closely as possible while keeping in mind that we only\n // deal with string URLs, not URL objects.\n const {\n hostname,\n pathname,\n port,\n username,\n password,\n search,\n protocol,\n hash,\n href,\n origin,\n host,\n } = new URL(stringUrl);\n\n const options: RequestOptions & {\n pathname: string;\n hash: string;\n search: string;\n href: string;\n origin: string;\n } = {\n protocol: protocol,\n hostname:\n hostname && hostname[0] === '[' ? hostname.slice(1, -1) : hostname,\n hash: hash,\n search: search,\n pathname: pathname,\n path: `${pathname || ''}${search || ''}`,\n href: href,\n origin: origin,\n host: host,\n };\n if (port !== '') {\n options.port = Number(port);\n }\n if (username || password) {\n options.auth = `${decodeURIComponent(username)}:${decodeURIComponent(\n password\n )}`;\n }\n return options;\n}\n\n/**\n * Makes sure options is an url object\n * return an object with default value and parsed options\n * @param logger component logger\n * @param options original options for the request\n * @param [extraOptions] additional options for the request\n */\nexport const getRequestInfo = (\n logger: DiagLogger,\n options: url.URL | RequestOptions | string,\n extraOptions?: RequestOptions\n): {\n origin: string;\n pathname: string;\n method: string;\n invalidUrl: boolean;\n optionsParsed: RequestOptions;\n} => {\n let pathname: string;\n let origin: string;\n let optionsParsed: RequestOptions;\n let invalidUrl = false;\n if (typeof options === 'string') {\n try {\n const convertedOptions = stringUrlToHttpOptions(options);\n optionsParsed = convertedOptions;\n pathname = convertedOptions.pathname || '/';\n } catch (e) {\n invalidUrl = true;\n logger.verbose(\n 'Unable to parse URL provided to HTTP request, using fallback to determine path. Original error:',\n e\n );\n // for backward compatibility with how url.parse() behaved.\n optionsParsed = {\n path: options,\n };\n pathname = optionsParsed.path || '/';\n }\n\n origin = `${optionsParsed.protocol || 'http:'}//${optionsParsed.host}`;\n if (extraOptions !== undefined) {\n Object.assign(optionsParsed, extraOptions);\n }\n } else if (options instanceof url.URL) {\n optionsParsed = {\n protocol: options.protocol,\n hostname:\n typeof options.hostname === 'string' && options.hostname.startsWith('[')\n ? options.hostname.slice(1, -1)\n : options.hostname,\n path: `${options.pathname || ''}${options.search || ''}`,\n };\n if (options.port !== '') {\n optionsParsed.port = Number(options.port);\n }\n if (options.username || options.password) {\n optionsParsed.auth = `${options.username}:${options.password}`;\n }\n pathname = options.pathname;\n origin = options.origin;\n if (extraOptions !== undefined) {\n Object.assign(optionsParsed, extraOptions);\n }\n } else {\n optionsParsed = Object.assign(\n { protocol: options.host ? 'http:' : undefined },\n options\n );\n\n const hostname =\n optionsParsed.host ||\n (optionsParsed.port != null\n ? `${optionsParsed.hostname}${optionsParsed.port}`\n : optionsParsed.hostname);\n origin = `${optionsParsed.protocol || 'http:'}//${hostname}`;\n\n pathname = (options as url.URL).pathname;\n if (!pathname && optionsParsed.path) {\n try {\n const parsedUrl = new URL(optionsParsed.path, origin);\n pathname = parsedUrl.pathname || '/';\n } catch (e) {\n pathname = '/';\n }\n }\n }\n\n // some packages return method in lowercase..\n // ensure upperCase for consistency\n const method = optionsParsed.method\n ? optionsParsed.method.toUpperCase()\n : 'GET';\n\n return { origin, pathname, method, optionsParsed, invalidUrl };\n};\n\n/**\n * Makes sure options is of type string or object\n * @param options for the request\n */\nexport const isValidOptionsType = (options: unknown): boolean => {\n if (!options) {\n return false;\n }\n\n const type = typeof options;\n return type === 'string' || (type === 'object' && !Array.isArray(options));\n};\n\nexport const extractHostnameAndPort = (\n requestOptions: Pick<\n ParsedRequestOptions,\n 'hostname' | 'host' | 'port' | 'protocol'\n >\n): { hostname: string; port: number | string } => {\n if (requestOptions.hostname && requestOptions.port) {\n return { hostname: requestOptions.hostname, port: requestOptions.port };\n }\n const matches = requestOptions.host?.match(/^([^:/ ]+)(:\\d{1,5})?/) || null;\n const hostname =\n requestOptions.hostname || (matches === null ? 'localhost' : matches[1]);\n let port = requestOptions.port;\n if (!port) {\n if (matches && matches[2]) {\n // remove the leading \":\". The extracted port would be something like \":8080\"\n port = matches[2].substring(1);\n } else {\n port = requestOptions.protocol === 'https:' ? '443' : '80';\n }\n }\n return { hostname, port };\n};\n\n/**\n * Returns outgoing request attributes scoped to the options passed to the request\n * @param {ParsedRequestOptions} requestOptions the same options used to make the request\n * @param {{ component: string, hostname: string, hookAttributes?: Attributes }} options used to pass data needed to create attributes\n * @param {SemconvStability} semconvStability determines which semconv version to use\n */\nexport const getOutgoingRequestAttributes = (\n requestOptions: ParsedRequestOptions,\n options: {\n component: string;\n hostname: string;\n port: string | number;\n hookAttributes?: Attributes;\n },\n semconvStability: SemconvStability,\n enableSyntheticSourceDetection: boolean\n): Attributes => {\n const hostname = options.hostname;\n const port = options.port;\n const method = requestOptions.method ?? 'GET';\n const normalizedMethod = normalizeMethod(method);\n const headers = requestOptions.headers || {};\n const userAgent = headers['user-agent'];\n const urlFull = getAbsoluteUrl(\n requestOptions,\n headers,\n `${options.component}:`\n );\n\n const oldAttributes: Attributes = {\n [ATTR_HTTP_URL]: urlFull,\n [ATTR_HTTP_METHOD]: method,\n [ATTR_HTTP_TARGET]: requestOptions.path || '/',\n [ATTR_NET_PEER_NAME]: hostname,\n [ATTR_HTTP_HOST]: headers.host ?? `${hostname}:${port}`,\n };\n\n const newAttributes: Attributes = {\n // Required attributes\n [ATTR_HTTP_REQUEST_METHOD]: normalizedMethod,\n [ATTR_SERVER_ADDRESS]: hostname,\n [ATTR_SERVER_PORT]: Number(port),\n [ATTR_URL_FULL]: urlFull,\n [ATTR_USER_AGENT_ORIGINAL]: userAgent,\n // leaving out protocol version, it is not yet negotiated\n // leaving out protocol name, it is only required when protocol version is set\n // retries and redirects not supported\n\n // Opt-in attributes left off for now\n };\n\n // conditionally required if request method required case normalization\n if (method !== normalizedMethod) {\n newAttributes[ATTR_HTTP_REQUEST_METHOD_ORIGINAL] = method;\n }\n\n if (enableSyntheticSourceDetection && userAgent) {\n newAttributes[ATTR_USER_AGENT_SYNTHETIC_TYPE] = getSyntheticType(userAgent);\n }\n if (userAgent !== undefined) {\n oldAttributes[ATTR_HTTP_USER_AGENT] = userAgent;\n }\n\n switch (semconvStability) {\n case SemconvStability.STABLE:\n return Object.assign(newAttributes, options.hookAttributes);\n case SemconvStability.OLD:\n return Object.assign(oldAttributes, options.hookAttributes);\n }\n\n return Object.assign(oldAttributes, newAttributes, options.hookAttributes);\n};\n\n/**\n * Returns outgoing request Metric attributes scoped to the request data\n * @param {Attributes} spanAttributes the span attributes\n */\nexport const getOutgoingRequestMetricAttributes = (\n spanAttributes: Attributes\n): Attributes => {\n const metricAttributes: Attributes = {};\n metricAttributes[ATTR_HTTP_METHOD] = spanAttributes[ATTR_HTTP_METHOD];\n metricAttributes[ATTR_NET_PEER_NAME] = spanAttributes[ATTR_NET_PEER_NAME];\n //TODO: http.url attribute, it should substitute any parameters to avoid high cardinality.\n return metricAttributes;\n};\n\n/**\n * Returns attributes related to the kind of HTTP protocol used\n * @param {string} [kind] Kind of HTTP protocol used: \"1.0\", \"1.1\", \"2\", \"SPDY\" or \"QUIC\".\n */\nexport const setAttributesFromHttpKind = (\n kind: string | undefined,\n attributes: Attributes\n): void => {\n if (kind) {\n attributes[ATTR_HTTP_FLAVOR] = kind;\n if (kind.toUpperCase() !== 'QUIC') {\n attributes[ATTR_NET_TRANSPORT] = NET_TRANSPORT_VALUE_IP_TCP;\n } else {\n attributes[ATTR_NET_TRANSPORT] = NET_TRANSPORT_VALUE_IP_UDP;\n }\n }\n};\n\n/**\n * Returns the type of synthetic source based on the user agent\n * @param {OutgoingHttpHeader} userAgent the user agent string\n */\nconst getSyntheticType = (\n userAgent: OutgoingHttpHeader\n): AttributeValue | undefined => {\n const userAgentString: string = String(userAgent).toLowerCase();\n for (const name of SYNTHETIC_TEST_NAMES) {\n if (userAgentString.includes(name)) {\n return USER_AGENT_SYNTHETIC_TYPE_VALUE_TEST;\n }\n }\n for (const name of SYNTHETIC_BOT_NAMES) {\n if (userAgentString.includes(name)) {\n return USER_AGENT_SYNTHETIC_TYPE_VALUE_BOT;\n }\n }\n return;\n};\n\n/**\n * Returns outgoing request attributes scoped to the response data\n * @param {IncomingMessage} response the response object\n * @param {SemconvStability} semconvStability determines which semconv version to use\n */\nexport const getOutgoingRequestAttributesOnResponse = (\n response: IncomingMessage,\n semconvStability: SemconvStability\n): Attributes => {\n const { statusCode, statusMessage, httpVersion, socket } = response;\n const oldAttributes: Attributes = {};\n const stableAttributes: Attributes = {};\n\n if (statusCode != null) {\n stableAttributes[ATTR_HTTP_RESPONSE_STATUS_CODE] = statusCode;\n }\n\n if (socket) {\n const { remoteAddress, remotePort } = socket;\n oldAttributes[ATTR_NET_PEER_IP] = remoteAddress;\n oldAttributes[ATTR_NET_PEER_PORT] = remotePort;\n\n // Recommended\n stableAttributes[ATTR_NETWORK_PEER_ADDRESS] = remoteAddress;\n stableAttributes[ATTR_NETWORK_PEER_PORT] = remotePort;\n stableAttributes[ATTR_NETWORK_PROTOCOL_VERSION] = response.httpVersion;\n }\n setResponseContentLengthAttribute(response, oldAttributes);\n\n if (statusCode) {\n oldAttributes[ATTR_HTTP_STATUS_CODE] = statusCode;\n oldAttributes[AttributeNames.HTTP_STATUS_TEXT] = (\n statusMessage || ''\n ).toUpperCase();\n }\n\n setAttributesFromHttpKind(httpVersion, oldAttributes);\n\n switch (semconvStability) {\n case SemconvStability.STABLE:\n return stableAttributes;\n case SemconvStability.OLD:\n return oldAttributes;\n }\n\n return Object.assign(oldAttributes, stableAttributes);\n};\n\n/**\n * Returns outgoing request Metric attributes scoped to the response data\n * @param {Attributes} spanAttributes the span attributes\n */\nexport const getOutgoingRequestMetricAttributesOnResponse = (\n spanAttributes: Attributes\n): Attributes => {\n const metricAttributes: Attributes = {};\n metricAttributes[ATTR_NET_PEER_PORT] = spanAttributes[ATTR_NET_PEER_PORT];\n metricAttributes[ATTR_HTTP_STATUS_CODE] =\n spanAttributes[ATTR_HTTP_STATUS_CODE];\n metricAttributes[ATTR_HTTP_FLAVOR] = spanAttributes[ATTR_HTTP_FLAVOR];\n\n return metricAttributes;\n};\n\nexport const getOutgoingStableRequestMetricAttributesOnResponse = (\n spanAttributes: Attributes\n): Attributes => {\n const metricAttributes: Attributes = {};\n\n if (spanAttributes[ATTR_NETWORK_PROTOCOL_VERSION]) {\n metricAttributes[ATTR_NETWORK_PROTOCOL_VERSION] =\n spanAttributes[ATTR_NETWORK_PROTOCOL_VERSION];\n }\n\n if (spanAttributes[ATTR_HTTP_RESPONSE_STATUS_CODE]) {\n metricAttributes[ATTR_HTTP_RESPONSE_STATUS_CODE] =\n spanAttributes[ATTR_HTTP_RESPONSE_STATUS_CODE];\n }\n return metricAttributes;\n};\n\nfunction parseHostHeader(\n hostHeader: string,\n proto?: string\n): { host: string; port?: string } {\n const parts = hostHeader.split(':');\n\n // no semicolon implies ipv4 dotted syntax or host name without port\n // x.x.x.x\n // example.com\n if (parts.length === 1) {\n if (proto === 'http') {\n return { host: parts[0], port: '80' };\n }\n\n if (proto === 'https') {\n return { host: parts[0], port: '443' };\n }\n\n return { host: parts[0] };\n }\n\n // single semicolon implies ipv4 dotted syntax or host name with port\n // x.x.x.x:yyyy\n // example.com:yyyy\n if (parts.length === 2) {\n return {\n host: parts[0],\n port: parts[1],\n };\n }\n\n // more than 2 parts implies ipv6 syntax with multiple colons\n // [x:x:x:x:x:x:x:x]\n // [x:x:x:x:x:x:x:x]:yyyy\n if (parts[0].startsWith('[')) {\n if (parts[parts.length - 1].endsWith(']')) {\n if (proto === 'http') {\n return { host: hostHeader, port: '80' };\n }\n\n if (proto === 'https') {\n return { host: hostHeader, port: '443' };\n }\n } else if (parts[parts.length - 2].endsWith(']')) {\n return {\n host: parts.slice(0, -1).join(':'),\n port: parts[parts.length - 1],\n };\n }\n }\n\n // if nothing above matches just return the host header\n return { host: hostHeader };\n}\n\n/**\n * Get server.address and port according to http semconv 1.27\n * https://github.com/open-telemetry/semantic-conventions/blob/bf0a2c1134f206f034408b201dbec37960ed60ec/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes\n */\nfunction getServerAddress(\n request: IncomingMessage,\n component: 'http' | 'https'\n): { host: string; port?: string } | null {\n const forwardedHeader = request.headers['forwarded'];\n if (forwardedHeader) {\n for (const entry of parseForwardedHeader(forwardedHeader)) {\n if (entry.host) {\n return parseHostHeader(entry.host, entry.proto);\n }\n }\n }\n\n const xForwardedHost = request.headers['x-forwarded-host'];\n if (typeof xForwardedHost === 'string') {\n if (typeof request.headers['x-forwarded-proto'] === 'string') {\n return parseHostHeader(\n xForwardedHost,\n request.headers['x-forwarded-proto']\n );\n }\n\n if (Array.isArray(request.headers['x-forwarded-proto'])) {\n return parseHostHeader(\n xForwardedHost,\n request.headers['x-forwarded-proto'][0]\n );\n }\n\n return parseHostHeader(xForwardedHost);\n } else if (\n Array.isArray(xForwardedHost) &&\n typeof xForwardedHost[0] === 'string' &&\n xForwardedHost[0].length > 0\n ) {\n if (typeof request.headers['x-forwarded-proto'] === 'string') {\n return parseHostHeader(\n xForwardedHost[0],\n request.headers['x-forwarded-proto']\n );\n }\n\n if (Array.isArray(request.headers['x-forwarded-proto'])) {\n return parseHostHeader(\n xForwardedHost[0],\n request.headers['x-forwarded-proto'][0]\n );\n }\n\n return parseHostHeader(xForwardedHost[0]);\n }\n\n const host = request.headers['host'];\n if (typeof host === 'string' && host.length > 0) {\n return parseHostHeader(host, component);\n }\n\n return null;\n}\n\n/**\n * Get server.address and port according to http semconv 1.27\n * https://github.com/open-telemetry/semantic-conventions/blob/bf0a2c1134f206f034408b201dbec37960ed60ec/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes\n */\nexport function getRemoteClientAddress(\n request: IncomingMessage\n): string | null {\n const forwardedHeader = request.headers['forwarded'];\n if (forwardedHeader) {\n for (const entry of parseForwardedHeader(forwardedHeader)) {\n if (entry.for) {\n return entry.for;\n }\n }\n }\n\n const xForwardedFor = request.headers['x-forwarded-for'];\n if (typeof xForwardedFor === 'string') {\n return xForwardedFor;\n } else if (Array.isArray(xForwardedFor)) {\n return xForwardedFor[0];\n }\n\n const remote = request.socket.remoteAddress;\n if (remote) {\n return remote;\n }\n\n return null;\n}\n\nfunction getInfoFromIncomingMessage(\n component: 'http' | 'https',\n request: IncomingMessage,\n logger: DiagLogger\n): { pathname?: string; search?: string; toString: () => string } {\n try {\n if (request.headers.host) {\n return new URL(\n request.url ?? '/',\n `${component}://${request.headers.host}`\n );\n } else {\n const unsafeParsedUrl = new URL(\n request.url ?? '/',\n // using localhost as a workaround to still use the URL constructor for parsing\n `${component}://localhost`\n );\n // since we use localhost as a workaround, ensure we hide the rest of the properties to avoid\n // our workaround leaking though.\n return {\n pathname: unsafeParsedUrl.pathname,\n search: unsafeParsedUrl.search,\n toString: function () {\n // we cannot use the result of unsafeParsedUrl.toString as it's potentially wrong.\n return unsafeParsedUrl.pathname + unsafeParsedUrl.search;\n },\n };\n }\n } catch (e) {\n // something is wrong, use undefined - this *should* never happen, logging\n // for troubleshooting in case it does happen.\n logger.verbose('Unable to get URL from request', e);\n return {};\n }\n}\n\n/**\n * Returns incoming request attributes scoped to the request data\n * @param {IncomingMessage} request the request object\n * @param {{ component: string, serverName?: string, hookAttributes?: Attributes }} options used to pass data needed to create attributes\n * @param {SemconvStability} semconvStability determines which semconv version to use\n */\nexport const getIncomingRequestAttributes = (\n request: IncomingMessage,\n options: {\n component: 'http' | 'https';\n serverName?: string;\n hookAttributes?: Attributes;\n semconvStability: SemconvStability;\n enableSyntheticSourceDetection: boolean;\n },\n logger: DiagLogger\n): Attributes => {\n const headers = request.headers;\n const userAgent = headers['user-agent'];\n const ips = headers['x-forwarded-for'];\n const httpVersion = request.httpVersion;\n const host = headers.host;\n const hostname = host?.replace(/^(.*)(:[0-9]{1,5})/, '$1') || 'localhost';\n\n const method = request.method;\n const normalizedMethod = normalizeMethod(method);\n\n const serverAddress = getServerAddress(request, options.component);\n const serverName = options.serverName;\n const remoteClientAddress = getRemoteClientAddress(request);\n\n const newAttributes: Attributes = {\n [ATTR_HTTP_REQUEST_METHOD]: normalizedMethod,\n [ATTR_URL_SCHEME]: options.component,\n [ATTR_SERVER_ADDRESS]: serverAddress?.host,\n [ATTR_NETWORK_PEER_ADDRESS]: request.socket.remoteAddress,\n [ATTR_NETWORK_PEER_PORT]: request.socket.remotePort,\n [ATTR_NETWORK_PROTOCOL_VERSION]: request.httpVersion,\n [ATTR_USER_AGENT_ORIGINAL]: userAgent,\n };\n\n const parsedUrl = getInfoFromIncomingMessage(\n options.component,\n request,\n logger\n );\n\n if (parsedUrl?.pathname != null) {\n newAttributes[ATTR_URL_PATH] = parsedUrl.pathname;\n }\n\n if (parsedUrl.search) {\n // Remove leading '?' from URL search (https://developer.mozilla.org/en-US/docs/Web/API/URL/search).\n newAttributes[ATTR_URL_QUERY] = parsedUrl.search.slice(1);\n }\n\n if (remoteClientAddress != null) {\n newAttributes[ATTR_CLIENT_ADDRESS] = remoteClientAddress.split(',')[0];\n }\n\n if (serverAddress?.port != null) {\n newAttributes[ATTR_SERVER_PORT] = Number(serverAddress.port);\n }\n\n // conditionally required if request method required case normalization\n if (method !== normalizedMethod) {\n newAttributes[ATTR_HTTP_REQUEST_METHOD_ORIGINAL] = method;\n }\n\n if (options.enableSyntheticSourceDetection && userAgent) {\n newAttributes[ATTR_USER_AGENT_SYNTHETIC_TYPE] = getSyntheticType(userAgent);\n }\n const oldAttributes: Attributes = {\n [ATTR_HTTP_URL]: parsedUrl.toString(),\n [ATTR_HTTP_HOST]: host,\n [ATTR_NET_HOST_NAME]: hostname,\n [ATTR_HTTP_METHOD]: method,\n [ATTR_HTTP_SCHEME]: options.component,\n };\n\n if (typeof ips === 'string') {\n oldAttributes[ATTR_HTTP_CLIENT_IP] = ips.split(',')[0];\n }\n\n if (typeof serverName === 'string') {\n oldAttributes[ATTR_HTTP_SERVER_NAME] = serverName;\n }\n\n if (parsedUrl?.pathname) {\n oldAttributes[ATTR_HTTP_TARGET] =\n parsedUrl?.pathname + parsedUrl?.search || '/';\n }\n\n if (userAgent !== undefined) {\n oldAttributes[ATTR_HTTP_USER_AGENT] = userAgent;\n }\n setRequestContentLengthAttribute(request, oldAttributes);\n setAttributesFromHttpKind(httpVersion, oldAttributes);\n\n switch (options.semconvStability) {\n case SemconvStability.STABLE:\n return Object.assign(newAttributes, options.hookAttributes);\n case SemconvStability.OLD:\n return Object.assign(oldAttributes, options.hookAttributes);\n }\n\n return Object.assign(oldAttributes, newAttributes, options.hookAttributes);\n};\n\n/**\n * Returns incoming request Metric attributes scoped to the request data\n * @param {Attributes} spanAttributes the span attributes\n * @param {{ component: string }} options used to pass data needed to create attributes\n */\nexport const getIncomingRequestMetricAttributes = (\n spanAttributes: Attributes\n): Attributes => {\n const metricAttributes: Attributes = {};\n metricAttributes[ATTR_HTTP_SCHEME] = spanAttributes[ATTR_HTTP_SCHEME];\n metricAttributes[ATTR_HTTP_METHOD] = spanAttributes[ATTR_HTTP_METHOD];\n metricAttributes[ATTR_NET_HOST_NAME] = spanAttributes[ATTR_NET_HOST_NAME];\n metricAttributes[ATTR_HTTP_FLAVOR] = spanAttributes[ATTR_HTTP_FLAVOR];\n //TODO: http.target attribute, it should substitute any parameters to avoid high cardinality.\n return metricAttributes;\n};\n\n/**\n * Returns incoming request attributes scoped to the response data\n * @param {(ServerResponse & { socket: Socket; })} response the response object\n */\nexport const getIncomingRequestAttributesOnResponse = (\n request: IncomingMessage,\n response: ServerResponse,\n semconvStability: SemconvStability\n): Attributes => {\n // take socket from the request,\n // since it may be detached from the response object in keep-alive mode\n const { socket } = request;\n const { statusCode, statusMessage } = response;\n\n const newAttributes: Attributes = {\n [ATTR_HTTP_RESPONSE_STATUS_CODE]: statusCode,\n };\n\n const rpcMetadata = getRPCMetadata(context.active());\n const oldAttributes: Attributes = {};\n if (socket) {\n const { localAddress, localPort, remoteAddress, remotePort } = socket;\n oldAttributes[ATTR_NET_HOST_IP] = localAddress;\n oldAttributes[ATTR_NET_HOST_PORT] = localPort;\n oldAttributes[ATTR_NET_PEER_IP] = remoteAddress;\n oldAttributes[ATTR_NET_PEER_PORT] = remotePort;\n }\n oldAttributes[ATTR_HTTP_STATUS_CODE] = statusCode;\n oldAttributes[AttributeNames.HTTP_STATUS_TEXT] = (\n statusMessage || ''\n ).toUpperCase();\n\n if (rpcMetadata?.type === RPCType.HTTP && rpcMetadata.route !== undefined) {\n oldAttributes[ATTR_HTTP_ROUTE] = rpcMetadata.route;\n newAttributes[ATTR_HTTP_ROUTE] = rpcMetadata.route;\n }\n\n switch (semconvStability) {\n case SemconvStability.STABLE:\n return newAttributes;\n case SemconvStability.OLD:\n return oldAttributes;\n }\n\n return Object.assign(oldAttributes, newAttributes);\n};\n\n/**\n * Returns incoming request Metric attributes scoped to the request data\n * @param {Attributes} spanAttributes the span attributes\n */\nexport const getIncomingRequestMetricAttributesOnResponse = (\n spanAttributes: Attributes\n): Attributes => {\n const metricAttributes: Attributes = {};\n metricAttributes[ATTR_HTTP_STATUS_CODE] =\n spanAttributes[ATTR_HTTP_STATUS_CODE];\n metricAttributes[ATTR_NET_HOST_PORT] = spanAttributes[ATTR_NET_HOST_PORT];\n if (spanAttributes[ATTR_HTTP_ROUTE] !== undefined) {\n metricAttributes[ATTR_HTTP_ROUTE] = spanAttributes[ATTR_HTTP_ROUTE];\n }\n return metricAttributes;\n};\n\n/**\n * Returns incoming stable request Metric attributes scoped to the request data\n * @param {Attributes} spanAttributes the span attributes\n */\nexport const getIncomingStableRequestMetricAttributesOnResponse = (\n spanAttributes: Attributes\n): Attributes => {\n const metricAttributes: Attributes = {};\n if (spanAttributes[ATTR_HTTP_ROUTE] !== undefined) {\n metricAttributes[ATTR_HTTP_ROUTE] = spanAttributes[ATTR_HTTP_ROUTE];\n }\n\n // required if and only if one was sent, same as span requirement\n if (spanAttributes[ATTR_HTTP_RESPONSE_STATUS_CODE]) {\n metricAttributes[ATTR_HTTP_RESPONSE_STATUS_CODE] =\n spanAttributes[ATTR_HTTP_RESPONSE_STATUS_CODE];\n }\n return metricAttributes;\n};\n\nexport function headerCapture(type: 'request' | 'response', headers: string[]) {\n const normalizedHeaders = new Map<string, string>();\n for (let i = 0, len = headers.length; i < len; i++) {\n const capturedHeader = headers[i].toLowerCase();\n normalizedHeaders.set(capturedHeader, capturedHeader.replace(/-/g, '_'));\n }\n\n return (\n span: Span,\n getHeader: (key: string) => undefined | string | string[] | number\n ) => {\n for (const capturedHeader of normalizedHeaders.keys()) {\n const value = getHeader(capturedHeader);\n\n if (value === undefined) {\n continue;\n }\n\n const normalizedHeader = normalizedHeaders.get(capturedHeader);\n const key = `http.${type}.header.${normalizedHeader}`;\n\n if (typeof value === 'string') {\n span.setAttribute(key, [value]);\n } else if (Array.isArray(value)) {\n span.setAttribute(key, value);\n } else {\n span.setAttribute(key, [value]);\n }\n }\n };\n}\n\nconst KNOWN_METHODS = new Set([\n // methods from https://www.rfc-editor.org/rfc/rfc9110.html#name-methods\n 'GET',\n 'HEAD',\n 'POST',\n 'PUT',\n 'DELETE',\n 'CONNECT',\n 'OPTIONS',\n 'TRACE',\n\n // PATCH from https://www.rfc-editor.org/rfc/rfc5789.html\n 'PATCH',\n]);\n\nfunction normalizeMethod(method?: string | null) {\n if (method == null) {\n return 'GET';\n }\n\n const upper = method.toUpperCase();\n if (KNOWN_METHODS.has(upper)) {\n return upper;\n }\n\n return '_OTHER';\n}\n\nfunction parseForwardedHeader(header: string): Record<string, string>[] {\n try {\n return forwardedParse(header);\n } catch {\n return [];\n }\n}\n"]}
|
package/build/src/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "0.
|
|
1
|
+
export declare const VERSION = "0.201.0";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/build/src/version.js
CHANGED