@opentelemetry/instrumentation-fetch 0.208.0 → 0.209.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 +21 -21
- package/build/esm/fetch.d.ts +3 -3
- package/build/esm/fetch.js +17 -20
- package/build/esm/fetch.js.map +1 -1
- package/build/esm/types.d.ts +2 -2
- package/build/esm/types.js.map +1 -1
- package/build/esm/utils.js +4 -2
- package/build/esm/utils.js.map +1 -1
- package/build/esm/version.d.ts +1 -1
- package/build/esm/version.js +1 -1
- package/build/esm/version.js.map +1 -1
- package/build/esnext/fetch.d.ts +3 -3
- package/build/esnext/fetch.js +17 -20
- package/build/esnext/fetch.js.map +1 -1
- package/build/esnext/types.d.ts +2 -2
- package/build/esnext/types.js.map +1 -1
- package/build/esnext/utils.js +4 -2
- package/build/esnext/utils.js.map +1 -1
- package/build/esnext/version.d.ts +1 -1
- package/build/esnext/version.js +1 -1
- package/build/esnext/version.js.map +1 -1
- package/build/src/fetch.d.ts +3 -3
- package/build/src/fetch.js +17 -20
- package/build/src/fetch.js.map +1 -1
- package/build/src/types.d.ts +2 -2
- package/build/src/types.js.map +1 -1
- package/build/src/utils.js +4 -2
- 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/README.md
CHANGED
|
@@ -66,13 +66,13 @@ See [examples/tracer-web/fetch](https://github.com/open-telemetry/opentelemetry-
|
|
|
66
66
|
|
|
67
67
|
Fetch instrumentation plugin has few options available to choose from. You can set the following:
|
|
68
68
|
|
|
69
|
-
| Options
|
|
70
|
-
|
|
|
71
|
-
| [`applyCustomAttributesOnSpan`](https://github.com/open-telemetry/opentelemetry-js/blob/main/experimental/packages/opentelemetry-instrumentation-fetch/src/fetch.ts#L83) | `FetchCustomAttributeFunction` | Function for adding custom attributes
|
|
72
|
-
| [`requestHook`](https://github.com/open-telemetry/opentelemetry-js/blob/main/experimental/packages/opentelemetry-instrumentation-fetch/src/fetch.ts#L85)
|
|
73
|
-
| [`ignoreNetworkEvents`](https://github.com/open-telemetry/opentelemetry-js/blob/main/experimental/packages/opentelemetry-instrumentation-fetch/src/fetch.ts#L87)
|
|
74
|
-
| [`measureRequestSize`](https://github.com/open-telemetry/opentelemetry-js/blob/main/experimental/packages/opentelemetry-instrumentation-fetch/src/fetch.ts#L89)
|
|
75
|
-
| `semconvStabilityOptIn`
|
|
69
|
+
| Options | Type | Description |
|
|
70
|
+
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
71
|
+
| [`applyCustomAttributesOnSpan`](https://github.com/open-telemetry/opentelemetry-js/blob/main/experimental/packages/opentelemetry-instrumentation-fetch/src/fetch.ts#L83) | `FetchCustomAttributeFunction` | Function for adding custom attributes |
|
|
72
|
+
| [`requestHook`](https://github.com/open-telemetry/opentelemetry-js/blob/main/experimental/packages/opentelemetry-instrumentation-fetch/src/fetch.ts#L85) | `FetchRequestHookFunction` | Function for adding custom attributes or headers before the request is handled |
|
|
73
|
+
| [`ignoreNetworkEvents`](https://github.com/open-telemetry/opentelemetry-js/blob/main/experimental/packages/opentelemetry-instrumentation-fetch/src/fetch.ts#L87) | `boolean` | Disable network events being added as span events (network events are added by default) |
|
|
74
|
+
| [`measureRequestSize`](https://github.com/open-telemetry/opentelemetry-js/blob/main/experimental/packages/opentelemetry-instrumentation-fetch/src/fetch.ts#L89) | `boolean` | Measure outgoing request length (outgoing request length is not measured by default) |
|
|
75
|
+
| `semconvStabilityOptIn` | string | A comma-separated string of tokens as described for `OTEL_SEMCONV_STABILITY_OPT_IN` in the [HTTP semantic convention stability migration](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/non-normative/http-migration.md) guide. See the "Semantic Conventions" section below. |
|
|
76
76
|
|
|
77
77
|
## Semantic Conventions
|
|
78
78
|
|
|
@@ -92,20 +92,20 @@ To select which semconv version(s) is emitted from this instrumentation, use the
|
|
|
92
92
|
|
|
93
93
|
**Span attributes:**
|
|
94
94
|
|
|
95
|
-
| v1.7.0 semconv
|
|
96
|
-
|
|
|
97
|
-
| `http.method`
|
|
98
|
-
| `http.url`
|
|
99
|
-
| `http.host`
|
|
100
|
-
| `http.status_code`
|
|
101
|
-
| `http.request_content_length_uncompressed`
|
|
102
|
-
| `http.response_content_length_uncompressed` | (not included)
|
|
103
|
-
| `http.response_content_length`
|
|
104
|
-
| (no equivalent)
|
|
105
|
-
| `http.user_agent`
|
|
106
|
-
| `http.scheme`
|
|
107
|
-
| `http.status_text`
|
|
108
|
-
| `component`
|
|
95
|
+
| v1.7.0 semconv | v1.23.0 semconv | Notes |
|
|
96
|
+
| ------------------------------------------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
97
|
+
| `http.method` | `http.request.method` | HTTP request method. With v1.23.0 semconv [`http.request.method_original` may also be included](https://github.com/open-telemetry/semantic-conventions/blob/v1.23.1/docs/http/http-spans.md#common-attributes). |
|
|
98
|
+
| `http.url` | `url.full` | Full HTTP request URL |
|
|
99
|
+
| `http.host` | `server.address` and `server.port` | The hostname and port of the request URL |
|
|
100
|
+
| `http.status_code` | `http.response.status_code` | HTTP response status code |
|
|
101
|
+
| `http.request_content_length_uncompressed` | `http.request.body.size` | This is only added if `measureRequestSize` is `true`. |
|
|
102
|
+
| `http.response_content_length_uncompressed` | (not included) | Stable HTTP semconv would use `http.response.body.size`, but this is an [`Opt-In` attribute](https://github.com/open-telemetry/semantic-conventions/blob/v1.23.1/docs/http/http-spans.md#http-client), so would require adding a configuration option to this instrumentation to enable. |
|
|
103
|
+
| `http.response_content_length` | (not included) | Stable HTTP semconv would use `http.response.header.<key>`, but this is an [`Opt-In` attribute](https://github.com/open-telemetry/semantic-conventions/blob/v1.23.1/docs/http/http-spans.md#http-client), so would require adding a configuration option to this instrumentation to enable. |
|
|
104
|
+
| (no equivalent) | `error.type` | The response status (as a string), if the response status was `>=400`. |
|
|
105
|
+
| `http.user_agent` | (not included) | Stable HTTP semconv would use `user_agent.original`, but this is an [`Opt-In` attribute](https://github.com/open-telemetry/semantic-conventions/blob/v1.23.1/docs/http/http-spans.md#http-client), so would require adding a configuration option to this instrumentation to enable. |
|
|
106
|
+
| `http.scheme` | (not included) | Stable HTTP semconv would use `url.scheme`, but this is an [`Opt-In` attribute](https://github.com/open-telemetry/semantic-conventions/blob/v1.23.1/docs/http/http-spans.md#http-client), so would require adding a configuration option to this instrumentation to enable. |
|
|
107
|
+
| `http.status_text` | (not included) | This is no longer a documented semantic conventions attribute. |
|
|
108
|
+
| `component` | (no replacement) | `component` was an ancient Span "tag" that was never formalized. |
|
|
109
109
|
|
|
110
110
|
## Useful links
|
|
111
111
|
|
package/build/esm/fetch.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import
|
|
1
|
+
import type { Span } from '@opentelemetry/api';
|
|
2
2
|
import { InstrumentationBase, InstrumentationConfig } from '@opentelemetry/instrumentation';
|
|
3
3
|
import * as web from '@opentelemetry/sdk-trace-web';
|
|
4
4
|
import { FetchError } from './types';
|
|
5
5
|
export interface FetchCustomAttributeFunction {
|
|
6
|
-
(span:
|
|
6
|
+
(span: Span, request: Request | RequestInit, result: Response | FetchError): void;
|
|
7
7
|
}
|
|
8
8
|
export interface FetchRequestHookFunction {
|
|
9
|
-
(span:
|
|
9
|
+
(span: Span, request: Request | RequestInit): void;
|
|
10
10
|
}
|
|
11
11
|
/**
|
|
12
12
|
* FetchPlugin Config
|
package/build/esm/fetch.js
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* See the License for the specific language governing permissions and
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
|
-
import
|
|
16
|
+
import { context, propagation, SpanKind, SpanStatusCode, trace, } from '@opentelemetry/api';
|
|
17
17
|
import { SemconvStability, semconvStabilityFromStr, isWrapped, InstrumentationBase, safeExecuteInTheMiddle, } from '@opentelemetry/instrumentation';
|
|
18
18
|
import * as core from '@opentelemetry/core';
|
|
19
19
|
import * as web from '@opentelemetry/sdk-trace-web';
|
|
@@ -22,13 +22,12 @@ import { ATTR_HTTP_STATUS_CODE, ATTR_HTTP_HOST, ATTR_HTTP_USER_AGENT, ATTR_HTTP_
|
|
|
22
22
|
import { ATTR_ERROR_TYPE, ATTR_HTTP_REQUEST_METHOD, ATTR_HTTP_REQUEST_METHOD_ORIGINAL, ATTR_HTTP_RESPONSE_STATUS_CODE, ATTR_SERVER_ADDRESS, ATTR_SERVER_PORT, ATTR_URL_FULL, } from '@opentelemetry/semantic-conventions';
|
|
23
23
|
import { getFetchBodyLength, normalizeHttpRequestMethod, serverPortFromUrl, } from './utils';
|
|
24
24
|
import { VERSION } from './version';
|
|
25
|
-
import { _globalThis } from '@opentelemetry/core';
|
|
26
25
|
// how long to wait for observer to collect information about resources
|
|
27
26
|
// this is needed as event "load" is called before observer
|
|
28
27
|
// hard to say how long it should really wait, seems like 300ms is
|
|
29
28
|
// safe enough
|
|
30
29
|
const OBSERVER_WAIT_TIME_MS = 300;
|
|
31
|
-
const
|
|
30
|
+
const hasBrowserPerformanceAPI = typeof PerformanceObserver !== 'undefined';
|
|
32
31
|
/**
|
|
33
32
|
* This class represents a fetch plugin for auto instrumentation
|
|
34
33
|
*/
|
|
@@ -52,7 +51,7 @@ export class FetchInstrumentation extends InstrumentationBase {
|
|
|
52
51
|
_addChildSpan(span, corsPreFlightRequest) {
|
|
53
52
|
const childSpan = this.tracer.startSpan('CORS Preflight', {
|
|
54
53
|
startTime: corsPreFlightRequest[web.PerformanceTimingNames.FETCH_START],
|
|
55
|
-
},
|
|
54
|
+
}, trace.setSpan(context.active(), span));
|
|
56
55
|
const skipOldSemconvContentLengthAttrs = !(this._semconvStability & SemconvStability.OLD);
|
|
57
56
|
web.addSpanNetworkEvents(childSpan, corsPreFlightRequest, this.getConfig().ignoreNetworkEvents, undefined, skipOldSemconvContentLengthAttrs);
|
|
58
57
|
childSpan.end(corsPreFlightRequest[web.PerformanceTimingNames.RESPONSE_END]);
|
|
@@ -94,30 +93,30 @@ export class FetchInstrumentation extends InstrumentationBase {
|
|
|
94
93
|
_addHeaders(options, spanUrl) {
|
|
95
94
|
if (!web.shouldPropagateTraceHeaders(spanUrl, this.getConfig().propagateTraceHeaderCorsUrls)) {
|
|
96
95
|
const headers = {};
|
|
97
|
-
|
|
96
|
+
propagation.inject(context.active(), headers);
|
|
98
97
|
if (Object.keys(headers).length > 0) {
|
|
99
98
|
this._diag.debug('headers inject skipped due to CORS policy');
|
|
100
99
|
}
|
|
101
100
|
return;
|
|
102
101
|
}
|
|
103
102
|
if (options instanceof Request) {
|
|
104
|
-
|
|
103
|
+
propagation.inject(context.active(), options.headers, {
|
|
105
104
|
set: (h, k, v) => h.set(k, typeof v === 'string' ? v : String(v)),
|
|
106
105
|
});
|
|
107
106
|
}
|
|
108
107
|
else if (options.headers instanceof Headers) {
|
|
109
|
-
|
|
108
|
+
propagation.inject(context.active(), options.headers, {
|
|
110
109
|
set: (h, k, v) => h.set(k, typeof v === 'string' ? v : String(v)),
|
|
111
110
|
});
|
|
112
111
|
}
|
|
113
112
|
else if (options.headers instanceof Map) {
|
|
114
|
-
|
|
113
|
+
propagation.inject(context.active(), options.headers, {
|
|
115
114
|
set: (h, k, v) => h.set(k, typeof v === 'string' ? v : String(v)),
|
|
116
115
|
});
|
|
117
116
|
}
|
|
118
117
|
else {
|
|
119
118
|
const headers = {};
|
|
120
|
-
|
|
119
|
+
propagation.inject(context.active(), headers);
|
|
121
120
|
options.headers = Object.assign({}, headers, options.headers || {});
|
|
122
121
|
}
|
|
123
122
|
}
|
|
@@ -167,7 +166,7 @@ export class FetchInstrumentation extends InstrumentationBase {
|
|
|
167
166
|
attributes[ATTR_URL_FULL] = url;
|
|
168
167
|
}
|
|
169
168
|
return this.tracer.startSpan(name, {
|
|
170
|
-
kind:
|
|
169
|
+
kind: SpanKind.CLIENT,
|
|
171
170
|
attributes,
|
|
172
171
|
});
|
|
173
172
|
}
|
|
@@ -223,7 +222,7 @@ export class FetchInstrumentation extends InstrumentationBase {
|
|
|
223
222
|
if (this._semconvStability & SemconvStability.STABLE) {
|
|
224
223
|
// https://github.com/open-telemetry/semantic-conventions/blob/main/docs/http/http-spans.md#status
|
|
225
224
|
if (response.status >= 400) {
|
|
226
|
-
span.setStatus({ code:
|
|
225
|
+
span.setStatus({ code: SpanStatusCode.ERROR });
|
|
227
226
|
span.setAttribute(ATTR_ERROR_TYPE, String(response.status));
|
|
228
227
|
}
|
|
229
228
|
}
|
|
@@ -381,7 +380,7 @@ export class FetchInstrumentation extends InstrumentationBase {
|
|
|
381
380
|
}
|
|
382
381
|
}
|
|
383
382
|
return new Promise((resolve, reject) => {
|
|
384
|
-
return
|
|
383
|
+
return context.with(trace.setSpan(context.active(), createdSpan), () => {
|
|
385
384
|
plugin._addHeaders(options, url);
|
|
386
385
|
plugin._callRequestHook(createdSpan, options);
|
|
387
386
|
plugin._tasksCount++;
|
|
@@ -443,26 +442,24 @@ export class FetchInstrumentation extends InstrumentationBase {
|
|
|
443
442
|
* implements enable function
|
|
444
443
|
*/
|
|
445
444
|
enable() {
|
|
446
|
-
if (
|
|
447
|
-
|
|
448
|
-
// support instrumenting it.
|
|
449
|
-
this._diag.warn("this instrumentation is intended for web usage only, it does not instrument Node.js's fetch()");
|
|
445
|
+
if (!hasBrowserPerformanceAPI) {
|
|
446
|
+
this._diag.warn('this instrumentation is intended for web usage only, it does not instrument server-side fetch()');
|
|
450
447
|
return;
|
|
451
448
|
}
|
|
452
449
|
if (isWrapped(fetch)) {
|
|
453
|
-
this._unwrap(
|
|
450
|
+
this._unwrap(globalThis, 'fetch');
|
|
454
451
|
this._diag.debug('removing previous patch for constructor');
|
|
455
452
|
}
|
|
456
|
-
this._wrap(
|
|
453
|
+
this._wrap(globalThis, 'fetch', this._patchConstructor());
|
|
457
454
|
}
|
|
458
455
|
/**
|
|
459
456
|
* implements unpatch function
|
|
460
457
|
*/
|
|
461
458
|
disable() {
|
|
462
|
-
if (
|
|
459
|
+
if (!hasBrowserPerformanceAPI) {
|
|
463
460
|
return;
|
|
464
461
|
}
|
|
465
|
-
this._unwrap(
|
|
462
|
+
this._unwrap(globalThis, 'fetch');
|
|
466
463
|
this._usedResources = new WeakSet();
|
|
467
464
|
}
|
|
468
465
|
}
|
package/build/esm/fetch.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../src/fetch.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 */\n\nimport * as api from '@opentelemetry/api';\nimport {\n SemconvStability,\n semconvStabilityFromStr,\n isWrapped,\n InstrumentationBase,\n InstrumentationConfig,\n safeExecuteInTheMiddle,\n} from '@opentelemetry/instrumentation';\nimport * as core from '@opentelemetry/core';\nimport * as web from '@opentelemetry/sdk-trace-web';\nimport { AttributeNames } from './enums/AttributeNames';\nimport {\n ATTR_HTTP_STATUS_CODE,\n ATTR_HTTP_HOST,\n ATTR_HTTP_USER_AGENT,\n ATTR_HTTP_SCHEME,\n ATTR_HTTP_URL,\n ATTR_HTTP_METHOD,\n ATTR_HTTP_REQUEST_CONTENT_LENGTH_UNCOMPRESSED,\n ATTR_HTTP_REQUEST_BODY_SIZE,\n} from './semconv';\nimport {\n ATTR_ERROR_TYPE,\n ATTR_HTTP_REQUEST_METHOD,\n ATTR_HTTP_REQUEST_METHOD_ORIGINAL,\n ATTR_HTTP_RESPONSE_STATUS_CODE,\n ATTR_SERVER_ADDRESS,\n ATTR_SERVER_PORT,\n ATTR_URL_FULL,\n} from '@opentelemetry/semantic-conventions';\nimport { FetchError, FetchResponse, SpanData } from './types';\nimport {\n getFetchBodyLength,\n normalizeHttpRequestMethod,\n serverPortFromUrl,\n} from './utils';\nimport { VERSION } from './version';\nimport { _globalThis } from '@opentelemetry/core';\n\n// how long to wait for observer to collect information about resources\n// this is needed as event \"load\" is called before observer\n// hard to say how long it should really wait, seems like 300ms is\n// safe enough\nconst OBSERVER_WAIT_TIME_MS = 300;\n\nconst isNode = typeof process === 'object' && process.release?.name === 'node';\n\nexport interface FetchCustomAttributeFunction {\n (\n span: api.Span,\n request: Request | RequestInit,\n result: Response | FetchError\n ): void;\n}\n\nexport interface FetchRequestHookFunction {\n (span: api.Span, request: Request | RequestInit): void;\n}\n\n/**\n * FetchPlugin Config\n */\nexport interface FetchInstrumentationConfig extends InstrumentationConfig {\n // the number of timing resources is limited, after the limit\n // (chrome 250, safari 150) the information is not collected anymore\n // the only way to prevent that is to regularly clean the resources\n // whenever it is possible, this is needed only when PerformanceObserver\n // is not available\n clearTimingResources?: boolean;\n // urls which should include trace headers when origin doesn't match\n propagateTraceHeaderCorsUrls?: web.PropagateTraceHeaderCorsUrls;\n /**\n * URLs that partially match any regex in ignoreUrls will not be traced.\n * In addition, URLs that are _exact matches_ of strings in ignoreUrls will\n * also not be traced.\n */\n ignoreUrls?: Array<string | RegExp>;\n /** Function for adding custom attributes on the span */\n applyCustomAttributesOnSpan?: FetchCustomAttributeFunction;\n /** Function for adding custom attributes or headers before the request is handled */\n requestHook?: FetchRequestHookFunction;\n // Ignore adding network events as span events\n ignoreNetworkEvents?: boolean;\n /** Measure outgoing request size */\n measureRequestSize?: boolean;\n /** Select the HTTP semantic conventions version(s) used. */\n semconvStabilityOptIn?: string;\n}\n\n/**\n * This class represents a fetch plugin for auto instrumentation\n */\nexport class FetchInstrumentation extends InstrumentationBase<FetchInstrumentationConfig> {\n readonly component: string = 'fetch';\n readonly version: string = VERSION;\n moduleName = this.component;\n private _usedResources = new WeakSet<PerformanceResourceTiming>();\n private _tasksCount = 0;\n\n private _semconvStability: SemconvStability;\n\n constructor(config: FetchInstrumentationConfig = {}) {\n super('@opentelemetry/instrumentation-fetch', VERSION, config);\n this._semconvStability = semconvStabilityFromStr(\n 'http',\n config?.semconvStabilityOptIn\n );\n }\n\n init(): void {}\n\n /**\n * Add cors pre flight child span\n * @param span\n * @param corsPreFlightRequest\n */\n private _addChildSpan(\n span: api.Span,\n corsPreFlightRequest: PerformanceResourceTiming\n ): void {\n const childSpan = this.tracer.startSpan(\n 'CORS Preflight',\n {\n startTime: corsPreFlightRequest[web.PerformanceTimingNames.FETCH_START],\n },\n api.trace.setSpan(api.context.active(), span)\n );\n const skipOldSemconvContentLengthAttrs = !(\n this._semconvStability & SemconvStability.OLD\n );\n web.addSpanNetworkEvents(\n childSpan,\n corsPreFlightRequest,\n this.getConfig().ignoreNetworkEvents,\n undefined,\n skipOldSemconvContentLengthAttrs\n );\n childSpan.end(\n corsPreFlightRequest[web.PerformanceTimingNames.RESPONSE_END]\n );\n }\n\n /**\n * Adds more attributes to span just before ending it\n * @param span\n * @param response\n */\n private _addFinalSpanAttributes(\n span: api.Span,\n response: FetchResponse\n ): void {\n const parsedUrl = web.parseUrl(response.url);\n\n if (this._semconvStability & SemconvStability.OLD) {\n span.setAttribute(ATTR_HTTP_STATUS_CODE, response.status);\n if (response.statusText != null) {\n span.setAttribute(AttributeNames.HTTP_STATUS_TEXT, response.statusText);\n }\n span.setAttribute(ATTR_HTTP_HOST, parsedUrl.host);\n span.setAttribute(ATTR_HTTP_SCHEME, parsedUrl.protocol.replace(':', ''));\n if (typeof navigator !== 'undefined') {\n span.setAttribute(ATTR_HTTP_USER_AGENT, navigator.userAgent);\n }\n }\n\n if (this._semconvStability & SemconvStability.STABLE) {\n span.setAttribute(ATTR_HTTP_RESPONSE_STATUS_CODE, response.status);\n // TODO: Set server.{address,port} at span creation for sampling decisions\n // (a \"SHOULD\" requirement in semconv).\n span.setAttribute(ATTR_SERVER_ADDRESS, parsedUrl.hostname);\n const serverPort = serverPortFromUrl(parsedUrl);\n if (serverPort) {\n span.setAttribute(ATTR_SERVER_PORT, serverPort);\n }\n }\n }\n\n /**\n * Add headers\n * @param options\n * @param spanUrl\n */\n private _addHeaders(options: Request | RequestInit, spanUrl: string): void {\n if (\n !web.shouldPropagateTraceHeaders(\n spanUrl,\n this.getConfig().propagateTraceHeaderCorsUrls\n )\n ) {\n const headers: Partial<Record<string, unknown>> = {};\n api.propagation.inject(api.context.active(), headers);\n if (Object.keys(headers).length > 0) {\n this._diag.debug('headers inject skipped due to CORS policy');\n }\n return;\n }\n\n if (options instanceof Request) {\n api.propagation.inject(api.context.active(), options.headers, {\n set: (h, k, v) => h.set(k, typeof v === 'string' ? v : String(v)),\n });\n } else if (options.headers instanceof Headers) {\n api.propagation.inject(api.context.active(), options.headers, {\n set: (h, k, v) => h.set(k, typeof v === 'string' ? v : String(v)),\n });\n } else if (options.headers instanceof Map) {\n api.propagation.inject(api.context.active(), options.headers, {\n set: (h, k, v) => h.set(k, typeof v === 'string' ? v : String(v)),\n });\n } else {\n const headers: Partial<Record<string, unknown>> = {};\n api.propagation.inject(api.context.active(), headers);\n options.headers = Object.assign({}, headers, options.headers || {});\n }\n }\n\n /**\n * Clears the resource timings and all resources assigned with spans\n * when {@link FetchPluginConfig.clearTimingResources} is\n * set to true (default false)\n * @private\n */\n private _clearResources() {\n if (this._tasksCount === 0 && this.getConfig().clearTimingResources) {\n performance.clearResourceTimings();\n this._usedResources = new WeakSet<PerformanceResourceTiming>();\n }\n }\n\n /**\n * Creates a new span\n * @param url\n * @param options\n */\n private _createSpan(\n url: string,\n options: Partial<Request | RequestInit> = {}\n ): api.Span | undefined {\n if (core.isUrlIgnored(url, this.getConfig().ignoreUrls)) {\n this._diag.debug('ignoring span as url matches ignored url');\n return;\n }\n\n let name = '';\n const attributes = {} as api.Attributes;\n if (this._semconvStability & SemconvStability.OLD) {\n const method = (options.method || 'GET').toUpperCase();\n name = `HTTP ${method}`;\n attributes[AttributeNames.COMPONENT] = this.moduleName;\n attributes[ATTR_HTTP_METHOD] = method;\n attributes[ATTR_HTTP_URL] = url;\n }\n if (this._semconvStability & SemconvStability.STABLE) {\n const origMethod = options.method;\n const normMethod = normalizeHttpRequestMethod(options.method || 'GET');\n if (!name) {\n // The \"old\" span name wins if emitting both old and stable semconv\n // ('http/dup').\n name = normMethod;\n }\n attributes[ATTR_HTTP_REQUEST_METHOD] = normMethod;\n if (normMethod !== origMethod) {\n attributes[ATTR_HTTP_REQUEST_METHOD_ORIGINAL] = origMethod;\n }\n attributes[ATTR_URL_FULL] = url;\n }\n\n return this.tracer.startSpan(name, {\n kind: api.SpanKind.CLIENT,\n attributes,\n });\n }\n\n /**\n * Finds appropriate resource and add network events to the span\n * @param span\n * @param resourcesObserver\n * @param endTime\n */\n private _findResourceAndAddNetworkEvents(\n span: api.Span,\n resourcesObserver: SpanData,\n endTime: api.HrTime\n ): void {\n let resources: PerformanceResourceTiming[] = resourcesObserver.entries;\n if (!resources.length) {\n if (!performance.getEntriesByType) {\n return;\n }\n // fallback - either Observer is not available or it took longer\n // then OBSERVER_WAIT_TIME_MS and observer didn't collect enough\n // information\n resources = performance.getEntriesByType(\n 'resource'\n ) as PerformanceResourceTiming[];\n }\n const resource = web.getResource(\n resourcesObserver.spanUrl,\n resourcesObserver.startTime,\n endTime,\n resources,\n this._usedResources,\n 'fetch'\n );\n\n if (resource.mainRequest) {\n const mainRequest = resource.mainRequest;\n this._markResourceAsUsed(mainRequest);\n\n const corsPreFlightRequest = resource.corsPreFlightRequest;\n if (corsPreFlightRequest) {\n this._addChildSpan(span, corsPreFlightRequest);\n this._markResourceAsUsed(corsPreFlightRequest);\n }\n const skipOldSemconvContentLengthAttrs = !(\n this._semconvStability & SemconvStability.OLD\n );\n web.addSpanNetworkEvents(\n span,\n mainRequest,\n this.getConfig().ignoreNetworkEvents,\n undefined,\n skipOldSemconvContentLengthAttrs\n );\n }\n }\n\n /**\n * Marks certain [resource]{@link PerformanceResourceTiming} when information\n * from this is used to add events to span.\n * This is done to avoid reusing the same resource again for next span\n * @param resource\n */\n private _markResourceAsUsed(resource: PerformanceResourceTiming): void {\n this._usedResources.add(resource);\n }\n\n /**\n * Finish span, add attributes, network events etc.\n * @param span\n * @param spanData\n * @param response\n */\n private _endSpan(\n span: api.Span,\n spanData: SpanData,\n response: FetchResponse\n ) {\n const endTime = core.millisToHrTime(Date.now());\n const performanceEndTime = core.hrTime();\n this._addFinalSpanAttributes(span, response);\n\n if (this._semconvStability & SemconvStability.STABLE) {\n // https://github.com/open-telemetry/semantic-conventions/blob/main/docs/http/http-spans.md#status\n if (response.status >= 400) {\n span.setStatus({ code: api.SpanStatusCode.ERROR });\n span.setAttribute(ATTR_ERROR_TYPE, String(response.status));\n }\n }\n\n setTimeout(() => {\n spanData.observer?.disconnect();\n this._findResourceAndAddNetworkEvents(span, spanData, performanceEndTime);\n this._tasksCount--;\n this._clearResources();\n span.end(endTime);\n }, OBSERVER_WAIT_TIME_MS);\n }\n\n /**\n * Patches the constructor of fetch\n */\n private _patchConstructor(): (original: typeof fetch) => typeof fetch {\n return original => {\n const plugin = this;\n return function patchConstructor(\n this: typeof globalThis,\n ...args: Parameters<typeof fetch>\n ): Promise<Response> {\n const self = this;\n const url = web.parseUrl(\n args[0] instanceof Request ? args[0].url : String(args[0])\n ).href;\n\n const options = args[0] instanceof Request ? args[0] : args[1] || {};\n const createdSpan = plugin._createSpan(url, options);\n if (!createdSpan) {\n return original.apply(this, args);\n }\n const spanData = plugin._prepareSpanData(url);\n\n if (plugin.getConfig().measureRequestSize) {\n getFetchBodyLength(...args)\n .then(bodyLength => {\n if (!bodyLength) return;\n if (plugin._semconvStability & SemconvStability.OLD) {\n createdSpan.setAttribute(\n ATTR_HTTP_REQUEST_CONTENT_LENGTH_UNCOMPRESSED,\n bodyLength\n );\n }\n if (plugin._semconvStability & SemconvStability.STABLE) {\n createdSpan.setAttribute(\n ATTR_HTTP_REQUEST_BODY_SIZE,\n bodyLength\n );\n }\n })\n .catch(error => {\n plugin._diag.warn('getFetchBodyLength', error);\n });\n }\n\n function endSpanOnError(span: api.Span, error: FetchError) {\n plugin._applyAttributesAfterFetch(span, options, error);\n plugin._endSpan(span, spanData, {\n status: error.status || 0,\n statusText: error.message,\n url,\n });\n }\n\n function endSpanOnSuccess(span: api.Span, response: Response) {\n plugin._applyAttributesAfterFetch(span, options, response);\n if (response.status >= 200 && response.status < 400) {\n plugin._endSpan(span, spanData, response);\n } else {\n plugin._endSpan(span, spanData, {\n status: response.status,\n statusText: response.statusText,\n url,\n });\n }\n }\n\n function withCancelPropagation(\n body: ReadableStream<Uint8Array> | null,\n readerClone: ReadableStreamDefaultReader<Uint8Array>\n ): ReadableStream<Uint8Array> | null {\n if (!body) return null;\n\n const reader = body.getReader();\n\n return new ReadableStream({\n async pull(controller) {\n try {\n const { value, done } = await reader.read();\n if (done) {\n reader.releaseLock();\n controller.close();\n } else {\n controller.enqueue(value);\n }\n } catch (err) {\n controller.error(err);\n reader.cancel(err).catch(_ => {});\n\n try {\n reader.releaseLock();\n } catch {\n // Spec reference:\n // https://streams.spec.whatwg.org/#default-reader-release-lock\n //\n // releaseLock() only throws if called on an invalid reader\n // (i.e. reader.[[stream]] is undefined, meaning the lock is already released\n // or the reader was never associated). In normal use this cannot happen.\n // This catch is defensive only.\n }\n }\n },\n cancel(reason) {\n readerClone.cancel(reason).catch(_ => {});\n return reader.cancel(reason);\n },\n });\n }\n\n function onSuccess(\n span: api.Span,\n resolve: (value: Response | PromiseLike<Response>) => void,\n response: Response\n ): void {\n let proxiedResponse: Response | null = null;\n\n try {\n // TODO: Switch to a consumer-driven model and drop `resClone`.\n // Keeping eager consumption here to preserve current behavior and avoid breaking existing tests.\n // Context: discussion in PR #5894 → https://github.com/open-telemetry/opentelemetry-js/pull/5894\n const resClone = response.clone();\n const body = resClone.body;\n if (body) {\n const reader = body.getReader();\n const isNullBodyStatus =\n // 101 responses and protocol upgrading is handled internally by the browser\n response.status === 204 ||\n response.status === 205 ||\n response.status === 304;\n const wrappedBody = isNullBodyStatus\n ? null\n : withCancelPropagation(response.body, reader);\n\n proxiedResponse = new Response(wrappedBody, {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n });\n\n const read = (): void => {\n reader.read().then(\n ({ done }) => {\n if (done) {\n endSpanOnSuccess(span, response);\n } else {\n read();\n }\n },\n error => {\n endSpanOnError(span, error);\n }\n );\n };\n read();\n } else {\n // some older browsers don't have .body implemented\n endSpanOnSuccess(span, response);\n }\n } finally {\n resolve(proxiedResponse ?? response);\n }\n }\n\n function onError(\n span: api.Span,\n reject: (reason?: unknown) => void,\n error: FetchError\n ) {\n try {\n endSpanOnError(span, error);\n } finally {\n reject(error);\n }\n }\n\n return new Promise((resolve, reject) => {\n return api.context.with(\n api.trace.setSpan(api.context.active(), createdSpan),\n () => {\n plugin._addHeaders(options, url);\n plugin._callRequestHook(createdSpan, options);\n plugin._tasksCount++;\n\n return original\n .apply(\n self,\n options instanceof Request ? [options] : [url, options]\n )\n .then(\n onSuccess.bind(self, createdSpan, resolve),\n onError.bind(self, createdSpan, reject)\n );\n }\n );\n });\n };\n };\n }\n\n private _applyAttributesAfterFetch(\n span: api.Span,\n request: Request | RequestInit,\n result: Response | FetchError\n ) {\n const applyCustomAttributesOnSpan =\n this.getConfig().applyCustomAttributesOnSpan;\n if (applyCustomAttributesOnSpan) {\n safeExecuteInTheMiddle(\n () => applyCustomAttributesOnSpan(span, request, result),\n error => {\n if (!error) {\n return;\n }\n\n this._diag.error('applyCustomAttributesOnSpan', error);\n },\n true\n );\n }\n }\n\n private _callRequestHook(span: api.Span, request: Request | RequestInit) {\n const requestHook = this.getConfig().requestHook;\n if (requestHook) {\n safeExecuteInTheMiddle(\n () => requestHook(span, request),\n error => {\n if (!error) {\n return;\n }\n\n this._diag.error('requestHook', error);\n },\n true\n );\n }\n }\n\n /**\n * Prepares a span data - needed later for matching appropriate network\n * resources\n * @param spanUrl\n */\n private _prepareSpanData(spanUrl: string): SpanData {\n const startTime = core.hrTime();\n const entries: PerformanceResourceTiming[] = [];\n if (typeof PerformanceObserver !== 'function') {\n return { entries, startTime, spanUrl };\n }\n\n const observer = new PerformanceObserver(list => {\n const perfObsEntries = list.getEntries() as PerformanceResourceTiming[];\n perfObsEntries.forEach(entry => {\n if (entry.initiatorType === 'fetch' && entry.name === spanUrl) {\n entries.push(entry);\n }\n });\n });\n observer.observe({\n entryTypes: ['resource'],\n });\n return { entries, observer, startTime, spanUrl };\n }\n\n /**\n * implements enable function\n */\n override enable(): void {\n if (isNode) {\n // Node.js v18+ *does* have a global `fetch()`, but this package does not\n // support instrumenting it.\n this._diag.warn(\n \"this instrumentation is intended for web usage only, it does not instrument Node.js's fetch()\"\n );\n return;\n }\n if (isWrapped(fetch)) {\n this._unwrap(_globalThis, 'fetch');\n this._diag.debug('removing previous patch for constructor');\n }\n this._wrap(_globalThis, 'fetch', this._patchConstructor());\n }\n\n /**\n * implements unpatch function\n */\n override disable(): void {\n if (isNode) {\n return;\n }\n this._unwrap(_globalThis, 'fetch');\n this._usedResources = new WeakSet<PerformanceResourceTiming>();\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../src/fetch.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 */\n\nimport {\n context,\n propagation,\n SpanKind,\n SpanStatusCode,\n trace,\n} from '@opentelemetry/api';\nimport type { Attributes, HrTime, Span } from '@opentelemetry/api';\nimport {\n SemconvStability,\n semconvStabilityFromStr,\n isWrapped,\n InstrumentationBase,\n InstrumentationConfig,\n safeExecuteInTheMiddle,\n} from '@opentelemetry/instrumentation';\nimport * as core from '@opentelemetry/core';\nimport * as web from '@opentelemetry/sdk-trace-web';\nimport { AttributeNames } from './enums/AttributeNames';\nimport {\n ATTR_HTTP_STATUS_CODE,\n ATTR_HTTP_HOST,\n ATTR_HTTP_USER_AGENT,\n ATTR_HTTP_SCHEME,\n ATTR_HTTP_URL,\n ATTR_HTTP_METHOD,\n ATTR_HTTP_REQUEST_CONTENT_LENGTH_UNCOMPRESSED,\n ATTR_HTTP_REQUEST_BODY_SIZE,\n} from './semconv';\nimport {\n ATTR_ERROR_TYPE,\n ATTR_HTTP_REQUEST_METHOD,\n ATTR_HTTP_REQUEST_METHOD_ORIGINAL,\n ATTR_HTTP_RESPONSE_STATUS_CODE,\n ATTR_SERVER_ADDRESS,\n ATTR_SERVER_PORT,\n ATTR_URL_FULL,\n} from '@opentelemetry/semantic-conventions';\nimport { FetchError, FetchResponse, SpanData } from './types';\nimport {\n getFetchBodyLength,\n normalizeHttpRequestMethod,\n serverPortFromUrl,\n} from './utils';\nimport { VERSION } from './version';\n\n// how long to wait for observer to collect information about resources\n// this is needed as event \"load\" is called before observer\n// hard to say how long it should really wait, seems like 300ms is\n// safe enough\nconst OBSERVER_WAIT_TIME_MS = 300;\n\nconst hasBrowserPerformanceAPI = typeof PerformanceObserver !== 'undefined';\n\nexport interface FetchCustomAttributeFunction {\n (\n span: Span,\n request: Request | RequestInit,\n result: Response | FetchError\n ): void;\n}\n\nexport interface FetchRequestHookFunction {\n (span: Span, request: Request | RequestInit): void;\n}\n\n/**\n * FetchPlugin Config\n */\nexport interface FetchInstrumentationConfig extends InstrumentationConfig {\n // the number of timing resources is limited, after the limit\n // (chrome 250, safari 150) the information is not collected anymore\n // the only way to prevent that is to regularly clean the resources\n // whenever it is possible, this is needed only when PerformanceObserver\n // is not available\n clearTimingResources?: boolean;\n // urls which should include trace headers when origin doesn't match\n propagateTraceHeaderCorsUrls?: web.PropagateTraceHeaderCorsUrls;\n /**\n * URLs that partially match any regex in ignoreUrls will not be traced.\n * In addition, URLs that are _exact matches_ of strings in ignoreUrls will\n * also not be traced.\n */\n ignoreUrls?: Array<string | RegExp>;\n /** Function for adding custom attributes on the span */\n applyCustomAttributesOnSpan?: FetchCustomAttributeFunction;\n /** Function for adding custom attributes or headers before the request is handled */\n requestHook?: FetchRequestHookFunction;\n // Ignore adding network events as span events\n ignoreNetworkEvents?: boolean;\n /** Measure outgoing request size */\n measureRequestSize?: boolean;\n /** Select the HTTP semantic conventions version(s) used. */\n semconvStabilityOptIn?: string;\n}\n\n/**\n * This class represents a fetch plugin for auto instrumentation\n */\nexport class FetchInstrumentation extends InstrumentationBase<FetchInstrumentationConfig> {\n readonly component: string = 'fetch';\n readonly version: string = VERSION;\n moduleName = this.component;\n private _usedResources = new WeakSet<PerformanceResourceTiming>();\n private _tasksCount = 0;\n\n private _semconvStability: SemconvStability;\n\n constructor(config: FetchInstrumentationConfig = {}) {\n super('@opentelemetry/instrumentation-fetch', VERSION, config);\n this._semconvStability = semconvStabilityFromStr(\n 'http',\n config?.semconvStabilityOptIn\n );\n }\n\n init(): void {}\n\n /**\n * Add cors pre flight child span\n * @param span\n * @param corsPreFlightRequest\n */\n private _addChildSpan(\n span: Span,\n corsPreFlightRequest: PerformanceResourceTiming\n ): void {\n const childSpan = this.tracer.startSpan(\n 'CORS Preflight',\n {\n startTime: corsPreFlightRequest[web.PerformanceTimingNames.FETCH_START],\n },\n trace.setSpan(context.active(), span)\n );\n const skipOldSemconvContentLengthAttrs = !(\n this._semconvStability & SemconvStability.OLD\n );\n web.addSpanNetworkEvents(\n childSpan,\n corsPreFlightRequest,\n this.getConfig().ignoreNetworkEvents,\n undefined,\n skipOldSemconvContentLengthAttrs\n );\n childSpan.end(\n corsPreFlightRequest[web.PerformanceTimingNames.RESPONSE_END]\n );\n }\n\n /**\n * Adds more attributes to span just before ending it\n * @param span\n * @param response\n */\n private _addFinalSpanAttributes(span: Span, response: FetchResponse): void {\n const parsedUrl = web.parseUrl(response.url);\n\n if (this._semconvStability & SemconvStability.OLD) {\n span.setAttribute(ATTR_HTTP_STATUS_CODE, response.status);\n if (response.statusText != null) {\n span.setAttribute(AttributeNames.HTTP_STATUS_TEXT, response.statusText);\n }\n span.setAttribute(ATTR_HTTP_HOST, parsedUrl.host);\n span.setAttribute(ATTR_HTTP_SCHEME, parsedUrl.protocol.replace(':', ''));\n if (typeof navigator !== 'undefined') {\n span.setAttribute(ATTR_HTTP_USER_AGENT, navigator.userAgent);\n }\n }\n\n if (this._semconvStability & SemconvStability.STABLE) {\n span.setAttribute(ATTR_HTTP_RESPONSE_STATUS_CODE, response.status);\n // TODO: Set server.{address,port} at span creation for sampling decisions\n // (a \"SHOULD\" requirement in semconv).\n span.setAttribute(ATTR_SERVER_ADDRESS, parsedUrl.hostname);\n const serverPort = serverPortFromUrl(parsedUrl);\n if (serverPort) {\n span.setAttribute(ATTR_SERVER_PORT, serverPort);\n }\n }\n }\n\n /**\n * Add headers\n * @param options\n * @param spanUrl\n */\n private _addHeaders(options: Request | RequestInit, spanUrl: string): void {\n if (\n !web.shouldPropagateTraceHeaders(\n spanUrl,\n this.getConfig().propagateTraceHeaderCorsUrls\n )\n ) {\n const headers: Partial<Record<string, unknown>> = {};\n propagation.inject(context.active(), headers);\n if (Object.keys(headers).length > 0) {\n this._diag.debug('headers inject skipped due to CORS policy');\n }\n return;\n }\n\n if (options instanceof Request) {\n propagation.inject(context.active(), options.headers, {\n set: (h, k, v) => h.set(k, typeof v === 'string' ? v : String(v)),\n });\n } else if (options.headers instanceof Headers) {\n propagation.inject(context.active(), options.headers, {\n set: (h, k, v) => h.set(k, typeof v === 'string' ? v : String(v)),\n });\n } else if (options.headers instanceof Map) {\n propagation.inject(context.active(), options.headers, {\n set: (h, k, v) => h.set(k, typeof v === 'string' ? v : String(v)),\n });\n } else {\n const headers: Partial<Record<string, unknown>> = {};\n propagation.inject(context.active(), headers);\n options.headers = Object.assign({}, headers, options.headers || {});\n }\n }\n\n /**\n * Clears the resource timings and all resources assigned with spans\n * when {@link FetchPluginConfig.clearTimingResources} is\n * set to true (default false)\n * @private\n */\n private _clearResources() {\n if (this._tasksCount === 0 && this.getConfig().clearTimingResources) {\n performance.clearResourceTimings();\n this._usedResources = new WeakSet<PerformanceResourceTiming>();\n }\n }\n\n /**\n * Creates a new span\n * @param url\n * @param options\n */\n private _createSpan(\n url: string,\n options: Partial<Request | RequestInit> = {}\n ): Span | undefined {\n if (core.isUrlIgnored(url, this.getConfig().ignoreUrls)) {\n this._diag.debug('ignoring span as url matches ignored url');\n return;\n }\n\n let name = '';\n const attributes = {} as Attributes;\n if (this._semconvStability & SemconvStability.OLD) {\n const method = (options.method || 'GET').toUpperCase();\n name = `HTTP ${method}`;\n attributes[AttributeNames.COMPONENT] = this.moduleName;\n attributes[ATTR_HTTP_METHOD] = method;\n attributes[ATTR_HTTP_URL] = url;\n }\n if (this._semconvStability & SemconvStability.STABLE) {\n const origMethod = options.method;\n const normMethod = normalizeHttpRequestMethod(options.method || 'GET');\n if (!name) {\n // The \"old\" span name wins if emitting both old and stable semconv\n // ('http/dup').\n name = normMethod;\n }\n attributes[ATTR_HTTP_REQUEST_METHOD] = normMethod;\n if (normMethod !== origMethod) {\n attributes[ATTR_HTTP_REQUEST_METHOD_ORIGINAL] = origMethod;\n }\n attributes[ATTR_URL_FULL] = url;\n }\n\n return this.tracer.startSpan(name, {\n kind: SpanKind.CLIENT,\n attributes,\n });\n }\n\n /**\n * Finds appropriate resource and add network events to the span\n * @param span\n * @param resourcesObserver\n * @param endTime\n */\n private _findResourceAndAddNetworkEvents(\n span: Span,\n resourcesObserver: SpanData,\n endTime: HrTime\n ): void {\n let resources: PerformanceResourceTiming[] = resourcesObserver.entries;\n if (!resources.length) {\n if (!performance.getEntriesByType) {\n return;\n }\n // fallback - either Observer is not available or it took longer\n // then OBSERVER_WAIT_TIME_MS and observer didn't collect enough\n // information\n resources = performance.getEntriesByType(\n 'resource'\n ) as PerformanceResourceTiming[];\n }\n const resource = web.getResource(\n resourcesObserver.spanUrl,\n resourcesObserver.startTime,\n endTime,\n resources,\n this._usedResources,\n 'fetch'\n );\n\n if (resource.mainRequest) {\n const mainRequest = resource.mainRequest;\n this._markResourceAsUsed(mainRequest);\n\n const corsPreFlightRequest = resource.corsPreFlightRequest;\n if (corsPreFlightRequest) {\n this._addChildSpan(span, corsPreFlightRequest);\n this._markResourceAsUsed(corsPreFlightRequest);\n }\n const skipOldSemconvContentLengthAttrs = !(\n this._semconvStability & SemconvStability.OLD\n );\n web.addSpanNetworkEvents(\n span,\n mainRequest,\n this.getConfig().ignoreNetworkEvents,\n undefined,\n skipOldSemconvContentLengthAttrs\n );\n }\n }\n\n /**\n * Marks certain [resource]{@link PerformanceResourceTiming} when information\n * from this is used to add events to span.\n * This is done to avoid reusing the same resource again for next span\n * @param resource\n */\n private _markResourceAsUsed(resource: PerformanceResourceTiming): void {\n this._usedResources.add(resource);\n }\n\n /**\n * Finish span, add attributes, network events etc.\n * @param span\n * @param spanData\n * @param response\n */\n private _endSpan(span: Span, spanData: SpanData, response: FetchResponse) {\n const endTime = core.millisToHrTime(Date.now());\n const performanceEndTime = core.hrTime();\n this._addFinalSpanAttributes(span, response);\n\n if (this._semconvStability & SemconvStability.STABLE) {\n // https://github.com/open-telemetry/semantic-conventions/blob/main/docs/http/http-spans.md#status\n if (response.status >= 400) {\n span.setStatus({ code: SpanStatusCode.ERROR });\n span.setAttribute(ATTR_ERROR_TYPE, String(response.status));\n }\n }\n\n setTimeout(() => {\n spanData.observer?.disconnect();\n this._findResourceAndAddNetworkEvents(span, spanData, performanceEndTime);\n this._tasksCount--;\n this._clearResources();\n span.end(endTime);\n }, OBSERVER_WAIT_TIME_MS);\n }\n\n /**\n * Patches the constructor of fetch\n */\n private _patchConstructor(): (original: typeof fetch) => typeof fetch {\n return original => {\n const plugin = this;\n return function patchConstructor(\n this: typeof globalThis,\n ...args: Parameters<typeof fetch>\n ): Promise<Response> {\n const self = this;\n const url = web.parseUrl(\n args[0] instanceof Request ? args[0].url : String(args[0])\n ).href;\n\n const options = args[0] instanceof Request ? args[0] : args[1] || {};\n const createdSpan = plugin._createSpan(url, options);\n if (!createdSpan) {\n return original.apply(this, args);\n }\n const spanData = plugin._prepareSpanData(url);\n\n if (plugin.getConfig().measureRequestSize) {\n getFetchBodyLength(...args)\n .then(bodyLength => {\n if (!bodyLength) return;\n if (plugin._semconvStability & SemconvStability.OLD) {\n createdSpan.setAttribute(\n ATTR_HTTP_REQUEST_CONTENT_LENGTH_UNCOMPRESSED,\n bodyLength\n );\n }\n if (plugin._semconvStability & SemconvStability.STABLE) {\n createdSpan.setAttribute(\n ATTR_HTTP_REQUEST_BODY_SIZE,\n bodyLength\n );\n }\n })\n .catch(error => {\n plugin._diag.warn('getFetchBodyLength', error);\n });\n }\n\n function endSpanOnError(span: Span, error: FetchError) {\n plugin._applyAttributesAfterFetch(span, options, error);\n plugin._endSpan(span, spanData, {\n status: error.status || 0,\n statusText: error.message,\n url,\n });\n }\n\n function endSpanOnSuccess(span: Span, response: Response) {\n plugin._applyAttributesAfterFetch(span, options, response);\n if (response.status >= 200 && response.status < 400) {\n plugin._endSpan(span, spanData, response);\n } else {\n plugin._endSpan(span, spanData, {\n status: response.status,\n statusText: response.statusText,\n url,\n });\n }\n }\n\n function withCancelPropagation(\n body: ReadableStream<Uint8Array> | null,\n readerClone: ReadableStreamDefaultReader<Uint8Array>\n ): ReadableStream<Uint8Array> | null {\n if (!body) return null;\n\n const reader = body.getReader();\n\n return new ReadableStream({\n async pull(controller) {\n try {\n const { value, done } = await reader.read();\n if (done) {\n reader.releaseLock();\n controller.close();\n } else {\n controller.enqueue(value);\n }\n } catch (err) {\n controller.error(err);\n reader.cancel(err).catch(_ => {});\n\n try {\n reader.releaseLock();\n } catch {\n // Spec reference:\n // https://streams.spec.whatwg.org/#default-reader-release-lock\n //\n // releaseLock() only throws if called on an invalid reader\n // (i.e. reader.[[stream]] is undefined, meaning the lock is already released\n // or the reader was never associated). In normal use this cannot happen.\n // This catch is defensive only.\n }\n }\n },\n cancel(reason) {\n readerClone.cancel(reason).catch(_ => {});\n return reader.cancel(reason);\n },\n });\n }\n\n function onSuccess(\n span: Span,\n resolve: (value: Response | PromiseLike<Response>) => void,\n response: Response\n ): void {\n let proxiedResponse: Response | null = null;\n\n try {\n // TODO: Switch to a consumer-driven model and drop `resClone`.\n // Keeping eager consumption here to preserve current behavior and avoid breaking existing tests.\n // Context: discussion in PR #5894 → https://github.com/open-telemetry/opentelemetry-js/pull/5894\n const resClone = response.clone();\n const body = resClone.body;\n if (body) {\n const reader = body.getReader();\n const isNullBodyStatus =\n // 101 responses and protocol upgrading is handled internally by the browser\n response.status === 204 ||\n response.status === 205 ||\n response.status === 304;\n const wrappedBody = isNullBodyStatus\n ? null\n : withCancelPropagation(response.body, reader);\n\n proxiedResponse = new Response(wrappedBody, {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n });\n\n const read = (): void => {\n reader.read().then(\n ({ done }) => {\n if (done) {\n endSpanOnSuccess(span, response);\n } else {\n read();\n }\n },\n error => {\n endSpanOnError(span, error);\n }\n );\n };\n read();\n } else {\n // some older browsers don't have .body implemented\n endSpanOnSuccess(span, response);\n }\n } finally {\n resolve(proxiedResponse ?? response);\n }\n }\n\n function onError(\n span: Span,\n reject: (reason?: unknown) => void,\n error: FetchError\n ) {\n try {\n endSpanOnError(span, error);\n } finally {\n reject(error);\n }\n }\n\n return new Promise((resolve, reject) => {\n return context.with(\n trace.setSpan(context.active(), createdSpan),\n () => {\n plugin._addHeaders(options, url);\n plugin._callRequestHook(createdSpan, options);\n plugin._tasksCount++;\n\n return original\n .apply(\n self,\n options instanceof Request ? [options] : [url, options]\n )\n .then(\n onSuccess.bind(self, createdSpan, resolve),\n onError.bind(self, createdSpan, reject)\n );\n }\n );\n });\n };\n };\n }\n\n private _applyAttributesAfterFetch(\n span: Span,\n request: Request | RequestInit,\n result: Response | FetchError\n ) {\n const applyCustomAttributesOnSpan =\n this.getConfig().applyCustomAttributesOnSpan;\n if (applyCustomAttributesOnSpan) {\n safeExecuteInTheMiddle(\n () => applyCustomAttributesOnSpan(span, request, result),\n error => {\n if (!error) {\n return;\n }\n\n this._diag.error('applyCustomAttributesOnSpan', error);\n },\n true\n );\n }\n }\n\n private _callRequestHook(span: Span, request: Request | RequestInit) {\n const requestHook = this.getConfig().requestHook;\n if (requestHook) {\n safeExecuteInTheMiddle(\n () => requestHook(span, request),\n error => {\n if (!error) {\n return;\n }\n\n this._diag.error('requestHook', error);\n },\n true\n );\n }\n }\n\n /**\n * Prepares a span data - needed later for matching appropriate network\n * resources\n * @param spanUrl\n */\n private _prepareSpanData(spanUrl: string): SpanData {\n const startTime = core.hrTime();\n const entries: PerformanceResourceTiming[] = [];\n if (typeof PerformanceObserver !== 'function') {\n return { entries, startTime, spanUrl };\n }\n\n const observer = new PerformanceObserver(list => {\n const perfObsEntries = list.getEntries() as PerformanceResourceTiming[];\n perfObsEntries.forEach(entry => {\n if (entry.initiatorType === 'fetch' && entry.name === spanUrl) {\n entries.push(entry);\n }\n });\n });\n observer.observe({\n entryTypes: ['resource'],\n });\n return { entries, observer, startTime, spanUrl };\n }\n\n /**\n * implements enable function\n */\n override enable(): void {\n if (!hasBrowserPerformanceAPI) {\n this._diag.warn(\n 'this instrumentation is intended for web usage only, it does not instrument server-side fetch()'\n );\n return;\n }\n if (isWrapped(fetch)) {\n this._unwrap(globalThis, 'fetch');\n this._diag.debug('removing previous patch for constructor');\n }\n this._wrap(globalThis, 'fetch', this._patchConstructor());\n }\n\n /**\n * implements unpatch function\n */\n override disable(): void {\n if (!hasBrowserPerformanceAPI) {\n return;\n }\n this._unwrap(globalThis, 'fetch');\n this._usedResources = new WeakSet<PerformanceResourceTiming>();\n }\n}\n"]}
|
package/build/esm/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import type { HrTime } from '@opentelemetry/api';
|
|
2
2
|
/**
|
|
3
3
|
* Interface used to provide information to finish span on fetch response
|
|
4
4
|
*/
|
|
@@ -22,6 +22,6 @@ export interface SpanData {
|
|
|
22
22
|
entries: PerformanceResourceTiming[];
|
|
23
23
|
observer?: PerformanceObserver;
|
|
24
24
|
spanUrl: string;
|
|
25
|
-
startTime:
|
|
25
|
+
startTime: HrTime;
|
|
26
26
|
}
|
|
27
27
|
//# sourceMappingURL=types.d.ts.map
|
package/build/esm/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG","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 */\n\nimport
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG","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 */\n\nimport type { HrTime } from '@opentelemetry/api';\n\n/**\n * Interface used to provide information to finish span on fetch response\n */\nexport interface FetchResponse {\n status: number;\n statusText?: string;\n url: string;\n}\n\n/**\n * Interface used to provide information to finish span on fetch error\n */\nexport interface FetchError {\n status?: number;\n message: string;\n}\n\n/**\n * Interface used to keep information about span between creating and\n * ending span\n */\nexport interface SpanData {\n entries: PerformanceResourceTiming[];\n observer?: PerformanceObserver;\n spanUrl: string;\n startTime: HrTime;\n}\n"]}
|
package/build/esm/utils.js
CHANGED
|
@@ -15,9 +15,9 @@
|
|
|
15
15
|
*/
|
|
16
16
|
// Much of the logic here overlaps with the same utils file in opentelemetry-instrumentation-xml-http-request
|
|
17
17
|
// These may be unified in the future.
|
|
18
|
-
import
|
|
18
|
+
import { diag } from '@opentelemetry/api';
|
|
19
19
|
import { getStringListFromEnv } from '@opentelemetry/core';
|
|
20
|
-
const DIAG_LOGGER =
|
|
20
|
+
const DIAG_LOGGER = diag.createComponentLogger({
|
|
21
21
|
namespace: '@opentelemetry/opentelemetry-instrumentation-fetch/utils',
|
|
22
22
|
});
|
|
23
23
|
/**
|
|
@@ -180,6 +180,8 @@ const DEFAULT_KNOWN_METHODS = {
|
|
|
180
180
|
POST: true,
|
|
181
181
|
PUT: true,
|
|
182
182
|
TRACE: true,
|
|
183
|
+
// QUERY from https://datatracker.ietf.org/doc/draft-ietf-httpbis-safe-method-w-body/
|
|
184
|
+
QUERY: true,
|
|
183
185
|
};
|
|
184
186
|
let knownMethods;
|
|
185
187
|
function getKnownMethods() {
|
package/build/esm/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 */\n\n// Much of the logic here overlaps with the same utils file in opentelemetry-instrumentation-xml-http-request\n// These may be unified in the future.\n\nimport * as api from '@opentelemetry/api';\nimport { getStringListFromEnv } from '@opentelemetry/core';\nimport { URLLike } from '@opentelemetry/sdk-trace-web';\n\nconst DIAG_LOGGER = api.diag.createComponentLogger({\n namespace: '@opentelemetry/opentelemetry-instrumentation-fetch/utils',\n});\n\n/**\n * Helper function to determine payload content length for fetch requests\n *\n * The fetch API is kinda messy: there are a couple of ways the body can be passed in.\n *\n * In all cases, the body param can be some variation of ReadableStream,\n * and ReadableStreams can only be read once! We want to avoid consuming the body here,\n * because that would mean that the body never gets sent with the actual fetch request.\n *\n * Either the first arg is a Request object, which can be cloned\n * so we can clone that object and read the body of the clone\n * without disturbing the original argument\n * However, reading the body here can only be done async; the body() method returns a promise\n * this means this entire function has to return a promise\n *\n * OR the first arg is a url/string\n * in which case the second arg has type RequestInit\n * RequestInit is NOT cloneable, but RequestInit.body is writable\n * so we can chain it into ReadableStream.pipeThrough()\n *\n * ReadableStream.pipeThrough() lets us process a stream and returns a new stream\n * So we can measure the body length as it passes through the pie, but need to attach\n * the new stream to the original request\n * so that the browser still has access to the body.\n *\n * @param body\n * @returns promise that resolves to the content length of the body\n */\nexport function getFetchBodyLength(...args: Parameters<typeof fetch>) {\n if (args[0] instanceof URL || typeof args[0] === 'string') {\n const requestInit = args[1];\n if (!requestInit?.body) {\n return Promise.resolve();\n }\n if (requestInit.body instanceof ReadableStream) {\n const { body, length } = _getBodyNonDestructively(requestInit.body);\n requestInit.body = body;\n\n return length;\n } else {\n return Promise.resolve(getXHRBodyLength(requestInit.body));\n }\n } else {\n const info = args[0];\n if (!info?.body) {\n return Promise.resolve();\n }\n\n return info\n .clone()\n .text()\n .then(t => getByteLength(t));\n }\n}\n\nfunction _getBodyNonDestructively(body: ReadableStream) {\n // can't read a ReadableStream without destroying it\n // but we CAN pipe it through and return a new ReadableStream\n\n // some (older) platforms don't expose the pipeThrough method and in that scenario, we're out of luck;\n // there's no way to read the stream without consuming it.\n if (!body.pipeThrough) {\n DIAG_LOGGER.warn('Platform has ReadableStream but not pipeThrough!');\n return {\n body,\n length: Promise.resolve(undefined),\n };\n }\n\n let length = 0;\n let resolveLength: (l: number) => void;\n const lengthPromise = new Promise<number>(resolve => {\n resolveLength = resolve;\n });\n\n const transform = new TransformStream({\n start() {},\n async transform(chunk, controller) {\n const bytearray = (await chunk) as Uint8Array;\n length += bytearray.byteLength;\n\n controller.enqueue(chunk);\n },\n flush() {\n resolveLength(length);\n },\n });\n\n return {\n body: body.pipeThrough(transform),\n length: lengthPromise,\n };\n}\n\nfunction isDocument(value: unknown): value is Document {\n return typeof Document !== 'undefined' && value instanceof Document;\n}\n\n/**\n * Helper function to determine payload content length for XHR requests\n * @param body\n * @returns content length\n */\nexport function getXHRBodyLength(\n body: Document | XMLHttpRequestBodyInit\n): number | undefined {\n if (isDocument(body)) {\n return new XMLSerializer().serializeToString(document).length;\n }\n\n // XMLHttpRequestBodyInit expands to the following:\n if (typeof body === 'string') {\n return getByteLength(body);\n }\n\n if (body instanceof Blob) {\n return body.size;\n }\n\n if (body instanceof FormData) {\n return getFormDataSize(body);\n }\n\n if (body instanceof URLSearchParams) {\n return getByteLength(body.toString());\n }\n\n // ArrayBuffer | ArrayBufferView\n if (body.byteLength !== undefined) {\n return body.byteLength;\n }\n\n DIAG_LOGGER.warn('unknown body type');\n return undefined;\n}\n\nconst TEXT_ENCODER = new TextEncoder();\nfunction getByteLength(s: string): number {\n return TEXT_ENCODER.encode(s).byteLength;\n}\n\nfunction getFormDataSize(formData: FormData): number {\n let size = 0;\n for (const [key, value] of formData.entries()) {\n size += key.length;\n if (value instanceof Blob) {\n size += value.size;\n } else {\n size += value.length;\n }\n }\n return size;\n}\n\n/**\n * Normalize an HTTP request method string per `http.request.method` spec\n * https://github.com/open-telemetry/semantic-conventions/blob/main/docs/http/http-spans.md#http-client-span\n */\nexport function normalizeHttpRequestMethod(method: string): string {\n const knownMethods = getKnownMethods();\n const methUpper = method.toUpperCase();\n if (methUpper in knownMethods) {\n return methUpper;\n } else {\n return '_OTHER';\n }\n}\n\nconst DEFAULT_KNOWN_METHODS = {\n CONNECT: true,\n DELETE: true,\n GET: true,\n HEAD: true,\n OPTIONS: true,\n PATCH: true,\n POST: true,\n PUT: true,\n TRACE: true,\n};\nlet knownMethods: { [key: string]: boolean };\nfunction getKnownMethods() {\n if (knownMethods === undefined) {\n const cfgMethods = getStringListFromEnv(\n 'OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS'\n );\n if (cfgMethods && cfgMethods.length > 0) {\n knownMethods = {};\n cfgMethods.forEach(m => {\n knownMethods[m] = true;\n });\n } else {\n knownMethods = DEFAULT_KNOWN_METHODS;\n }\n }\n return knownMethods;\n}\n\nconst HTTP_PORT_FROM_PROTOCOL: { [key: string]: string } = {\n 'https:': '443',\n 'http:': '80',\n};\nexport function serverPortFromUrl(url: URLLike): number | undefined {\n const serverPort = Number(url.port || HTTP_PORT_FROM_PROTOCOL[url.protocol]);\n // Guard with `if (serverPort)` because `Number('') === 0`.\n if (serverPort && !isNaN(serverPort)) {\n return serverPort;\n } else {\n return undefined;\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 */\n\n// Much of the logic here overlaps with the same utils file in opentelemetry-instrumentation-xml-http-request\n// These may be unified in the future.\n\nimport { diag } from '@opentelemetry/api';\nimport { getStringListFromEnv } from '@opentelemetry/core';\nimport { URLLike } from '@opentelemetry/sdk-trace-web';\n\nconst DIAG_LOGGER = diag.createComponentLogger({\n namespace: '@opentelemetry/opentelemetry-instrumentation-fetch/utils',\n});\n\n/**\n * Helper function to determine payload content length for fetch requests\n *\n * The fetch API is kinda messy: there are a couple of ways the body can be passed in.\n *\n * In all cases, the body param can be some variation of ReadableStream,\n * and ReadableStreams can only be read once! We want to avoid consuming the body here,\n * because that would mean that the body never gets sent with the actual fetch request.\n *\n * Either the first arg is a Request object, which can be cloned\n * so we can clone that object and read the body of the clone\n * without disturbing the original argument\n * However, reading the body here can only be done async; the body() method returns a promise\n * this means this entire function has to return a promise\n *\n * OR the first arg is a url/string\n * in which case the second arg has type RequestInit\n * RequestInit is NOT cloneable, but RequestInit.body is writable\n * so we can chain it into ReadableStream.pipeThrough()\n *\n * ReadableStream.pipeThrough() lets us process a stream and returns a new stream\n * So we can measure the body length as it passes through the pie, but need to attach\n * the new stream to the original request\n * so that the browser still has access to the body.\n *\n * @param body\n * @returns promise that resolves to the content length of the body\n */\nexport function getFetchBodyLength(...args: Parameters<typeof fetch>) {\n if (args[0] instanceof URL || typeof args[0] === 'string') {\n const requestInit = args[1];\n if (!requestInit?.body) {\n return Promise.resolve();\n }\n if (requestInit.body instanceof ReadableStream) {\n const { body, length } = _getBodyNonDestructively(requestInit.body);\n requestInit.body = body;\n\n return length;\n } else {\n return Promise.resolve(getXHRBodyLength(requestInit.body));\n }\n } else {\n const info = args[0];\n if (!info?.body) {\n return Promise.resolve();\n }\n\n return info\n .clone()\n .text()\n .then(t => getByteLength(t));\n }\n}\n\nfunction _getBodyNonDestructively(body: ReadableStream) {\n // can't read a ReadableStream without destroying it\n // but we CAN pipe it through and return a new ReadableStream\n\n // some (older) platforms don't expose the pipeThrough method and in that scenario, we're out of luck;\n // there's no way to read the stream without consuming it.\n if (!body.pipeThrough) {\n DIAG_LOGGER.warn('Platform has ReadableStream but not pipeThrough!');\n return {\n body,\n length: Promise.resolve(undefined),\n };\n }\n\n let length = 0;\n let resolveLength: (l: number) => void;\n const lengthPromise = new Promise<number>(resolve => {\n resolveLength = resolve;\n });\n\n const transform = new TransformStream({\n start() {},\n async transform(chunk, controller) {\n const bytearray = (await chunk) as Uint8Array;\n length += bytearray.byteLength;\n\n controller.enqueue(chunk);\n },\n flush() {\n resolveLength(length);\n },\n });\n\n return {\n body: body.pipeThrough(transform),\n length: lengthPromise,\n };\n}\n\nfunction isDocument(value: unknown): value is Document {\n return typeof Document !== 'undefined' && value instanceof Document;\n}\n\n/**\n * Helper function to determine payload content length for XHR requests\n * @param body\n * @returns content length\n */\nexport function getXHRBodyLength(\n body: Document | XMLHttpRequestBodyInit\n): number | undefined {\n if (isDocument(body)) {\n return new XMLSerializer().serializeToString(document).length;\n }\n\n // XMLHttpRequestBodyInit expands to the following:\n if (typeof body === 'string') {\n return getByteLength(body);\n }\n\n if (body instanceof Blob) {\n return body.size;\n }\n\n if (body instanceof FormData) {\n return getFormDataSize(body);\n }\n\n if (body instanceof URLSearchParams) {\n return getByteLength(body.toString());\n }\n\n // ArrayBuffer | ArrayBufferView\n if (body.byteLength !== undefined) {\n return body.byteLength;\n }\n\n DIAG_LOGGER.warn('unknown body type');\n return undefined;\n}\n\nconst TEXT_ENCODER = new TextEncoder();\nfunction getByteLength(s: string): number {\n return TEXT_ENCODER.encode(s).byteLength;\n}\n\nfunction getFormDataSize(formData: FormData): number {\n let size = 0;\n for (const [key, value] of formData.entries()) {\n size += key.length;\n if (value instanceof Blob) {\n size += value.size;\n } else {\n size += value.length;\n }\n }\n return size;\n}\n\n/**\n * Normalize an HTTP request method string per `http.request.method` spec\n * https://github.com/open-telemetry/semantic-conventions/blob/main/docs/http/http-spans.md#http-client-span\n */\nexport function normalizeHttpRequestMethod(method: string): string {\n const knownMethods = getKnownMethods();\n const methUpper = method.toUpperCase();\n if (methUpper in knownMethods) {\n return methUpper;\n } else {\n return '_OTHER';\n }\n}\n\nconst DEFAULT_KNOWN_METHODS = {\n CONNECT: true,\n DELETE: true,\n GET: true,\n HEAD: true,\n OPTIONS: true,\n PATCH: true,\n POST: true,\n PUT: true,\n TRACE: true,\n // QUERY from https://datatracker.ietf.org/doc/draft-ietf-httpbis-safe-method-w-body/\n QUERY: true,\n};\nlet knownMethods: { [key: string]: boolean };\nfunction getKnownMethods() {\n if (knownMethods === undefined) {\n const cfgMethods = getStringListFromEnv(\n 'OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS'\n );\n if (cfgMethods && cfgMethods.length > 0) {\n knownMethods = {};\n cfgMethods.forEach(m => {\n knownMethods[m] = true;\n });\n } else {\n knownMethods = DEFAULT_KNOWN_METHODS;\n }\n }\n return knownMethods;\n}\n\nconst HTTP_PORT_FROM_PROTOCOL: { [key: string]: string } = {\n 'https:': '443',\n 'http:': '80',\n};\nexport function serverPortFromUrl(url: URLLike): number | undefined {\n const serverPort = Number(url.port || HTTP_PORT_FROM_PROTOCOL[url.protocol]);\n // Guard with `if (serverPort)` because `Number('') === 0`.\n if (serverPort && !isNaN(serverPort)) {\n return serverPort;\n } else {\n return undefined;\n }\n}\n"]}
|
package/build/esm/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "0.
|
|
1
|
+
export declare const VERSION = "0.209.0";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/build/esm/version.js
CHANGED
package/build/esm/version.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,4DAA4D;AAC5D,MAAM,CAAC,MAAM,OAAO,GAAG,SAAS,CAAC","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 */\n\n// this is autogenerated file, see scripts/version-update.js\nexport const VERSION = '0.
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,4DAA4D;AAC5D,MAAM,CAAC,MAAM,OAAO,GAAG,SAAS,CAAC","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 */\n\n// this is autogenerated file, see scripts/version-update.js\nexport const VERSION = '0.209.0';\n"]}
|
package/build/esnext/fetch.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import
|
|
1
|
+
import type { Span } from '@opentelemetry/api';
|
|
2
2
|
import { InstrumentationBase, InstrumentationConfig } from '@opentelemetry/instrumentation';
|
|
3
3
|
import * as web from '@opentelemetry/sdk-trace-web';
|
|
4
4
|
import { FetchError } from './types';
|
|
5
5
|
export interface FetchCustomAttributeFunction {
|
|
6
|
-
(span:
|
|
6
|
+
(span: Span, request: Request | RequestInit, result: Response | FetchError): void;
|
|
7
7
|
}
|
|
8
8
|
export interface FetchRequestHookFunction {
|
|
9
|
-
(span:
|
|
9
|
+
(span: Span, request: Request | RequestInit): void;
|
|
10
10
|
}
|
|
11
11
|
/**
|
|
12
12
|
* FetchPlugin Config
|