@opentelemetry/instrumentation-http 0.220.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 CHANGED
@@ -61,7 +61,7 @@ Options | Type
61
61
  `ignoreOutgoingRequestHook` | `IgnoreOutgoingRequestFunction` | Function for filtering outgoing requests. HTTP instrumentation will not trace outgoing requests for which the function returns `true`.
62
62
  `disableOutgoingRequestInstrumentation` | `boolean` | Set to true to avoid instrumenting outgoing requests at all. This can be helpful when another instrumentation handles outgoing requests.
63
63
  `disableIncomingRequestInstrumentation` | `boolean` | Set to true to avoid instrumenting incoming requests at all. This can be helpful when another instrumentation handles incoming requests.
64
- `serverName` | `string` | The primary server name of the matched virtual host.
64
+ `serverName` | `string` | **Deprecated.** No longer used. Stable HTTP semantic conventions do not include the `http.server_name` attribute; this option has no effect.
65
65
  `requireParentforOutgoingSpans` | Boolean | Require that is a parent span to create new span for outgoing requests.
66
66
  `requireParentforIncomingSpans` | Boolean | Require that is a parent span to create new span for incoming requests.
67
67
  `headersToSpanAttributes` | `object` | Specify which HTTP headers should be captured as span attributes. This is an object of the form `{client: {requestHeaders: [...], responseHeaders: [...]}, server: {requestHeaders: [...], responseHeaders: [...]}}`, where each `[...]` is an array of HTTP header names (case-insensitive) to capture. Client (outgoing requests, incoming responses) and server (incoming requests, outgoing responses) headers will be converted to span attributes in the form of `http.{request,response}.header.$header_name`, e.g. `http.response.header.content_length`. By default hyphens in header names are converted to underscore. However, if stable semantic conventions are selected (see next section), then, hyphens in header names are not changed, e.g. `http.response.header.content-length`.
@@ -83,7 +83,7 @@ Hook type | Parameters
83
83
  Prior to version `0.54.0`, this instrumentation created spans targeting an experimental semantic convention [Version 1.7.0](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.7.0/semantic_conventions/README.md).
84
84
 
85
85
  HTTP semantic conventions (semconv) were stabilized in v1.23.0, and a [migration process](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/non-normative/http-migration.md#http-semantic-convention-stability-migration) was defined.
86
- `instrumentation-http` versions 0.54.0 and later include support for migrating to stable HTTP semantic conventions, as described below.
86
+ `instrumentation-http` versions 0.54.0 - XXXX include support for migrating to stable HTTP semantic conventions, as described below.
87
87
  The intent is to provide an approximate 6 month time window for users of this instrumentation to migrate to the new HTTP semconv, after which a new minor version will use the *new* semconv by default and drop support for the old semconv.
88
88
  See the [HTTP semconv migration plan for OpenTelemetry JS instrumentations](https://github.com/open-telemetry/opentelemetry-js/issues/5646).
89
89
 
@@ -93,6 +93,8 @@ To select which semconv version(s) is emitted from this instrumentation, use the
93
93
  - `http/dup`: emit **both** the old v1.7.0 and the new (stable) v1.23.0+ semantics
94
94
  - By default, if `OTEL_SEMCONV_STABILITY_OPT_IN` includes neither of the above tokens, the old v1.7.0 semconv is used.
95
95
 
96
+ `instrumentation-http` versions XXX and later emit the stable v1.23.0+ semantics only.
97
+
96
98
  ### Attributes collected
97
99
 
98
100
  v1.7.0 semconv | v1.23.0 semconv | Short Description
@@ -9,11 +9,8 @@ export declare class HttpInstrumentation extends InstrumentationBase<HttpInstrum
9
9
  private _headerCapture;
10
10
  private _httpPatched;
11
11
  private _httpsPatched;
12
- private _oldHttpServerDurationHistogram;
13
- private _stableHttpServerDurationHistogram;
14
- private _oldHttpClientDurationHistogram;
15
- private _stableHttpClientDurationHistogram;
16
- private _semconvStability;
12
+ private _httpServerDurationHistogram;
13
+ private _httpClientDurationHistogram;
17
14
  constructor(config?: HttpInstrumentationConfig);
18
15
  protected _updateMetricInstruments(): void;
19
16
  private _recordServerDuration;
@@ -46,8 +43,7 @@ export declare class HttpInstrumentation extends InstrumentationBase<HttpInstrum
46
43
  * @param request The original request object.
47
44
  * @param span representing the current operation
48
45
  * @param startTime representing the start time of the request to calculate duration in Metric
49
- * @param oldMetricAttributes metric attributes for old semantic conventions
50
- * @param stableMetricAttributes metric attributes for new semantic conventions
46
+ * @param metricAttributes metric attributes for the request duration metric
51
47
  */
52
48
  private _traceClientRequest;
53
49
  private _incomingRequestFunction;
package/build/src/http.js CHANGED
@@ -22,24 +22,12 @@ class HttpInstrumentation extends instrumentation_1.InstrumentationBase {
22
22
  _headerCapture;
23
23
  _httpPatched = false;
24
24
  _httpsPatched = false;
25
- _semconvStability = instrumentation_1.SemconvStability.OLD;
26
25
  constructor(config = {}) {
27
26
  super('@opentelemetry/instrumentation-http', version_1.VERSION, config);
28
- this._semconvStability = (0, instrumentation_1.semconvStabilityFromStr)('http', process.env.OTEL_SEMCONV_STABILITY_OPT_IN);
29
- this._headerCapture = this._createHeaderCapture(this._semconvStability);
27
+ this._headerCapture = this._createHeaderCapture();
30
28
  }
31
29
  _updateMetricInstruments() {
32
- this._oldHttpServerDurationHistogram = this.meter.createHistogram('http.server.duration', {
33
- description: 'Measures the duration of inbound HTTP requests.',
34
- unit: 'ms',
35
- valueType: api_1.ValueType.DOUBLE,
36
- });
37
- this._oldHttpClientDurationHistogram = this.meter.createHistogram('http.client.duration', {
38
- description: 'Measures the duration of outbound HTTP requests.',
39
- unit: 'ms',
40
- valueType: api_1.ValueType.DOUBLE,
41
- });
42
- this._stableHttpServerDurationHistogram = this.meter.createHistogram(semantic_conventions_1.METRIC_HTTP_SERVER_REQUEST_DURATION, {
30
+ this._httpServerDurationHistogram = this.meter.createHistogram(semantic_conventions_1.METRIC_HTTP_SERVER_REQUEST_DURATION, {
43
31
  description: 'Duration of HTTP server requests.',
44
32
  unit: 's',
45
33
  valueType: api_1.ValueType.DOUBLE,
@@ -50,7 +38,7 @@ class HttpInstrumentation extends instrumentation_1.InstrumentationBase {
50
38
  ],
51
39
  },
52
40
  });
53
- this._stableHttpClientDurationHistogram = this.meter.createHistogram(semantic_conventions_1.METRIC_HTTP_CLIENT_REQUEST_DURATION, {
41
+ this._httpClientDurationHistogram = this.meter.createHistogram(semantic_conventions_1.METRIC_HTTP_CLIENT_REQUEST_DURATION, {
54
42
  description: 'Duration of HTTP client requests.',
55
43
  unit: 's',
56
44
  valueType: api_1.ValueType.DOUBLE,
@@ -62,29 +50,17 @@ class HttpInstrumentation extends instrumentation_1.InstrumentationBase {
62
50
  },
63
51
  });
64
52
  }
65
- _recordServerDuration(durationMs, oldAttributes, stableAttributes) {
66
- if (this._semconvStability & instrumentation_1.SemconvStability.OLD) {
67
- // old histogram is counted in MS
68
- this._oldHttpServerDurationHistogram.record(durationMs, oldAttributes);
69
- }
70
- if (this._semconvStability & instrumentation_1.SemconvStability.STABLE) {
71
- // stable histogram is counted in S
72
- this._stableHttpServerDurationHistogram.record(durationMs / 1000, stableAttributes);
73
- }
53
+ _recordServerDuration(durationMs, attributes) {
54
+ // stable histogram is counted in S
55
+ this._httpServerDurationHistogram.record(durationMs / 1000, attributes);
74
56
  }
75
- _recordClientDuration(durationMs, oldAttributes, stableAttributes) {
76
- if (this._semconvStability & instrumentation_1.SemconvStability.OLD) {
77
- // old histogram is counted in MS
78
- this._oldHttpClientDurationHistogram.record(durationMs, oldAttributes);
79
- }
80
- if (this._semconvStability & instrumentation_1.SemconvStability.STABLE) {
81
- // stable histogram is counted in S
82
- this._stableHttpClientDurationHistogram.record(durationMs / 1000, stableAttributes);
83
- }
57
+ _recordClientDuration(durationMs, attributes) {
58
+ // stable histogram is counted in S
59
+ this._httpClientDurationHistogram.record(durationMs / 1000, attributes);
84
60
  }
85
61
  setConfig(config = {}) {
86
62
  super.setConfig(config);
87
- this._headerCapture = this._createHeaderCapture(this._semconvStability);
63
+ this._headerCapture = this._createHeaderCapture();
88
64
  }
89
65
  init() {
90
66
  return [this._getHttpsInstrumentation(), this._getHttpInstrumentation()];
@@ -238,10 +214,9 @@ class HttpInstrumentation extends instrumentation_1.InstrumentationBase {
238
214
  * @param request The original request object.
239
215
  * @param span representing the current operation
240
216
  * @param startTime representing the start time of the request to calculate duration in Metric
241
- * @param oldMetricAttributes metric attributes for old semantic conventions
242
- * @param stableMetricAttributes metric attributes for new semantic conventions
217
+ * @param metricAttributes metric attributes for the request duration metric
243
218
  */
244
- _traceClientRequest(request, span, startTime, oldMetricAttributes, stableMetricAttributes) {
219
+ _traceClientRequest(request, span, startTime, metricAttributes) {
245
220
  if (this.getConfig().requestHook) {
246
221
  this._callRequestHook(span, request);
247
222
  }
@@ -259,10 +234,9 @@ class HttpInstrumentation extends instrumentation_1.InstrumentationBase {
259
234
  if (request.listenerCount('response') <= 1) {
260
235
  response.resume();
261
236
  }
262
- const responseAttributes = (0, utils_1.getOutgoingRequestAttributesOnResponse)(response, this._semconvStability);
237
+ const responseAttributes = (0, utils_1.getOutgoingRequestAttributesOnResponse)(response);
263
238
  span.setAttributes(responseAttributes);
264
- oldMetricAttributes = Object.assign(oldMetricAttributes, (0, utils_1.getOutgoingRequestMetricAttributesOnResponse)(responseAttributes));
265
- stableMetricAttributes = Object.assign(stableMetricAttributes, (0, utils_1.getOutgoingStableRequestMetricAttributesOnResponse)(responseAttributes));
239
+ metricAttributes = Object.assign(metricAttributes, (0, utils_1.getOutgoingStableRequestMetricAttributesOnResponse)(responseAttributes));
266
240
  if (this.getConfig().responseHook) {
267
241
  this._callResponseHook(span, response);
268
242
  }
@@ -289,7 +263,7 @@ class HttpInstrumentation extends instrumentation_1.InstrumentationBase {
289
263
  if (this.getConfig().applyCustomAttributesOnSpan) {
290
264
  (0, instrumentation_1.safeExecuteInTheMiddle)(() => this.getConfig().applyCustomAttributesOnSpan(span, request, response), () => { }, true);
291
265
  }
292
- this._closeHttpSpan(span, api_1.SpanKind.CLIENT, startTime, oldMetricAttributes, stableMetricAttributes);
266
+ this._closeHttpSpan(span, api_1.SpanKind.CLIENT, startTime, metricAttributes);
293
267
  };
294
268
  response.on('end', endHandler);
295
269
  response.on(events_1.errorMonitor, (error) => {
@@ -298,7 +272,7 @@ class HttpInstrumentation extends instrumentation_1.InstrumentationBase {
298
272
  return;
299
273
  }
300
274
  responseFinished = true;
301
- this._onOutgoingRequestError(span, oldMetricAttributes, stableMetricAttributes, startTime, error);
275
+ this._onOutgoingRequestError(span, metricAttributes, startTime, error);
302
276
  });
303
277
  });
304
278
  request.on('close', () => {
@@ -307,7 +281,7 @@ class HttpInstrumentation extends instrumentation_1.InstrumentationBase {
307
281
  return;
308
282
  }
309
283
  responseFinished = true;
310
- this._closeHttpSpan(span, api_1.SpanKind.CLIENT, startTime, oldMetricAttributes, stableMetricAttributes);
284
+ this._closeHttpSpan(span, api_1.SpanKind.CLIENT, startTime, metricAttributes);
311
285
  });
312
286
  request.on(events_1.errorMonitor, (error) => {
313
287
  this._diag.debug('outgoingRequest on request error()', error);
@@ -315,7 +289,7 @@ class HttpInstrumentation extends instrumentation_1.InstrumentationBase {
315
289
  return;
316
290
  }
317
291
  responseFinished = true;
318
- this._onOutgoingRequestError(span, oldMetricAttributes, stableMetricAttributes, startTime, error);
292
+ this._onOutgoingRequestError(span, metricAttributes, startTime, error);
319
293
  });
320
294
  this._diag.debug('http.ClientRequest return request');
321
295
  return request;
@@ -345,9 +319,7 @@ class HttpInstrumentation extends instrumentation_1.InstrumentationBase {
345
319
  const headers = request.headers;
346
320
  const spanAttributes = (0, utils_1.getIncomingRequestAttributes)(request, {
347
321
  component: component,
348
- serverName: instrumentation.getConfig().serverName,
349
322
  hookAttributes: instrumentation._callStartSpanHook(request, instrumentation.getConfig().startIncomingSpanHook),
350
- semconvStability: instrumentation._semconvStability,
351
323
  enableSyntheticSourceDetection: instrumentation.getConfig().enableSyntheticSourceDetection || false,
352
324
  }, instrumentation._diag);
353
325
  Object.assign(spanAttributes, instrumentation._headerCapture.server.captureRequestHeaders(header => request.headers[header]));
@@ -356,15 +328,14 @@ class HttpInstrumentation extends instrumentation_1.InstrumentationBase {
356
328
  attributes: spanAttributes,
357
329
  };
358
330
  const startTime = (0, core_1.hrTime)();
359
- const oldMetricAttributes = (0, utils_1.getIncomingRequestMetricAttributes)(spanAttributes);
360
331
  // request method and url.scheme are both required span attributes
361
- const stableMetricAttributes = {
332
+ const metricAttributes = {
362
333
  [semantic_conventions_1.ATTR_HTTP_REQUEST_METHOD]: spanAttributes[semantic_conventions_1.ATTR_HTTP_REQUEST_METHOD],
363
334
  [semantic_conventions_1.ATTR_URL_SCHEME]: spanAttributes[semantic_conventions_1.ATTR_URL_SCHEME],
364
335
  };
365
336
  // recommended if and only if one was sent, same as span recommendation
366
337
  if (spanAttributes[semantic_conventions_1.ATTR_NETWORK_PROTOCOL_VERSION]) {
367
- stableMetricAttributes[semantic_conventions_1.ATTR_NETWORK_PROTOCOL_VERSION] =
338
+ metricAttributes[semantic_conventions_1.ATTR_NETWORK_PROTOCOL_VERSION] =
368
339
  spanAttributes[semantic_conventions_1.ATTR_NETWORK_PROTOCOL_VERSION];
369
340
  }
370
341
  const ctx = api_1.propagation.extract(api_1.ROOT_CONTEXT, headers);
@@ -388,15 +359,15 @@ class HttpInstrumentation extends instrumentation_1.InstrumentationBase {
388
359
  if (hasError) {
389
360
  return;
390
361
  }
391
- instrumentation._onServerResponseFinish(request, response, span, oldMetricAttributes, stableMetricAttributes, startTime);
362
+ instrumentation._onServerResponseFinish(request, response, span, metricAttributes, startTime);
392
363
  });
393
364
  response.on(events_1.errorMonitor, (err) => {
394
365
  hasError = true;
395
- instrumentation._onServerResponseError(span, oldMetricAttributes, stableMetricAttributes, startTime, err);
366
+ instrumentation._onServerResponseError(span, metricAttributes, startTime, err);
396
367
  });
397
368
  return (0, instrumentation_1.safeExecuteInTheMiddle)(() => original.apply(this, [event, ...args]), error => {
398
369
  if (error) {
399
- instrumentation._onServerResponseError(span, oldMetricAttributes, stableMetricAttributes, startTime, error);
370
+ instrumentation._onServerResponseError(span, metricAttributes, startTime, error);
400
371
  throw error;
401
372
  }
402
373
  });
@@ -430,23 +401,22 @@ class HttpInstrumentation extends instrumentation_1.InstrumentationBase {
430
401
  hostname,
431
402
  hookAttributes: instrumentation._callStartSpanHook(optionsParsed, instrumentation.getConfig().startOutgoingSpanHook),
432
403
  redactedQueryParams: instrumentation.getConfig().redactedQueryParams, // Added config for adding custom query strings
433
- }, instrumentation._semconvStability, instrumentation.getConfig().enableSyntheticSourceDetection || false);
404
+ }, instrumentation.getConfig().enableSyntheticSourceDetection || false);
434
405
  const startTime = (0, core_1.hrTime)();
435
- const oldMetricAttributes = (0, utils_1.getOutgoingRequestMetricAttributes)(attributes);
436
406
  // request method, server address, and server port are both required span attributes
437
- const stableMetricAttributes = {
407
+ const metricAttributes = {
438
408
  [semantic_conventions_1.ATTR_HTTP_REQUEST_METHOD]: attributes[semantic_conventions_1.ATTR_HTTP_REQUEST_METHOD],
439
409
  [semantic_conventions_1.ATTR_SERVER_ADDRESS]: attributes[semantic_conventions_1.ATTR_SERVER_ADDRESS],
440
410
  [semantic_conventions_1.ATTR_SERVER_PORT]: attributes[semantic_conventions_1.ATTR_SERVER_PORT],
441
411
  };
442
412
  // required if and only if one was sent, same as span requirement
443
413
  if (attributes[semantic_conventions_1.ATTR_HTTP_RESPONSE_STATUS_CODE]) {
444
- stableMetricAttributes[semantic_conventions_1.ATTR_HTTP_RESPONSE_STATUS_CODE] =
414
+ metricAttributes[semantic_conventions_1.ATTR_HTTP_RESPONSE_STATUS_CODE] =
445
415
  attributes[semantic_conventions_1.ATTR_HTTP_RESPONSE_STATUS_CODE];
446
416
  }
447
417
  // recommended if and only if one was sent, same as span recommendation
448
418
  if (attributes[semantic_conventions_1.ATTR_NETWORK_PROTOCOL_VERSION]) {
449
- stableMetricAttributes[semantic_conventions_1.ATTR_NETWORK_PROTOCOL_VERSION] =
419
+ metricAttributes[semantic_conventions_1.ATTR_NETWORK_PROTOCOL_VERSION] =
450
420
  attributes[semantic_conventions_1.ATTR_NETWORK_PROTOCOL_VERSION];
451
421
  }
452
422
  const spanOptions = {
@@ -486,20 +456,19 @@ class HttpInstrumentation extends instrumentation_1.InstrumentationBase {
486
456
  }
487
457
  }, error => {
488
458
  if (error) {
489
- instrumentation._onOutgoingRequestError(span, oldMetricAttributes, stableMetricAttributes, startTime, error);
459
+ instrumentation._onOutgoingRequestError(span, metricAttributes, startTime, error);
490
460
  throw error;
491
461
  }
492
462
  });
493
463
  instrumentation._diag.debug(`${component} instrumentation outgoingRequest`);
494
464
  api_1.context.bind(parentContext, request);
495
- return instrumentation._traceClientRequest(request, span, startTime, oldMetricAttributes, stableMetricAttributes);
465
+ return instrumentation._traceClientRequest(request, span, startTime, metricAttributes);
496
466
  });
497
467
  };
498
468
  }
499
- _onServerResponseFinish(request, response, span, oldMetricAttributes, stableMetricAttributes, startTime) {
500
- const attributes = (0, utils_1.getIncomingRequestAttributesOnResponse)(request, response, this._semconvStability);
501
- oldMetricAttributes = Object.assign(oldMetricAttributes, (0, utils_1.getIncomingRequestMetricAttributesOnResponse)(attributes));
502
- stableMetricAttributes = Object.assign(stableMetricAttributes, (0, utils_1.getIncomingStableRequestMetricAttributesOnResponse)(attributes));
469
+ _onServerResponseFinish(request, response, span, metricAttributes, startTime) {
470
+ const attributes = (0, utils_1.getIncomingRequestAttributesOnResponse)(response);
471
+ metricAttributes = Object.assign(metricAttributes, (0, utils_1.getIncomingStableRequestMetricAttributesOnResponse)(attributes));
503
472
  span.setAttributes(this._headerCapture.server.captureResponseHeaders(header => response.getHeader(header)));
504
473
  span.setAttributes(attributes).setStatus({
505
474
  code: (0, utils_1.parseResponseStatus)(api_1.SpanKind.SERVER, response.statusCode),
@@ -511,17 +480,17 @@ class HttpInstrumentation extends instrumentation_1.InstrumentationBase {
511
480
  if (this.getConfig().applyCustomAttributesOnSpan) {
512
481
  (0, instrumentation_1.safeExecuteInTheMiddle)(() => this.getConfig().applyCustomAttributesOnSpan(span, request, response), () => { }, true);
513
482
  }
514
- this._closeHttpSpan(span, api_1.SpanKind.SERVER, startTime, oldMetricAttributes, stableMetricAttributes);
483
+ this._closeHttpSpan(span, api_1.SpanKind.SERVER, startTime, metricAttributes);
515
484
  }
516
- _onOutgoingRequestError(span, oldMetricAttributes, stableMetricAttributes, startTime, error) {
517
- (0, utils_1.setSpanWithError)(span, error, this._semconvStability);
518
- stableMetricAttributes[semantic_conventions_1.ATTR_ERROR_TYPE] = error.name;
519
- this._closeHttpSpan(span, api_1.SpanKind.CLIENT, startTime, oldMetricAttributes, stableMetricAttributes);
485
+ _onOutgoingRequestError(span, metricAttributes, startTime, error) {
486
+ (0, utils_1.setSpanWithError)(span, error);
487
+ metricAttributes[semantic_conventions_1.ATTR_ERROR_TYPE] = error.name;
488
+ this._closeHttpSpan(span, api_1.SpanKind.CLIENT, startTime, metricAttributes);
520
489
  }
521
- _onServerResponseError(span, oldMetricAttributes, stableMetricAttributes, startTime, error) {
522
- (0, utils_1.setSpanWithError)(span, error, this._semconvStability);
523
- stableMetricAttributes[semantic_conventions_1.ATTR_ERROR_TYPE] = error.name;
524
- this._closeHttpSpan(span, api_1.SpanKind.SERVER, startTime, oldMetricAttributes, stableMetricAttributes);
490
+ _onServerResponseError(span, metricAttributes, startTime, error) {
491
+ (0, utils_1.setSpanWithError)(span, error);
492
+ metricAttributes[semantic_conventions_1.ATTR_ERROR_TYPE] = error.name;
493
+ this._closeHttpSpan(span, api_1.SpanKind.SERVER, startTime, metricAttributes);
525
494
  }
526
495
  _startHttpSpan(name, options, ctx = api_1.context.active()) {
527
496
  /*
@@ -546,7 +515,7 @@ class HttpInstrumentation extends instrumentation_1.InstrumentationBase {
546
515
  this._spanNotEnded.add(span);
547
516
  return span;
548
517
  }
549
- _closeHttpSpan(span, spanKind, startTime, oldMetricAttributes, stableMetricAttributes) {
518
+ _closeHttpSpan(span, spanKind, startTime, metricAttributes) {
550
519
  if (!this._spanNotEnded.has(span)) {
551
520
  return;
552
521
  }
@@ -555,10 +524,10 @@ class HttpInstrumentation extends instrumentation_1.InstrumentationBase {
555
524
  // Record metrics
556
525
  const duration = (0, core_1.hrTimeToMilliseconds)((0, core_1.hrTimeDuration)(startTime, (0, core_1.hrTime)()));
557
526
  if (spanKind === api_1.SpanKind.SERVER) {
558
- this._recordServerDuration(duration, oldMetricAttributes, stableMetricAttributes);
527
+ this._recordServerDuration(duration, metricAttributes);
559
528
  }
560
529
  else if (spanKind === api_1.SpanKind.CLIENT) {
561
- this._recordClientDuration(duration, oldMetricAttributes, stableMetricAttributes);
530
+ this._recordClientDuration(duration, metricAttributes);
562
531
  }
563
532
  }
564
533
  _callResponseHook(span, response) {
@@ -572,16 +541,16 @@ class HttpInstrumentation extends instrumentation_1.InstrumentationBase {
572
541
  return (0, instrumentation_1.safeExecuteInTheMiddle)(() => hookFunc(request), () => { }, true);
573
542
  }
574
543
  }
575
- _createHeaderCapture(semconvStability) {
544
+ _createHeaderCapture() {
576
545
  const config = this.getConfig();
577
546
  return {
578
547
  client: {
579
- captureRequestHeaders: (0, utils_1.headerCapture)('request', config.headersToSpanAttributes?.client?.requestHeaders ?? [], semconvStability),
580
- captureResponseHeaders: (0, utils_1.headerCapture)('response', config.headersToSpanAttributes?.client?.responseHeaders ?? [], semconvStability),
548
+ captureRequestHeaders: (0, utils_1.headerCapture)('request', config.headersToSpanAttributes?.client?.requestHeaders ?? []),
549
+ captureResponseHeaders: (0, utils_1.headerCapture)('response', config.headersToSpanAttributes?.client?.responseHeaders ?? []),
581
550
  },
582
551
  server: {
583
- captureRequestHeaders: (0, utils_1.headerCapture)('request', config.headersToSpanAttributes?.server?.requestHeaders ?? [], semconvStability),
584
- captureResponseHeaders: (0, utils_1.headerCapture)('response', config.headersToSpanAttributes?.server?.responseHeaders ?? [], semconvStability),
552
+ captureRequestHeaders: (0, utils_1.headerCapture)('request', config.headersToSpanAttributes?.server?.requestHeaders ?? []),
553
+ captureResponseHeaders: (0, utils_1.headerCapture)('response', config.headersToSpanAttributes?.server?.responseHeaders ?? []),
585
554
  },
586
555
  };
587
556
  }
@@ -1 +1 @@
1
- {"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/http.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type {\n HrTime,\n Span,\n SpanOptions,\n SpanStatus,\n Histogram,\n Attributes,\n} from '@opentelemetry/api';\nimport {\n context,\n INVALID_SPAN_CONTEXT,\n propagation,\n ROOT_CONTEXT,\n SpanKind,\n SpanStatusCode,\n trace,\n ValueType,\n} from '@opentelemetry/api';\nimport type { RPCMetadata } from '@opentelemetry/core';\nimport {\n hrTime,\n hrTimeDuration,\n hrTimeToMilliseconds,\n suppressTracing,\n RPCType,\n setRPCMetadata,\n} from '@opentelemetry/core';\nimport type * as http from 'http';\nimport type * as https from 'https';\nimport type { Socket } from 'net';\nimport * as url from 'url';\nimport type { HttpInstrumentationConfig } from './types';\nimport { VERSION } from './version';\nimport {\n InstrumentationBase,\n InstrumentationNodeModuleDefinition,\n SemconvStability,\n semconvStabilityFromStr,\n safeExecuteInTheMiddle,\n} from '@opentelemetry/instrumentation';\nimport { errorMonitor } from 'events';\nimport {\n ATTR_ERROR_TYPE,\n ATTR_HTTP_REQUEST_METHOD,\n ATTR_HTTP_RESPONSE_STATUS_CODE,\n ATTR_NETWORK_PROTOCOL_VERSION,\n ATTR_HTTP_ROUTE,\n ATTR_SERVER_ADDRESS,\n ATTR_SERVER_PORT,\n ATTR_URL_SCHEME,\n METRIC_HTTP_CLIENT_REQUEST_DURATION,\n METRIC_HTTP_SERVER_REQUEST_DURATION,\n} from '@opentelemetry/semantic-conventions';\nimport {\n extractHostnameAndPort,\n getIncomingRequestAttributes,\n getIncomingRequestAttributesOnResponse,\n getIncomingRequestMetricAttributes,\n getIncomingRequestMetricAttributesOnResponse,\n getIncomingStableRequestMetricAttributesOnResponse,\n getOutgoingRequestAttributes,\n getOutgoingRequestAttributesOnResponse,\n getOutgoingRequestMetricAttributes,\n getOutgoingRequestMetricAttributesOnResponse,\n getOutgoingStableRequestMetricAttributesOnResponse,\n getRequestInfo,\n headerCapture,\n isValidOptionsType,\n parseResponseStatus,\n setSpanWithError,\n} from './utils';\nimport type { Err, Func, Http, HttpRequestArgs, Https } from './internal-types';\n\n/**\n * `node:http` and `node:https` instrumentation for OpenTelemetry\n */\nexport class HttpInstrumentation extends InstrumentationBase<HttpInstrumentationConfig> {\n /** keep track on spans not ended */\n private readonly _spanNotEnded: WeakSet<Span> = new WeakSet<Span>();\n private _headerCapture;\n private _httpPatched: boolean = false;\n private _httpsPatched: boolean = false;\n declare private _oldHttpServerDurationHistogram: Histogram;\n declare private _stableHttpServerDurationHistogram: Histogram;\n declare private _oldHttpClientDurationHistogram: Histogram;\n declare private _stableHttpClientDurationHistogram: Histogram;\n\n private _semconvStability: SemconvStability = SemconvStability.OLD;\n\n constructor(config: HttpInstrumentationConfig = {}) {\n super('@opentelemetry/instrumentation-http', VERSION, config);\n this._semconvStability = semconvStabilityFromStr(\n 'http',\n process.env.OTEL_SEMCONV_STABILITY_OPT_IN\n );\n this._headerCapture = this._createHeaderCapture(this._semconvStability);\n }\n\n protected override _updateMetricInstruments() {\n this._oldHttpServerDurationHistogram = this.meter.createHistogram(\n 'http.server.duration',\n {\n description: 'Measures the duration of inbound HTTP requests.',\n unit: 'ms',\n valueType: ValueType.DOUBLE,\n }\n );\n this._oldHttpClientDurationHistogram = this.meter.createHistogram(\n 'http.client.duration',\n {\n description: 'Measures the duration of outbound HTTP requests.',\n unit: 'ms',\n valueType: ValueType.DOUBLE,\n }\n );\n this._stableHttpServerDurationHistogram = this.meter.createHistogram(\n METRIC_HTTP_SERVER_REQUEST_DURATION,\n {\n description: 'Duration of HTTP server requests.',\n unit: 's',\n valueType: ValueType.DOUBLE,\n advice: {\n explicitBucketBoundaries: [\n 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5,\n 7.5, 10,\n ],\n },\n }\n );\n this._stableHttpClientDurationHistogram = this.meter.createHistogram(\n METRIC_HTTP_CLIENT_REQUEST_DURATION,\n {\n description: 'Duration of HTTP client requests.',\n unit: 's',\n valueType: ValueType.DOUBLE,\n advice: {\n explicitBucketBoundaries: [\n 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5,\n 7.5, 10,\n ],\n },\n }\n );\n }\n\n private _recordServerDuration(\n durationMs: number,\n oldAttributes: Attributes,\n stableAttributes: Attributes\n ) {\n if (this._semconvStability & SemconvStability.OLD) {\n // old histogram is counted in MS\n this._oldHttpServerDurationHistogram.record(durationMs, oldAttributes);\n }\n\n if (this._semconvStability & SemconvStability.STABLE) {\n // stable histogram is counted in S\n this._stableHttpServerDurationHistogram.record(\n durationMs / 1000,\n stableAttributes\n );\n }\n }\n\n private _recordClientDuration(\n durationMs: number,\n oldAttributes: Attributes,\n stableAttributes: Attributes\n ) {\n if (this._semconvStability & SemconvStability.OLD) {\n // old histogram is counted in MS\n this._oldHttpClientDurationHistogram.record(durationMs, oldAttributes);\n }\n\n if (this._semconvStability & SemconvStability.STABLE) {\n // stable histogram is counted in S\n this._stableHttpClientDurationHistogram.record(\n durationMs / 1000,\n stableAttributes\n );\n }\n }\n\n override setConfig(config: HttpInstrumentationConfig = {}): void {\n super.setConfig(config);\n this._headerCapture = this._createHeaderCapture(this._semconvStability);\n }\n\n init(): [\n InstrumentationNodeModuleDefinition,\n InstrumentationNodeModuleDefinition,\n ] {\n return [this._getHttpsInstrumentation(), this._getHttpInstrumentation()];\n }\n\n private _getHttpInstrumentation() {\n return new InstrumentationNodeModuleDefinition(\n 'http',\n ['*'],\n (moduleExports: Http): Http => {\n // Guard against double-instrumentation, if loaded by both `require`\n // and `import`.\n if (this._httpPatched) {\n return moduleExports;\n }\n this._httpPatched = true;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const isESM = (moduleExports as any)[Symbol.toStringTag] === 'Module';\n\n if (!this.getConfig().disableOutgoingRequestInstrumentation) {\n const patchedRequest = this._wrap(\n moduleExports,\n 'request',\n this._getPatchOutgoingRequestFunction('http')\n ) as unknown as Func<http.ClientRequest>;\n const patchedGet = this._wrap(\n moduleExports,\n 'get',\n this._getPatchOutgoingGetFunction(patchedRequest)\n );\n if (isESM) {\n // To handle `import http from 'http'`, which returns the default\n // export, we need to set `module.default.*`.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (moduleExports as any).default.request = patchedRequest;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (moduleExports as any).default.get = patchedGet;\n }\n }\n if (!this.getConfig().disableIncomingRequestInstrumentation) {\n this._wrap(\n moduleExports.Server.prototype,\n 'emit',\n this._getPatchIncomingRequestFunction('http')\n );\n }\n return moduleExports;\n },\n (moduleExports: Http) => {\n this._httpPatched = false;\n if (moduleExports === undefined) return;\n\n if (!this.getConfig().disableOutgoingRequestInstrumentation) {\n this._unwrap(moduleExports, 'request');\n this._unwrap(moduleExports, 'get');\n }\n if (!this.getConfig().disableIncomingRequestInstrumentation) {\n this._unwrap(moduleExports.Server.prototype, 'emit');\n }\n }\n );\n }\n\n private _getHttpsInstrumentation() {\n return new InstrumentationNodeModuleDefinition(\n 'https',\n ['*'],\n (moduleExports: Https): Https => {\n // Guard against double-instrumentation, if loaded by both `require`\n // and `import`.\n if (this._httpsPatched) {\n return moduleExports;\n }\n this._httpsPatched = true;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const isESM = (moduleExports as any)[Symbol.toStringTag] === 'Module';\n\n if (!this.getConfig().disableOutgoingRequestInstrumentation) {\n const patchedRequest = this._wrap(\n moduleExports,\n 'request',\n this._getPatchHttpsOutgoingRequestFunction('https')\n ) as unknown as Func<http.ClientRequest>;\n const patchedGet = this._wrap(\n moduleExports,\n 'get',\n this._getPatchHttpsOutgoingGetFunction(patchedRequest)\n );\n if (isESM) {\n // To handle `import https from 'https'`, which returns the default\n // export, we need to set `module.default.*`.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (moduleExports as any).default.request = patchedRequest;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (moduleExports as any).default.get = patchedGet;\n }\n }\n if (!this.getConfig().disableIncomingRequestInstrumentation) {\n this._wrap(\n moduleExports.Server.prototype,\n 'emit',\n this._getPatchIncomingRequestFunction('https')\n );\n }\n return moduleExports;\n },\n (moduleExports: Https) => {\n this._httpsPatched = false;\n if (moduleExports === undefined) return;\n\n if (!this.getConfig().disableOutgoingRequestInstrumentation) {\n this._unwrap(moduleExports, 'request');\n this._unwrap(moduleExports, 'get');\n }\n if (!this.getConfig().disableIncomingRequestInstrumentation) {\n this._unwrap(moduleExports.Server.prototype, 'emit');\n }\n }\n );\n }\n\n /**\n * Creates spans for incoming requests, restoring spans' context if applied.\n */\n private _getPatchIncomingRequestFunction(component: 'http' | 'https') {\n return (\n original: (event: string, ...args: unknown[]) => boolean\n ): ((this: unknown, event: string, ...args: unknown[]) => boolean) => {\n return this._incomingRequestFunction(component, original);\n };\n }\n\n /**\n * Creates spans for outgoing requests, sending spans' context for distributed\n * tracing.\n */\n private _getPatchOutgoingRequestFunction(component: 'http' | 'https') {\n return (original: Func<http.ClientRequest>): Func<http.ClientRequest> => {\n return this._outgoingRequestFunction(component, original);\n };\n }\n\n private _getPatchOutgoingGetFunction(\n clientRequest: (\n options: http.RequestOptions | string | url.URL,\n ...args: HttpRequestArgs\n ) => http.ClientRequest\n ) {\n return (_original: Func<http.ClientRequest>): Func<http.ClientRequest> => {\n // Re-implement http.get. This needs to be done (instead of using\n // getPatchOutgoingRequestFunction to patch it) because we need to\n // set the trace context header before the returned http.ClientRequest is\n // ended. The Node.js docs state that the only differences between\n // request and get are that (1) get defaults to the HTTP GET method and\n // (2) the returned request object is ended immediately. The former is\n // already true (at least in supported Node versions up to v10), so we\n // simply follow the latter. Ref:\n // https://nodejs.org/dist/latest/docs/api/http.html#http_http_get_options_callback\n // https://github.com/googleapis/cloud-trace-nodejs/blob/master/src/instrumentations/instrumentation-http.ts#L198\n return function outgoingGetRequest<\n T extends http.RequestOptions | string | url.URL,\n >(options: T, ...args: HttpRequestArgs): http.ClientRequest {\n const req = clientRequest(options, ...args);\n req.end();\n return req;\n };\n };\n }\n\n /** Patches HTTPS outgoing requests */\n private _getPatchHttpsOutgoingRequestFunction(component: 'http' | 'https') {\n return (original: Func<http.ClientRequest>): Func<http.ClientRequest> => {\n const instrumentation = this;\n return function httpsOutgoingRequest(\n options: https.RequestOptions | string | URL,\n ...args: HttpRequestArgs\n ): http.ClientRequest {\n // Makes sure options will have default HTTPS parameters\n if (\n component === 'https' &&\n typeof options === 'object' &&\n options?.constructor?.name !== 'URL'\n ) {\n options = Object.assign({}, options);\n instrumentation._setDefaultOptions(options);\n }\n return instrumentation._getPatchOutgoingRequestFunction(component)(\n original\n )(options, ...args);\n };\n };\n }\n\n private _setDefaultOptions(options: https.RequestOptions) {\n options.protocol = options.protocol || 'https:';\n options.port = options.port || 443;\n }\n\n /** Patches HTTPS outgoing get requests */\n private _getPatchHttpsOutgoingGetFunction(\n clientRequest: (\n options: http.RequestOptions | string | URL,\n ...args: HttpRequestArgs\n ) => http.ClientRequest\n ) {\n return (original: Func<http.ClientRequest>): Func<http.ClientRequest> => {\n const instrumentation = this;\n return function httpsOutgoingRequest(\n options: https.RequestOptions | string | URL,\n ...args: HttpRequestArgs\n ): http.ClientRequest {\n return instrumentation._getPatchOutgoingGetFunction(clientRequest)(\n original\n )(options, ...args);\n };\n };\n }\n\n /**\n * Attach event listeners to a client request to end span and add span attributes.\n *\n * @param request The original request object.\n * @param span representing the current operation\n * @param startTime representing the start time of the request to calculate duration in Metric\n * @param oldMetricAttributes metric attributes for old semantic conventions\n * @param stableMetricAttributes metric attributes for new semantic conventions\n */\n private _traceClientRequest(\n request: http.ClientRequest,\n span: Span,\n startTime: HrTime,\n oldMetricAttributes: Attributes,\n stableMetricAttributes: Attributes\n ): http.ClientRequest {\n if (this.getConfig().requestHook) {\n this._callRequestHook(span, request);\n }\n\n /**\n * Determines if the request has errored or the response has ended/errored.\n */\n let responseFinished = false;\n\n /*\n * User 'response' event listeners can be added before our listener,\n * force our listener to be the first, so response emitter is bound\n * before any user listeners are added to it.\n */\n request.prependListener(\n 'response',\n (response: http.IncomingMessage & { aborted?: boolean }) => {\n this._diag.debug('outgoingRequest on response()');\n if (request.listenerCount('response') <= 1) {\n response.resume();\n }\n const responseAttributes = getOutgoingRequestAttributesOnResponse(\n response,\n this._semconvStability\n );\n span.setAttributes(responseAttributes);\n oldMetricAttributes = Object.assign(\n oldMetricAttributes,\n getOutgoingRequestMetricAttributesOnResponse(responseAttributes)\n );\n stableMetricAttributes = Object.assign(\n stableMetricAttributes,\n getOutgoingStableRequestMetricAttributesOnResponse(responseAttributes)\n );\n\n if (this.getConfig().responseHook) {\n this._callResponseHook(span, response);\n }\n\n span.setAttributes(\n this._headerCapture.client.captureRequestHeaders(header =>\n request.getHeader(header)\n )\n );\n span.setAttributes(\n this._headerCapture.client.captureResponseHeaders(\n header => response.headers[header]\n )\n );\n\n context.bind(context.active(), response);\n\n const endHandler = () => {\n this._diag.debug('outgoingRequest on end()');\n if (responseFinished) {\n return;\n }\n responseFinished = true;\n let status: SpanStatus;\n\n if (response.aborted && !response.complete) {\n status = { code: SpanStatusCode.ERROR };\n } else {\n // behaves same for new and old semconv\n status = {\n code: parseResponseStatus(SpanKind.CLIENT, response.statusCode),\n };\n }\n\n span.setStatus(status);\n\n if (this.getConfig().applyCustomAttributesOnSpan) {\n safeExecuteInTheMiddle(\n () =>\n this.getConfig().applyCustomAttributesOnSpan!(\n span,\n request,\n response\n ),\n () => {},\n true\n );\n }\n\n this._closeHttpSpan(\n span,\n SpanKind.CLIENT,\n startTime,\n oldMetricAttributes,\n stableMetricAttributes\n );\n };\n\n response.on('end', endHandler);\n response.on(errorMonitor, (error: Err) => {\n this._diag.debug('outgoingRequest on error()', error);\n if (responseFinished) {\n return;\n }\n responseFinished = true;\n this._onOutgoingRequestError(\n span,\n oldMetricAttributes,\n stableMetricAttributes,\n startTime,\n error\n );\n });\n }\n );\n request.on('close', () => {\n this._diag.debug('outgoingRequest on request close()');\n if (request.aborted || responseFinished) {\n return;\n }\n responseFinished = true;\n this._closeHttpSpan(\n span,\n SpanKind.CLIENT,\n startTime,\n oldMetricAttributes,\n stableMetricAttributes\n );\n });\n request.on(errorMonitor, (error: Err) => {\n this._diag.debug('outgoingRequest on request error()', error);\n if (responseFinished) {\n return;\n }\n responseFinished = true;\n this._onOutgoingRequestError(\n span,\n oldMetricAttributes,\n stableMetricAttributes,\n startTime,\n error\n );\n });\n\n this._diag.debug('http.ClientRequest return request');\n return request;\n }\n\n private _incomingRequestFunction(\n component: 'http' | 'https',\n original: (event: string, ...args: unknown[]) => boolean\n ) {\n const instrumentation = this;\n return function incomingRequest(\n this: unknown,\n event: string,\n ...args: unknown[]\n ): boolean {\n // Only traces request events\n if (event !== 'request') {\n return original.apply(this, [event, ...args]);\n }\n\n const request = args[0] as http.IncomingMessage;\n const response = args[1] as http.ServerResponse & { socket: Socket };\n const method = request.method || 'GET';\n\n instrumentation._diag.debug(\n `${component} instrumentation incomingRequest`\n );\n\n if (\n safeExecuteInTheMiddle(\n () =>\n instrumentation.getConfig().ignoreIncomingRequestHook?.(request),\n (e: unknown) => {\n if (e != null) {\n instrumentation._diag.error(\n 'caught ignoreIncomingRequestHook error: ',\n e\n );\n }\n },\n true\n )\n ) {\n return context.with(suppressTracing(context.active()), () => {\n context.bind(context.active(), request);\n context.bind(context.active(), response);\n return original.apply(this, [event, ...args]);\n });\n }\n\n const headers = request.headers;\n\n const spanAttributes = getIncomingRequestAttributes(\n request,\n {\n component: component,\n serverName: instrumentation.getConfig().serverName,\n hookAttributes: instrumentation._callStartSpanHook(\n request,\n instrumentation.getConfig().startIncomingSpanHook\n ),\n semconvStability: instrumentation._semconvStability,\n enableSyntheticSourceDetection:\n instrumentation.getConfig().enableSyntheticSourceDetection || false,\n },\n instrumentation._diag\n );\n\n Object.assign(\n spanAttributes,\n instrumentation._headerCapture.server.captureRequestHeaders(\n header => request.headers[header]\n )\n );\n\n const spanOptions: SpanOptions = {\n kind: SpanKind.SERVER,\n attributes: spanAttributes,\n };\n\n const startTime = hrTime();\n const oldMetricAttributes =\n getIncomingRequestMetricAttributes(spanAttributes);\n\n // request method and url.scheme are both required span attributes\n const stableMetricAttributes: Attributes = {\n [ATTR_HTTP_REQUEST_METHOD]: spanAttributes[ATTR_HTTP_REQUEST_METHOD],\n [ATTR_URL_SCHEME]: spanAttributes[ATTR_URL_SCHEME],\n };\n\n // recommended if and only if one was sent, same as span recommendation\n if (spanAttributes[ATTR_NETWORK_PROTOCOL_VERSION]) {\n stableMetricAttributes[ATTR_NETWORK_PROTOCOL_VERSION] =\n spanAttributes[ATTR_NETWORK_PROTOCOL_VERSION];\n }\n\n const ctx = propagation.extract(ROOT_CONTEXT, headers);\n const span = instrumentation._startHttpSpan(method, spanOptions, ctx);\n const rpcMetadata: RPCMetadata = {\n type: RPCType.HTTP,\n span,\n };\n\n return context.with(\n setRPCMetadata(trace.setSpan(ctx, span), rpcMetadata),\n () => {\n context.bind(context.active(), request);\n context.bind(context.active(), response);\n\n if (instrumentation.getConfig().requestHook) {\n instrumentation._callRequestHook(span, request);\n }\n if (instrumentation.getConfig().responseHook) {\n instrumentation._callResponseHook(span, response);\n }\n\n // After 'error', no further events other than 'close' should be emitted.\n let hasError = false;\n response.on('close', () => {\n if (hasError) {\n return;\n }\n instrumentation._onServerResponseFinish(\n request,\n response,\n span,\n oldMetricAttributes,\n stableMetricAttributes,\n startTime\n );\n });\n response.on(errorMonitor, (err: Err) => {\n hasError = true;\n instrumentation._onServerResponseError(\n span,\n oldMetricAttributes,\n stableMetricAttributes,\n startTime,\n err\n );\n });\n\n return safeExecuteInTheMiddle(\n () => original.apply(this, [event, ...args]),\n error => {\n if (error) {\n instrumentation._onServerResponseError(\n span,\n oldMetricAttributes,\n stableMetricAttributes,\n startTime,\n error\n );\n throw error;\n }\n }\n );\n }\n );\n };\n }\n\n private _outgoingRequestFunction(\n component: 'http' | 'https',\n original: Func<http.ClientRequest>\n ): Func<http.ClientRequest> {\n const instrumentation = this;\n return function outgoingRequest(\n this: unknown,\n options: url.URL | http.RequestOptions | string,\n ...args: unknown[]\n ): http.ClientRequest {\n if (!isValidOptionsType(options)) {\n return original.apply(this, [options, ...args]);\n }\n const extraOptions =\n typeof args[0] === 'object' &&\n (typeof options === 'string' || options instanceof url.URL)\n ? (args.shift() as http.RequestOptions)\n : undefined;\n const { method, invalidUrl, optionsParsed } = getRequestInfo(\n instrumentation._diag,\n options,\n extraOptions\n );\n\n if (\n safeExecuteInTheMiddle(\n () =>\n instrumentation\n .getConfig()\n .ignoreOutgoingRequestHook?.(optionsParsed),\n (e: unknown) => {\n if (e != null) {\n instrumentation._diag.error(\n 'caught ignoreOutgoingRequestHook error: ',\n e\n );\n }\n },\n true\n )\n ) {\n return original.apply(this, [optionsParsed, ...args]);\n }\n\n const { hostname, port } = extractHostnameAndPort(optionsParsed);\n const attributes = getOutgoingRequestAttributes(\n optionsParsed,\n {\n component,\n port,\n hostname,\n hookAttributes: instrumentation._callStartSpanHook(\n optionsParsed,\n instrumentation.getConfig().startOutgoingSpanHook\n ),\n redactedQueryParams: instrumentation.getConfig().redactedQueryParams, // Added config for adding custom query strings\n },\n instrumentation._semconvStability,\n instrumentation.getConfig().enableSyntheticSourceDetection || false\n );\n\n const startTime = hrTime();\n const oldMetricAttributes: Attributes =\n getOutgoingRequestMetricAttributes(attributes);\n\n // request method, server address, and server port are both required span attributes\n const stableMetricAttributes: Attributes = {\n [ATTR_HTTP_REQUEST_METHOD]: attributes[ATTR_HTTP_REQUEST_METHOD],\n [ATTR_SERVER_ADDRESS]: attributes[ATTR_SERVER_ADDRESS],\n [ATTR_SERVER_PORT]: attributes[ATTR_SERVER_PORT],\n };\n\n // required if and only if one was sent, same as span requirement\n if (attributes[ATTR_HTTP_RESPONSE_STATUS_CODE]) {\n stableMetricAttributes[ATTR_HTTP_RESPONSE_STATUS_CODE] =\n attributes[ATTR_HTTP_RESPONSE_STATUS_CODE];\n }\n\n // recommended if and only if one was sent, same as span recommendation\n if (attributes[ATTR_NETWORK_PROTOCOL_VERSION]) {\n stableMetricAttributes[ATTR_NETWORK_PROTOCOL_VERSION] =\n attributes[ATTR_NETWORK_PROTOCOL_VERSION];\n }\n\n const spanOptions: SpanOptions = {\n kind: SpanKind.CLIENT,\n attributes,\n };\n const span = instrumentation._startHttpSpan(method, spanOptions);\n\n const parentContext = context.active();\n const requestContext = trace.setSpan(parentContext, span);\n\n if (!optionsParsed.headers) {\n optionsParsed.headers = {};\n } else {\n // Make a copy of the headers object to avoid mutating an object the\n // caller might have a reference to.\n optionsParsed.headers = Object.assign({}, optionsParsed.headers);\n }\n propagation.inject(requestContext, optionsParsed.headers);\n\n return context.with(requestContext, () => {\n /*\n * The response callback is registered before ClientRequest is bound,\n * thus it is needed to bind it before the function call.\n */\n const cb = args[args.length - 1];\n if (typeof cb === 'function') {\n args[args.length - 1] = context.bind(parentContext, cb);\n }\n\n const request: http.ClientRequest = safeExecuteInTheMiddle(\n () => {\n if (invalidUrl) {\n // we know that the url is invalid, there's no point in injecting context as it will fail validation.\n // Passing in what the user provided will give the user an error that matches what they'd see without\n // the instrumentation.\n return original.apply(this, [options, ...args]);\n } else {\n return original.apply(this, [optionsParsed, ...args]);\n }\n },\n error => {\n if (error) {\n instrumentation._onOutgoingRequestError(\n span,\n oldMetricAttributes,\n stableMetricAttributes,\n startTime,\n error\n );\n throw error;\n }\n }\n );\n\n instrumentation._diag.debug(\n `${component} instrumentation outgoingRequest`\n );\n context.bind(parentContext, request);\n return instrumentation._traceClientRequest(\n request,\n span,\n startTime,\n oldMetricAttributes,\n stableMetricAttributes\n );\n });\n };\n }\n\n private _onServerResponseFinish(\n request: http.IncomingMessage,\n response: http.ServerResponse,\n span: Span,\n oldMetricAttributes: Attributes,\n stableMetricAttributes: Attributes,\n startTime: HrTime\n ) {\n const attributes = getIncomingRequestAttributesOnResponse(\n request,\n response,\n this._semconvStability\n );\n oldMetricAttributes = Object.assign(\n oldMetricAttributes,\n getIncomingRequestMetricAttributesOnResponse(attributes)\n );\n stableMetricAttributes = Object.assign(\n stableMetricAttributes,\n getIncomingStableRequestMetricAttributesOnResponse(attributes)\n );\n\n span.setAttributes(\n this._headerCapture.server.captureResponseHeaders(header =>\n response.getHeader(header)\n )\n );\n\n span.setAttributes(attributes).setStatus({\n code: parseResponseStatus(SpanKind.SERVER, response.statusCode),\n });\n\n const route = attributes[ATTR_HTTP_ROUTE];\n if (route) {\n span.updateName(`${request.method || 'GET'} ${route}`);\n }\n\n if (this.getConfig().applyCustomAttributesOnSpan) {\n safeExecuteInTheMiddle(\n () =>\n this.getConfig().applyCustomAttributesOnSpan!(\n span,\n request,\n response\n ),\n () => {},\n true\n );\n }\n\n this._closeHttpSpan(\n span,\n SpanKind.SERVER,\n startTime,\n oldMetricAttributes,\n stableMetricAttributes\n );\n }\n\n private _onOutgoingRequestError(\n span: Span,\n oldMetricAttributes: Attributes,\n stableMetricAttributes: Attributes,\n startTime: HrTime,\n error: Err\n ) {\n setSpanWithError(span, error, this._semconvStability);\n stableMetricAttributes[ATTR_ERROR_TYPE] = error.name;\n\n this._closeHttpSpan(\n span,\n SpanKind.CLIENT,\n startTime,\n oldMetricAttributes,\n stableMetricAttributes\n );\n }\n\n private _onServerResponseError(\n span: Span,\n oldMetricAttributes: Attributes,\n stableMetricAttributes: Attributes,\n startTime: HrTime,\n error: Err\n ) {\n setSpanWithError(span, error, this._semconvStability);\n stableMetricAttributes[ATTR_ERROR_TYPE] = error.name;\n\n this._closeHttpSpan(\n span,\n SpanKind.SERVER,\n startTime,\n oldMetricAttributes,\n stableMetricAttributes\n );\n }\n\n private _startHttpSpan(\n name: string,\n options: SpanOptions,\n ctx = context.active()\n ) {\n /*\n * If a parent is required but not present, we use a `NoopSpan` to still\n * propagate context without recording it.\n */\n const requireParent =\n options.kind === SpanKind.CLIENT\n ? this.getConfig().requireParentforOutgoingSpans\n : this.getConfig().requireParentforIncomingSpans;\n\n let span: Span;\n const currentSpan = trace.getSpan(ctx);\n\n if (\n requireParent === true &&\n (!currentSpan || !trace.isSpanContextValid(currentSpan.spanContext()))\n ) {\n span = trace.wrapSpanContext(INVALID_SPAN_CONTEXT);\n } else if (requireParent === true && currentSpan?.spanContext().isRemote) {\n span = currentSpan;\n } else {\n span = this.tracer.startSpan(name, options, ctx);\n }\n this._spanNotEnded.add(span);\n return span;\n }\n\n private _closeHttpSpan(\n span: Span,\n spanKind: SpanKind,\n startTime: HrTime,\n oldMetricAttributes: Attributes,\n stableMetricAttributes: Attributes\n ) {\n if (!this._spanNotEnded.has(span)) {\n return;\n }\n\n span.end();\n this._spanNotEnded.delete(span);\n\n // Record metrics\n const duration = hrTimeToMilliseconds(hrTimeDuration(startTime, hrTime()));\n if (spanKind === SpanKind.SERVER) {\n this._recordServerDuration(\n duration,\n oldMetricAttributes,\n stableMetricAttributes\n );\n } else if (spanKind === SpanKind.CLIENT) {\n this._recordClientDuration(\n duration,\n oldMetricAttributes,\n stableMetricAttributes\n );\n }\n }\n\n private _callResponseHook(\n span: Span,\n response: http.IncomingMessage | http.ServerResponse\n ) {\n safeExecuteInTheMiddle(\n () => this.getConfig().responseHook!(span, response),\n () => {},\n true\n );\n }\n\n private _callRequestHook(\n span: Span,\n request: http.ClientRequest | http.IncomingMessage\n ) {\n safeExecuteInTheMiddle(\n () => this.getConfig().requestHook!(span, request),\n () => {},\n true\n );\n }\n\n private _callStartSpanHook(\n request: http.IncomingMessage | http.RequestOptions,\n hookFunc: Function | undefined\n ) {\n if (typeof hookFunc === 'function') {\n return safeExecuteInTheMiddle(\n () => hookFunc(request),\n () => {},\n true\n );\n }\n }\n\n private _createHeaderCapture(semconvStability: SemconvStability) {\n const config = this.getConfig();\n\n return {\n client: {\n captureRequestHeaders: headerCapture(\n 'request',\n config.headersToSpanAttributes?.client?.requestHeaders ?? [],\n semconvStability\n ),\n captureResponseHeaders: headerCapture(\n 'response',\n config.headersToSpanAttributes?.client?.responseHeaders ?? [],\n semconvStability\n ),\n },\n server: {\n captureRequestHeaders: headerCapture(\n 'request',\n config.headersToSpanAttributes?.server?.requestHeaders ?? [],\n semconvStability\n ),\n captureResponseHeaders: headerCapture(\n 'response',\n config.headersToSpanAttributes?.server?.responseHeaders ?? [],\n semconvStability\n ),\n },\n };\n }\n}\n"]}
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/http.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type {\n HrTime,\n Span,\n SpanOptions,\n SpanStatus,\n Histogram,\n Attributes,\n} from '@opentelemetry/api';\nimport {\n context,\n INVALID_SPAN_CONTEXT,\n propagation,\n ROOT_CONTEXT,\n SpanKind,\n SpanStatusCode,\n trace,\n ValueType,\n} from '@opentelemetry/api';\nimport type { RPCMetadata } from '@opentelemetry/core';\nimport {\n hrTime,\n hrTimeDuration,\n hrTimeToMilliseconds,\n suppressTracing,\n RPCType,\n setRPCMetadata,\n} from '@opentelemetry/core';\nimport type * as http from 'http';\nimport type * as https from 'https';\nimport type { Socket } from 'net';\nimport * as url from 'url';\nimport type { HttpInstrumentationConfig } from './types';\nimport { VERSION } from './version';\nimport {\n InstrumentationBase,\n InstrumentationNodeModuleDefinition,\n safeExecuteInTheMiddle,\n} from '@opentelemetry/instrumentation';\nimport { errorMonitor } from 'events';\nimport {\n ATTR_ERROR_TYPE,\n ATTR_HTTP_REQUEST_METHOD,\n ATTR_HTTP_RESPONSE_STATUS_CODE,\n ATTR_NETWORK_PROTOCOL_VERSION,\n ATTR_HTTP_ROUTE,\n ATTR_SERVER_ADDRESS,\n ATTR_SERVER_PORT,\n ATTR_URL_SCHEME,\n METRIC_HTTP_CLIENT_REQUEST_DURATION,\n METRIC_HTTP_SERVER_REQUEST_DURATION,\n} from '@opentelemetry/semantic-conventions';\nimport {\n extractHostnameAndPort,\n getIncomingRequestAttributes,\n getIncomingRequestAttributesOnResponse,\n getIncomingStableRequestMetricAttributesOnResponse,\n getOutgoingRequestAttributes,\n getOutgoingRequestAttributesOnResponse,\n getOutgoingStableRequestMetricAttributesOnResponse,\n getRequestInfo,\n headerCapture,\n isValidOptionsType,\n parseResponseStatus,\n setSpanWithError,\n} from './utils';\nimport type { Err, Func, Http, HttpRequestArgs, Https } from './internal-types';\n\n/**\n * `node:http` and `node:https` instrumentation for OpenTelemetry\n */\nexport class HttpInstrumentation extends InstrumentationBase<HttpInstrumentationConfig> {\n /** keep track on spans not ended */\n private readonly _spanNotEnded: WeakSet<Span> = new WeakSet<Span>();\n private _headerCapture;\n private _httpPatched: boolean = false;\n private _httpsPatched: boolean = false;\n declare private _httpServerDurationHistogram: Histogram;\n declare private _httpClientDurationHistogram: Histogram;\n\n constructor(config: HttpInstrumentationConfig = {}) {\n super('@opentelemetry/instrumentation-http', VERSION, config);\n this._headerCapture = this._createHeaderCapture();\n }\n\n protected override _updateMetricInstruments() {\n this._httpServerDurationHistogram = this.meter.createHistogram(\n METRIC_HTTP_SERVER_REQUEST_DURATION,\n {\n description: 'Duration of HTTP server requests.',\n unit: 's',\n valueType: ValueType.DOUBLE,\n advice: {\n explicitBucketBoundaries: [\n 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5,\n 7.5, 10,\n ],\n },\n }\n );\n this._httpClientDurationHistogram = this.meter.createHistogram(\n METRIC_HTTP_CLIENT_REQUEST_DURATION,\n {\n description: 'Duration of HTTP client requests.',\n unit: 's',\n valueType: ValueType.DOUBLE,\n advice: {\n explicitBucketBoundaries: [\n 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1, 2.5, 5,\n 7.5, 10,\n ],\n },\n }\n );\n }\n\n private _recordServerDuration(durationMs: number, attributes: Attributes) {\n // stable histogram is counted in S\n this._httpServerDurationHistogram.record(durationMs / 1000, attributes);\n }\n\n private _recordClientDuration(durationMs: number, attributes: Attributes) {\n // stable histogram is counted in S\n this._httpClientDurationHistogram.record(durationMs / 1000, attributes);\n }\n\n override setConfig(config: HttpInstrumentationConfig = {}): void {\n super.setConfig(config);\n this._headerCapture = this._createHeaderCapture();\n }\n\n init(): [\n InstrumentationNodeModuleDefinition,\n InstrumentationNodeModuleDefinition,\n ] {\n return [this._getHttpsInstrumentation(), this._getHttpInstrumentation()];\n }\n\n private _getHttpInstrumentation() {\n return new InstrumentationNodeModuleDefinition(\n 'http',\n ['*'],\n (moduleExports: Http): Http => {\n // Guard against double-instrumentation, if loaded by both `require`\n // and `import`.\n if (this._httpPatched) {\n return moduleExports;\n }\n this._httpPatched = true;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const isESM = (moduleExports as any)[Symbol.toStringTag] === 'Module';\n\n if (!this.getConfig().disableOutgoingRequestInstrumentation) {\n const patchedRequest = this._wrap(\n moduleExports,\n 'request',\n this._getPatchOutgoingRequestFunction('http')\n ) as unknown as Func<http.ClientRequest>;\n const patchedGet = this._wrap(\n moduleExports,\n 'get',\n this._getPatchOutgoingGetFunction(patchedRequest)\n );\n if (isESM) {\n // To handle `import http from 'http'`, which returns the default\n // export, we need to set `module.default.*`.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (moduleExports as any).default.request = patchedRequest;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (moduleExports as any).default.get = patchedGet;\n }\n }\n if (!this.getConfig().disableIncomingRequestInstrumentation) {\n this._wrap(\n moduleExports.Server.prototype,\n 'emit',\n this._getPatchIncomingRequestFunction('http')\n );\n }\n return moduleExports;\n },\n (moduleExports: Http) => {\n this._httpPatched = false;\n if (moduleExports === undefined) return;\n\n if (!this.getConfig().disableOutgoingRequestInstrumentation) {\n this._unwrap(moduleExports, 'request');\n this._unwrap(moduleExports, 'get');\n }\n if (!this.getConfig().disableIncomingRequestInstrumentation) {\n this._unwrap(moduleExports.Server.prototype, 'emit');\n }\n }\n );\n }\n\n private _getHttpsInstrumentation() {\n return new InstrumentationNodeModuleDefinition(\n 'https',\n ['*'],\n (moduleExports: Https): Https => {\n // Guard against double-instrumentation, if loaded by both `require`\n // and `import`.\n if (this._httpsPatched) {\n return moduleExports;\n }\n this._httpsPatched = true;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const isESM = (moduleExports as any)[Symbol.toStringTag] === 'Module';\n\n if (!this.getConfig().disableOutgoingRequestInstrumentation) {\n const patchedRequest = this._wrap(\n moduleExports,\n 'request',\n this._getPatchHttpsOutgoingRequestFunction('https')\n ) as unknown as Func<http.ClientRequest>;\n const patchedGet = this._wrap(\n moduleExports,\n 'get',\n this._getPatchHttpsOutgoingGetFunction(patchedRequest)\n );\n if (isESM) {\n // To handle `import https from 'https'`, which returns the default\n // export, we need to set `module.default.*`.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (moduleExports as any).default.request = patchedRequest;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (moduleExports as any).default.get = patchedGet;\n }\n }\n if (!this.getConfig().disableIncomingRequestInstrumentation) {\n this._wrap(\n moduleExports.Server.prototype,\n 'emit',\n this._getPatchIncomingRequestFunction('https')\n );\n }\n return moduleExports;\n },\n (moduleExports: Https) => {\n this._httpsPatched = false;\n if (moduleExports === undefined) return;\n\n if (!this.getConfig().disableOutgoingRequestInstrumentation) {\n this._unwrap(moduleExports, 'request');\n this._unwrap(moduleExports, 'get');\n }\n if (!this.getConfig().disableIncomingRequestInstrumentation) {\n this._unwrap(moduleExports.Server.prototype, 'emit');\n }\n }\n );\n }\n\n /**\n * Creates spans for incoming requests, restoring spans' context if applied.\n */\n private _getPatchIncomingRequestFunction(component: 'http' | 'https') {\n return (\n original: (event: string, ...args: unknown[]) => boolean\n ): ((this: unknown, event: string, ...args: unknown[]) => boolean) => {\n return this._incomingRequestFunction(component, original);\n };\n }\n\n /**\n * Creates spans for outgoing requests, sending spans' context for distributed\n * tracing.\n */\n private _getPatchOutgoingRequestFunction(component: 'http' | 'https') {\n return (original: Func<http.ClientRequest>): Func<http.ClientRequest> => {\n return this._outgoingRequestFunction(component, original);\n };\n }\n\n private _getPatchOutgoingGetFunction(\n clientRequest: (\n options: http.RequestOptions | string | url.URL,\n ...args: HttpRequestArgs\n ) => http.ClientRequest\n ) {\n return (_original: Func<http.ClientRequest>): Func<http.ClientRequest> => {\n // Re-implement http.get. This needs to be done (instead of using\n // getPatchOutgoingRequestFunction to patch it) because we need to\n // set the trace context header before the returned http.ClientRequest is\n // ended. The Node.js docs state that the only differences between\n // request and get are that (1) get defaults to the HTTP GET method and\n // (2) the returned request object is ended immediately. The former is\n // already true (at least in supported Node versions up to v10), so we\n // simply follow the latter. Ref:\n // https://nodejs.org/dist/latest/docs/api/http.html#http_http_get_options_callback\n // https://github.com/googleapis/cloud-trace-nodejs/blob/master/src/instrumentations/instrumentation-http.ts#L198\n return function outgoingGetRequest<\n T extends http.RequestOptions | string | url.URL,\n >(options: T, ...args: HttpRequestArgs): http.ClientRequest {\n const req = clientRequest(options, ...args);\n req.end();\n return req;\n };\n };\n }\n\n /** Patches HTTPS outgoing requests */\n private _getPatchHttpsOutgoingRequestFunction(component: 'http' | 'https') {\n return (original: Func<http.ClientRequest>): Func<http.ClientRequest> => {\n const instrumentation = this;\n return function httpsOutgoingRequest(\n options: https.RequestOptions | string | URL,\n ...args: HttpRequestArgs\n ): http.ClientRequest {\n // Makes sure options will have default HTTPS parameters\n if (\n component === 'https' &&\n typeof options === 'object' &&\n options?.constructor?.name !== 'URL'\n ) {\n options = Object.assign({}, options);\n instrumentation._setDefaultOptions(options);\n }\n return instrumentation._getPatchOutgoingRequestFunction(component)(\n original\n )(options, ...args);\n };\n };\n }\n\n private _setDefaultOptions(options: https.RequestOptions) {\n options.protocol = options.protocol || 'https:';\n options.port = options.port || 443;\n }\n\n /** Patches HTTPS outgoing get requests */\n private _getPatchHttpsOutgoingGetFunction(\n clientRequest: (\n options: http.RequestOptions | string | URL,\n ...args: HttpRequestArgs\n ) => http.ClientRequest\n ) {\n return (original: Func<http.ClientRequest>): Func<http.ClientRequest> => {\n const instrumentation = this;\n return function httpsOutgoingRequest(\n options: https.RequestOptions | string | URL,\n ...args: HttpRequestArgs\n ): http.ClientRequest {\n return instrumentation._getPatchOutgoingGetFunction(clientRequest)(\n original\n )(options, ...args);\n };\n };\n }\n\n /**\n * Attach event listeners to a client request to end span and add span attributes.\n *\n * @param request The original request object.\n * @param span representing the current operation\n * @param startTime representing the start time of the request to calculate duration in Metric\n * @param metricAttributes metric attributes for the request duration metric\n */\n private _traceClientRequest(\n request: http.ClientRequest,\n span: Span,\n startTime: HrTime,\n metricAttributes: Attributes\n ): http.ClientRequest {\n if (this.getConfig().requestHook) {\n this._callRequestHook(span, request);\n }\n\n /**\n * Determines if the request has errored or the response has ended/errored.\n */\n let responseFinished = false;\n\n /*\n * User 'response' event listeners can be added before our listener,\n * force our listener to be the first, so response emitter is bound\n * before any user listeners are added to it.\n */\n request.prependListener(\n 'response',\n (response: http.IncomingMessage & { aborted?: boolean }) => {\n this._diag.debug('outgoingRequest on response()');\n if (request.listenerCount('response') <= 1) {\n response.resume();\n }\n const responseAttributes =\n getOutgoingRequestAttributesOnResponse(response);\n span.setAttributes(responseAttributes);\n metricAttributes = Object.assign(\n metricAttributes,\n getOutgoingStableRequestMetricAttributesOnResponse(responseAttributes)\n );\n\n if (this.getConfig().responseHook) {\n this._callResponseHook(span, response);\n }\n\n span.setAttributes(\n this._headerCapture.client.captureRequestHeaders(header =>\n request.getHeader(header)\n )\n );\n span.setAttributes(\n this._headerCapture.client.captureResponseHeaders(\n header => response.headers[header]\n )\n );\n\n context.bind(context.active(), response);\n\n const endHandler = () => {\n this._diag.debug('outgoingRequest on end()');\n if (responseFinished) {\n return;\n }\n responseFinished = true;\n let status: SpanStatus;\n\n if (response.aborted && !response.complete) {\n status = { code: SpanStatusCode.ERROR };\n } else {\n // behaves same for new and old semconv\n status = {\n code: parseResponseStatus(SpanKind.CLIENT, response.statusCode),\n };\n }\n\n span.setStatus(status);\n\n if (this.getConfig().applyCustomAttributesOnSpan) {\n safeExecuteInTheMiddle(\n () =>\n this.getConfig().applyCustomAttributesOnSpan!(\n span,\n request,\n response\n ),\n () => {},\n true\n );\n }\n\n this._closeHttpSpan(\n span,\n SpanKind.CLIENT,\n startTime,\n metricAttributes\n );\n };\n\n response.on('end', endHandler);\n response.on(errorMonitor, (error: Err) => {\n this._diag.debug('outgoingRequest on error()', error);\n if (responseFinished) {\n return;\n }\n responseFinished = true;\n this._onOutgoingRequestError(\n span,\n metricAttributes,\n startTime,\n error\n );\n });\n }\n );\n request.on('close', () => {\n this._diag.debug('outgoingRequest on request close()');\n if (request.aborted || responseFinished) {\n return;\n }\n responseFinished = true;\n this._closeHttpSpan(span, SpanKind.CLIENT, startTime, metricAttributes);\n });\n request.on(errorMonitor, (error: Err) => {\n this._diag.debug('outgoingRequest on request error()', error);\n if (responseFinished) {\n return;\n }\n responseFinished = true;\n this._onOutgoingRequestError(span, metricAttributes, startTime, error);\n });\n\n this._diag.debug('http.ClientRequest return request');\n return request;\n }\n\n private _incomingRequestFunction(\n component: 'http' | 'https',\n original: (event: string, ...args: unknown[]) => boolean\n ) {\n const instrumentation = this;\n return function incomingRequest(\n this: unknown,\n event: string,\n ...args: unknown[]\n ): boolean {\n // Only traces request events\n if (event !== 'request') {\n return original.apply(this, [event, ...args]);\n }\n\n const request = args[0] as http.IncomingMessage;\n const response = args[1] as http.ServerResponse & { socket: Socket };\n const method = request.method || 'GET';\n\n instrumentation._diag.debug(\n `${component} instrumentation incomingRequest`\n );\n\n if (\n safeExecuteInTheMiddle(\n () =>\n instrumentation.getConfig().ignoreIncomingRequestHook?.(request),\n (e: unknown) => {\n if (e != null) {\n instrumentation._diag.error(\n 'caught ignoreIncomingRequestHook error: ',\n e\n );\n }\n },\n true\n )\n ) {\n return context.with(suppressTracing(context.active()), () => {\n context.bind(context.active(), request);\n context.bind(context.active(), response);\n return original.apply(this, [event, ...args]);\n });\n }\n\n const headers = request.headers;\n\n const spanAttributes = getIncomingRequestAttributes(\n request,\n {\n component: component,\n hookAttributes: instrumentation._callStartSpanHook(\n request,\n instrumentation.getConfig().startIncomingSpanHook\n ),\n enableSyntheticSourceDetection:\n instrumentation.getConfig().enableSyntheticSourceDetection || false,\n },\n instrumentation._diag\n );\n\n Object.assign(\n spanAttributes,\n instrumentation._headerCapture.server.captureRequestHeaders(\n header => request.headers[header]\n )\n );\n\n const spanOptions: SpanOptions = {\n kind: SpanKind.SERVER,\n attributes: spanAttributes,\n };\n\n const startTime = hrTime();\n\n // request method and url.scheme are both required span attributes\n const metricAttributes: Attributes = {\n [ATTR_HTTP_REQUEST_METHOD]: spanAttributes[ATTR_HTTP_REQUEST_METHOD],\n [ATTR_URL_SCHEME]: spanAttributes[ATTR_URL_SCHEME],\n };\n\n // recommended if and only if one was sent, same as span recommendation\n if (spanAttributes[ATTR_NETWORK_PROTOCOL_VERSION]) {\n metricAttributes[ATTR_NETWORK_PROTOCOL_VERSION] =\n spanAttributes[ATTR_NETWORK_PROTOCOL_VERSION];\n }\n\n const ctx = propagation.extract(ROOT_CONTEXT, headers);\n const span = instrumentation._startHttpSpan(method, spanOptions, ctx);\n const rpcMetadata: RPCMetadata = {\n type: RPCType.HTTP,\n span,\n };\n\n return context.with(\n setRPCMetadata(trace.setSpan(ctx, span), rpcMetadata),\n () => {\n context.bind(context.active(), request);\n context.bind(context.active(), response);\n\n if (instrumentation.getConfig().requestHook) {\n instrumentation._callRequestHook(span, request);\n }\n if (instrumentation.getConfig().responseHook) {\n instrumentation._callResponseHook(span, response);\n }\n\n // After 'error', no further events other than 'close' should be emitted.\n let hasError = false;\n response.on('close', () => {\n if (hasError) {\n return;\n }\n instrumentation._onServerResponseFinish(\n request,\n response,\n span,\n metricAttributes,\n startTime\n );\n });\n response.on(errorMonitor, (err: Err) => {\n hasError = true;\n instrumentation._onServerResponseError(\n span,\n metricAttributes,\n startTime,\n err\n );\n });\n\n return safeExecuteInTheMiddle(\n () => original.apply(this, [event, ...args]),\n error => {\n if (error) {\n instrumentation._onServerResponseError(\n span,\n metricAttributes,\n startTime,\n error\n );\n throw error;\n }\n }\n );\n }\n );\n };\n }\n\n private _outgoingRequestFunction(\n component: 'http' | 'https',\n original: Func<http.ClientRequest>\n ): Func<http.ClientRequest> {\n const instrumentation = this;\n return function outgoingRequest(\n this: unknown,\n options: url.URL | http.RequestOptions | string,\n ...args: unknown[]\n ): http.ClientRequest {\n if (!isValidOptionsType(options)) {\n return original.apply(this, [options, ...args]);\n }\n const extraOptions =\n typeof args[0] === 'object' &&\n (typeof options === 'string' || options instanceof url.URL)\n ? (args.shift() as http.RequestOptions)\n : undefined;\n const { method, invalidUrl, optionsParsed } = getRequestInfo(\n instrumentation._diag,\n options,\n extraOptions\n );\n\n if (\n safeExecuteInTheMiddle(\n () =>\n instrumentation\n .getConfig()\n .ignoreOutgoingRequestHook?.(optionsParsed),\n (e: unknown) => {\n if (e != null) {\n instrumentation._diag.error(\n 'caught ignoreOutgoingRequestHook error: ',\n e\n );\n }\n },\n true\n )\n ) {\n return original.apply(this, [optionsParsed, ...args]);\n }\n\n const { hostname, port } = extractHostnameAndPort(optionsParsed);\n const attributes = getOutgoingRequestAttributes(\n optionsParsed,\n {\n component,\n port,\n hostname,\n hookAttributes: instrumentation._callStartSpanHook(\n optionsParsed,\n instrumentation.getConfig().startOutgoingSpanHook\n ),\n redactedQueryParams: instrumentation.getConfig().redactedQueryParams, // Added config for adding custom query strings\n },\n instrumentation.getConfig().enableSyntheticSourceDetection || false\n );\n\n const startTime = hrTime();\n\n // request method, server address, and server port are both required span attributes\n const metricAttributes: Attributes = {\n [ATTR_HTTP_REQUEST_METHOD]: attributes[ATTR_HTTP_REQUEST_METHOD],\n [ATTR_SERVER_ADDRESS]: attributes[ATTR_SERVER_ADDRESS],\n [ATTR_SERVER_PORT]: attributes[ATTR_SERVER_PORT],\n };\n\n // required if and only if one was sent, same as span requirement\n if (attributes[ATTR_HTTP_RESPONSE_STATUS_CODE]) {\n metricAttributes[ATTR_HTTP_RESPONSE_STATUS_CODE] =\n attributes[ATTR_HTTP_RESPONSE_STATUS_CODE];\n }\n\n // recommended if and only if one was sent, same as span recommendation\n if (attributes[ATTR_NETWORK_PROTOCOL_VERSION]) {\n metricAttributes[ATTR_NETWORK_PROTOCOL_VERSION] =\n attributes[ATTR_NETWORK_PROTOCOL_VERSION];\n }\n\n const spanOptions: SpanOptions = {\n kind: SpanKind.CLIENT,\n attributes,\n };\n const span = instrumentation._startHttpSpan(method, spanOptions);\n\n const parentContext = context.active();\n const requestContext = trace.setSpan(parentContext, span);\n\n if (!optionsParsed.headers) {\n optionsParsed.headers = {};\n } else {\n // Make a copy of the headers object to avoid mutating an object the\n // caller might have a reference to.\n optionsParsed.headers = Object.assign({}, optionsParsed.headers);\n }\n propagation.inject(requestContext, optionsParsed.headers);\n\n return context.with(requestContext, () => {\n /*\n * The response callback is registered before ClientRequest is bound,\n * thus it is needed to bind it before the function call.\n */\n const cb = args[args.length - 1];\n if (typeof cb === 'function') {\n args[args.length - 1] = context.bind(parentContext, cb);\n }\n\n const request: http.ClientRequest = safeExecuteInTheMiddle(\n () => {\n if (invalidUrl) {\n // we know that the url is invalid, there's no point in injecting context as it will fail validation.\n // Passing in what the user provided will give the user an error that matches what they'd see without\n // the instrumentation.\n return original.apply(this, [options, ...args]);\n } else {\n return original.apply(this, [optionsParsed, ...args]);\n }\n },\n error => {\n if (error) {\n instrumentation._onOutgoingRequestError(\n span,\n metricAttributes,\n startTime,\n error\n );\n throw error;\n }\n }\n );\n\n instrumentation._diag.debug(\n `${component} instrumentation outgoingRequest`\n );\n context.bind(parentContext, request);\n return instrumentation._traceClientRequest(\n request,\n span,\n startTime,\n metricAttributes\n );\n });\n };\n }\n\n private _onServerResponseFinish(\n request: http.IncomingMessage,\n response: http.ServerResponse,\n span: Span,\n metricAttributes: Attributes,\n startTime: HrTime\n ) {\n const attributes = getIncomingRequestAttributesOnResponse(response);\n metricAttributes = Object.assign(\n metricAttributes,\n getIncomingStableRequestMetricAttributesOnResponse(attributes)\n );\n\n span.setAttributes(\n this._headerCapture.server.captureResponseHeaders(header =>\n response.getHeader(header)\n )\n );\n\n span.setAttributes(attributes).setStatus({\n code: parseResponseStatus(SpanKind.SERVER, response.statusCode),\n });\n\n const route = attributes[ATTR_HTTP_ROUTE];\n if (route) {\n span.updateName(`${request.method || 'GET'} ${route}`);\n }\n\n if (this.getConfig().applyCustomAttributesOnSpan) {\n safeExecuteInTheMiddle(\n () =>\n this.getConfig().applyCustomAttributesOnSpan!(\n span,\n request,\n response\n ),\n () => {},\n true\n );\n }\n\n this._closeHttpSpan(span, SpanKind.SERVER, startTime, metricAttributes);\n }\n\n private _onOutgoingRequestError(\n span: Span,\n metricAttributes: Attributes,\n startTime: HrTime,\n error: Err\n ) {\n setSpanWithError(span, error);\n metricAttributes[ATTR_ERROR_TYPE] = error.name;\n\n this._closeHttpSpan(span, SpanKind.CLIENT, startTime, metricAttributes);\n }\n\n private _onServerResponseError(\n span: Span,\n metricAttributes: Attributes,\n startTime: HrTime,\n error: Err\n ) {\n setSpanWithError(span, error);\n metricAttributes[ATTR_ERROR_TYPE] = error.name;\n\n this._closeHttpSpan(span, SpanKind.SERVER, startTime, metricAttributes);\n }\n\n private _startHttpSpan(\n name: string,\n options: SpanOptions,\n ctx = context.active()\n ) {\n /*\n * If a parent is required but not present, we use a `NoopSpan` to still\n * propagate context without recording it.\n */\n const requireParent =\n options.kind === SpanKind.CLIENT\n ? this.getConfig().requireParentforOutgoingSpans\n : this.getConfig().requireParentforIncomingSpans;\n\n let span: Span;\n const currentSpan = trace.getSpan(ctx);\n\n if (\n requireParent === true &&\n (!currentSpan || !trace.isSpanContextValid(currentSpan.spanContext()))\n ) {\n span = trace.wrapSpanContext(INVALID_SPAN_CONTEXT);\n } else if (requireParent === true && currentSpan?.spanContext().isRemote) {\n span = currentSpan;\n } else {\n span = this.tracer.startSpan(name, options, ctx);\n }\n this._spanNotEnded.add(span);\n return span;\n }\n\n private _closeHttpSpan(\n span: Span,\n spanKind: SpanKind,\n startTime: HrTime,\n metricAttributes: Attributes\n ) {\n if (!this._spanNotEnded.has(span)) {\n return;\n }\n\n span.end();\n this._spanNotEnded.delete(span);\n\n // Record metrics\n const duration = hrTimeToMilliseconds(hrTimeDuration(startTime, hrTime()));\n if (spanKind === SpanKind.SERVER) {\n this._recordServerDuration(duration, metricAttributes);\n } else if (spanKind === SpanKind.CLIENT) {\n this._recordClientDuration(duration, metricAttributes);\n }\n }\n\n private _callResponseHook(\n span: Span,\n response: http.IncomingMessage | http.ServerResponse\n ) {\n safeExecuteInTheMiddle(\n () => this.getConfig().responseHook!(span, response),\n () => {},\n true\n );\n }\n\n private _callRequestHook(\n span: Span,\n request: http.ClientRequest | http.IncomingMessage\n ) {\n safeExecuteInTheMiddle(\n () => this.getConfig().requestHook!(span, request),\n () => {},\n true\n );\n }\n\n private _callStartSpanHook(\n request: http.IncomingMessage | http.RequestOptions,\n hookFunc: Function | undefined\n ) {\n if (typeof hookFunc === 'function') {\n return safeExecuteInTheMiddle(\n () => hookFunc(request),\n () => {},\n true\n );\n }\n }\n\n private _createHeaderCapture() {\n const config = this.getConfig();\n\n return {\n client: {\n captureRequestHeaders: headerCapture(\n 'request',\n config.headersToSpanAttributes?.client?.requestHeaders ?? []\n ),\n captureResponseHeaders: headerCapture(\n 'response',\n config.headersToSpanAttributes?.client?.responseHeaders ?? []\n ),\n },\n server: {\n captureRequestHeaders: headerCapture(\n 'request',\n config.headersToSpanAttributes?.server?.requestHeaders ?? []\n ),\n captureResponseHeaders: headerCapture(\n 'response',\n config.headersToSpanAttributes?.server?.responseHeaders ?? []\n ),\n },\n };\n }\n}\n"]}