@opentelemetry/instrumentation-fetch 0.54.1 → 0.55.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
@@ -26,9 +26,9 @@ import { FetchInstrumentation } from '@opentelemetry/instrumentation-fetch';
26
26
  import { ZoneContextManager } from '@opentelemetry/context-zone';
27
27
  import { registerInstrumentations } from '@opentelemetry/instrumentation';
28
28
 
29
- const provider = new WebTracerProvider();
30
-
31
- provider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter()));
29
+ const provider = new WebTracerProvider({
30
+ spanProcessors: [new SimpleSpanProcessor(new ConsoleSpanExporter())]
31
+ });
32
32
 
33
33
  provider.register({
34
34
  contextManager: new ZoneContextManager(),
@@ -40,15 +40,14 @@ registerInstrumentations({
40
40
 
41
41
  // or plugin can be also initialised separately and then set the tracer provider or meter provider
42
42
  const fetchInstrumentation = new FetchInstrumentation();
43
- const provider = new WebTracerProvider();
43
+ const provider = new WebTracerProvider({
44
+ spanProcessors: [new SimpleSpanProcessor(new ConsoleSpanExporter())]
45
+ });
44
46
  provider.register({
45
47
  contextManager: new ZoneContextManager(),
46
48
  });
47
49
  fetchInstrumentation.setTracerProvider(provider);
48
50
 
49
- provider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter()));
50
-
51
-
52
51
  // and some test
53
52
 
54
53
  fetch('http://localhost:8090/fetch.js');
@@ -69,8 +68,9 @@ Fetch instrumentation plugin has few options available to choose from. You can s
69
68
 
70
69
  | Options | Type | Description |
71
70
  |--------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------|-----------------------------------------------------------------------------------------|
72
- | [`applyCustomAttributesOnSpan`](https://github.com/open-telemetry/opentelemetry-js/blob/main/experimental/packages/opentelemetry-instrumentation-fetch/src/fetch.ts#L64) | `HttpCustomAttributeFunction` | Function for adding custom attributes |
73
- | [`ignoreNetworkEvents`](https://github.com/open-telemetry/opentelemetry-js/blob/main/experimental/packages/opentelemetry-instrumentation-fetch/src/fetch.ts#L67) | `boolean` | Disable network events being added as span events (network events are added by default) |
71
+ | [`applyCustomAttributesOnSpan`](https://github.com/open-telemetry/opentelemetry-js/blob/main/experimental/packages/opentelemetry-instrumentation-fetch/src/fetch.ts#L75) | `HttpCustomAttributeFunction` | Function for adding custom attributes |
72
+ | [`ignoreNetworkEvents`](https://github.com/open-telemetry/opentelemetry-js/blob/main/experimental/packages/opentelemetry-instrumentation-fetch/src/fetch.ts#L77) | `boolean` | Disable network events being added as span events (network events are added by default) |
73
+ | [`measureRequestSize`](https://github.com/open-telemetry/opentelemetry-js/blob/main/experimental/packages/opentelemetry-instrumentation-fetch/src/fetch.ts#L79) | `boolean` | Measure outgoing request length (outgoing request length is not measured by default) |
74
74
 
75
75
  ## Semantic Conventions
76
76
 
@@ -80,12 +80,13 @@ Attributes collected:
80
80
 
81
81
  | Attribute | Short Description |
82
82
  | ------------------------------------------- | ------------------------------------------------------------------------------ |
83
- | `http.status_code` | HTTP response status code |
83
+ | `http.status_code` | HTTP response status code |
84
84
  | `http.host` | The value of the HTTP host header |
85
85
  | `http.user_agent` | Value of the HTTP User-Agent header sent by the client |
86
86
  | `http.scheme` | The URI scheme identifying the used protocol |
87
87
  | `http.url` | Full HTTP request URL |
88
88
  | `http.method` | HTTP request method |
89
+ | `http.request_content_length_uncompressed` | Uncompressed size of the request body, if any body exists |
89
90
 
90
91
  ## Useful links
91
92
 
@@ -20,6 +20,8 @@ export interface FetchInstrumentationConfig extends InstrumentationConfig {
20
20
  /** Function for adding custom attributes on the span */
21
21
  applyCustomAttributesOnSpan?: FetchCustomAttributeFunction;
22
22
  ignoreNetworkEvents?: boolean;
23
+ /** Measure outgoing request size */
24
+ measureRequestSize?: boolean;
23
25
  }
24
26
  /**
25
27
  * This class represents a fetch plugin for auto instrumentation
@@ -28,13 +28,39 @@ var __extends = (this && this.__extends) || (function () {
28
28
  d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
29
29
  };
30
30
  })();
31
+ var __read = (this && this.__read) || function (o, n) {
32
+ var m = typeof Symbol === "function" && o[Symbol.iterator];
33
+ if (!m) return o;
34
+ var i = m.call(o), r, ar = [], e;
35
+ try {
36
+ while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
37
+ }
38
+ catch (error) { e = { error: error }; }
39
+ finally {
40
+ try {
41
+ if (r && !r.done && (m = i["return"])) m.call(i);
42
+ }
43
+ finally { if (e) throw e.error; }
44
+ }
45
+ return ar;
46
+ };
47
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
48
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
49
+ if (ar || !(i in from)) {
50
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
51
+ ar[i] = from[i];
52
+ }
53
+ }
54
+ return to.concat(ar || Array.prototype.slice.call(from));
55
+ };
31
56
  var _a;
32
57
  import * as api from '@opentelemetry/api';
33
58
  import { isWrapped, InstrumentationBase, safeExecuteInTheMiddle, } from '@opentelemetry/instrumentation';
34
59
  import * as core from '@opentelemetry/core';
35
60
  import * as web from '@opentelemetry/sdk-trace-web';
36
61
  import { AttributeNames } from './enums/AttributeNames';
37
- import { SEMATTRS_HTTP_STATUS_CODE, SEMATTRS_HTTP_HOST, SEMATTRS_HTTP_USER_AGENT, SEMATTRS_HTTP_SCHEME, SEMATTRS_HTTP_URL, SEMATTRS_HTTP_METHOD, } from '@opentelemetry/semantic-conventions';
62
+ import { SEMATTRS_HTTP_STATUS_CODE, SEMATTRS_HTTP_HOST, SEMATTRS_HTTP_USER_AGENT, SEMATTRS_HTTP_SCHEME, SEMATTRS_HTTP_URL, SEMATTRS_HTTP_METHOD, SEMATTRS_HTTP_REQUEST_CONTENT_LENGTH_UNCOMPRESSED, } from '@opentelemetry/semantic-conventions';
63
+ import { getFetchBodyLength } from './utils';
38
64
  import { VERSION } from './version';
39
65
  import { _globalThis } from '@opentelemetry/core';
40
66
  // how long to wait for observer to collect information about resources
@@ -240,6 +266,16 @@ var FetchInstrumentation = /** @class */ (function (_super) {
240
266
  return original.apply(this, args);
241
267
  }
242
268
  var spanData = plugin._prepareSpanData(url);
269
+ if (plugin.getConfig().measureRequestSize) {
270
+ getFetchBodyLength.apply(void 0, __spreadArray([], __read(args), false)).then(function (length) {
271
+ if (!length)
272
+ return;
273
+ createdSpan.setAttribute(SEMATTRS_HTTP_REQUEST_CONTENT_LENGTH_UNCOMPRESSED, length);
274
+ })
275
+ .catch(function (error) {
276
+ plugin._diag.warn('getFetchBodyLength', error);
277
+ });
278
+ }
243
279
  function endSpanOnError(span, error) {
244
280
  plugin._applyAttributesAfterFetch(span, options, error);
245
281
  plugin._endSpan(span, spanData, {
@@ -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 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 SEMATTRS_HTTP_STATUS_CODE,\n SEMATTRS_HTTP_HOST,\n SEMATTRS_HTTP_USER_AGENT,\n SEMATTRS_HTTP_SCHEME,\n SEMATTRS_HTTP_URL,\n SEMATTRS_HTTP_METHOD,\n} from '@opentelemetry/semantic-conventions';\nimport { FetchError, FetchResponse, SpanData } from './types';\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\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 // Ignore adding network events as span events\n ignoreNetworkEvents?: boolean;\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 constructor(config: FetchInstrumentationConfig = {}) {\n super('@opentelemetry/instrumentation-fetch', VERSION, config);\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 if (!this.getConfig().ignoreNetworkEvents) {\n web.addSpanNetworkEvents(childSpan, corsPreFlightRequest);\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 span.setAttribute(SEMATTRS_HTTP_STATUS_CODE, response.status);\n if (response.statusText != null) {\n span.setAttribute(AttributeNames.HTTP_STATUS_TEXT, response.statusText);\n }\n span.setAttribute(SEMATTRS_HTTP_HOST, parsedUrl.host);\n span.setAttribute(\n SEMATTRS_HTTP_SCHEME,\n parsedUrl.protocol.replace(':', '')\n );\n if (typeof navigator !== 'undefined') {\n span.setAttribute(SEMATTRS_HTTP_USER_AGENT, navigator.userAgent);\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 const method = (options.method || 'GET').toUpperCase();\n const spanName = `HTTP ${method}`;\n return this.tracer.startSpan(spanName, {\n kind: api.SpanKind.CLIENT,\n attributes: {\n [AttributeNames.COMPONENT]: this.moduleName,\n [SEMATTRS_HTTP_METHOD]: method,\n [SEMATTRS_HTTP_URL]: url,\n },\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 if (!this.getConfig().ignoreNetworkEvents) {\n web.addSpanNetworkEvents(span, mainRequest);\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 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 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 onSuccess(\n span: api.Span,\n resolve: (value: Response | PromiseLike<Response>) => void,\n response: Response\n ): void {\n try {\n const resClone = response.clone();\n const resClone4Hook = response.clone();\n const body = resClone.body;\n if (body) {\n const reader = body.getReader();\n const read = (): void => {\n reader.read().then(\n ({ done }) => {\n if (done) {\n endSpanOnSuccess(span, resClone4Hook);\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(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._tasksCount++;\n // TypeScript complains about arrow function captured a this typed as globalThis\n // ts(7041)\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 /**\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 * as api from '@opentelemetry/api';\nimport {\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 SEMATTRS_HTTP_STATUS_CODE,\n SEMATTRS_HTTP_HOST,\n SEMATTRS_HTTP_USER_AGENT,\n SEMATTRS_HTTP_SCHEME,\n SEMATTRS_HTTP_URL,\n SEMATTRS_HTTP_METHOD,\n SEMATTRS_HTTP_REQUEST_CONTENT_LENGTH_UNCOMPRESSED,\n} from '@opentelemetry/semantic-conventions';\nimport { FetchError, FetchResponse, SpanData } from './types';\nimport { getFetchBodyLength } 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\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 // Ignore adding network events as span events\n ignoreNetworkEvents?: boolean;\n /** Measure outgoing request size */\n measureRequestSize?: boolean;\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 constructor(config: FetchInstrumentationConfig = {}) {\n super('@opentelemetry/instrumentation-fetch', VERSION, config);\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 if (!this.getConfig().ignoreNetworkEvents) {\n web.addSpanNetworkEvents(childSpan, corsPreFlightRequest);\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 span.setAttribute(SEMATTRS_HTTP_STATUS_CODE, response.status);\n if (response.statusText != null) {\n span.setAttribute(AttributeNames.HTTP_STATUS_TEXT, response.statusText);\n }\n span.setAttribute(SEMATTRS_HTTP_HOST, parsedUrl.host);\n span.setAttribute(\n SEMATTRS_HTTP_SCHEME,\n parsedUrl.protocol.replace(':', '')\n );\n if (typeof navigator !== 'undefined') {\n span.setAttribute(SEMATTRS_HTTP_USER_AGENT, navigator.userAgent);\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 const method = (options.method || 'GET').toUpperCase();\n const spanName = `HTTP ${method}`;\n return this.tracer.startSpan(spanName, {\n kind: api.SpanKind.CLIENT,\n attributes: {\n [AttributeNames.COMPONENT]: this.moduleName,\n [SEMATTRS_HTTP_METHOD]: method,\n [SEMATTRS_HTTP_URL]: url,\n },\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 if (!this.getConfig().ignoreNetworkEvents) {\n web.addSpanNetworkEvents(span, mainRequest);\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 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(length => {\n if (!length) return;\n\n createdSpan.setAttribute(\n SEMATTRS_HTTP_REQUEST_CONTENT_LENGTH_UNCOMPRESSED,\n length\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 onSuccess(\n span: api.Span,\n resolve: (value: Response | PromiseLike<Response>) => void,\n response: Response\n ): void {\n try {\n const resClone = response.clone();\n const resClone4Hook = response.clone();\n const body = resClone.body;\n if (body) {\n const reader = body.getReader();\n const read = (): void => {\n reader.read().then(\n ({ done }) => {\n if (done) {\n endSpanOnSuccess(span, resClone4Hook);\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(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._tasksCount++;\n // TypeScript complains about arrow function captured a this typed as globalThis\n // ts(7041)\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 /**\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"]}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Helper function to determine payload content length for fetch requests
3
+ *
4
+ * The fetch API is kinda messy: there are a couple of ways the body can be passed in.
5
+ *
6
+ * In all cases, the body param can be some variation of ReadableStream,
7
+ * and ReadableStreams can only be read once! We want to avoid consuming the body here,
8
+ * because that would mean that the body never gets sent with the actual fetch request.
9
+ *
10
+ * Either the first arg is a Request object, which can be cloned
11
+ * so we can clone that object and read the body of the clone
12
+ * without disturbing the original argument
13
+ * However, reading the body here can only be done async; the body() method returns a promise
14
+ * this means this entire function has to return a promise
15
+ *
16
+ * OR the first arg is a url/string
17
+ * in which case the second arg has type RequestInit
18
+ * RequestInit is NOT cloneable, but RequestInit.body is writable
19
+ * so we can chain it into ReadableStream.pipeThrough()
20
+ *
21
+ * ReadableStream.pipeThrough() lets us process a stream and returns a new stream
22
+ * So we can measure the body length as it passes through the pie, but need to attach
23
+ * the new stream to the original request
24
+ * so that the browser still has access to the body.
25
+ *
26
+ * @param body
27
+ * @returns promise that resolves to the content length of the body
28
+ */
29
+ export declare function getFetchBodyLength(...args: Parameters<typeof fetch>): Promise<void> | Promise<number | undefined>;
30
+ /**
31
+ * Helper function to determine payload content length for XHR requests
32
+ * @param body
33
+ * @returns content length
34
+ */
35
+ export declare function getXHRBodyLength(body: Document | XMLHttpRequestBodyInit): number | undefined;
36
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1,243 @@
1
+ /*
2
+ * Copyright The OpenTelemetry Authors
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * https://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
17
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
18
+ return new (P || (P = Promise))(function (resolve, reject) {
19
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
20
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
21
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
22
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
23
+ });
24
+ };
25
+ var __generator = (this && this.__generator) || function (thisArg, body) {
26
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
27
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
28
+ function verb(n) { return function (v) { return step([n, v]); }; }
29
+ function step(op) {
30
+ if (f) throw new TypeError("Generator is already executing.");
31
+ while (_) try {
32
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
33
+ if (y = 0, t) op = [op[0] & 2, t.value];
34
+ switch (op[0]) {
35
+ case 0: case 1: t = op; break;
36
+ case 4: _.label++; return { value: op[1], done: false };
37
+ case 5: _.label++; y = op[1]; op = [0]; continue;
38
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
39
+ default:
40
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
41
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
42
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
43
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
44
+ if (t[2]) _.ops.pop();
45
+ _.trys.pop(); continue;
46
+ }
47
+ op = body.call(thisArg, _);
48
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
49
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
50
+ }
51
+ };
52
+ var __values = (this && this.__values) || function(o) {
53
+ var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
54
+ if (m) return m.call(o);
55
+ if (o && typeof o.length === "number") return {
56
+ next: function () {
57
+ if (o && i >= o.length) o = void 0;
58
+ return { value: o && o[i++], done: !o };
59
+ }
60
+ };
61
+ throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
62
+ };
63
+ var __read = (this && this.__read) || function (o, n) {
64
+ var m = typeof Symbol === "function" && o[Symbol.iterator];
65
+ if (!m) return o;
66
+ var i = m.call(o), r, ar = [], e;
67
+ try {
68
+ while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
69
+ }
70
+ catch (error) { e = { error: error }; }
71
+ finally {
72
+ try {
73
+ if (r && !r.done && (m = i["return"])) m.call(i);
74
+ }
75
+ finally { if (e) throw e.error; }
76
+ }
77
+ return ar;
78
+ };
79
+ // Much of the logic here overlaps with the same utils file in opentelemetry-instrumentation-xml-http-request
80
+ // These may be unified in the future.
81
+ import * as api from '@opentelemetry/api';
82
+ var DIAG_LOGGER = api.diag.createComponentLogger({
83
+ namespace: '@opentelemetry/opentelemetry-instrumentation-fetch/utils',
84
+ });
85
+ /**
86
+ * Helper function to determine payload content length for fetch requests
87
+ *
88
+ * The fetch API is kinda messy: there are a couple of ways the body can be passed in.
89
+ *
90
+ * In all cases, the body param can be some variation of ReadableStream,
91
+ * and ReadableStreams can only be read once! We want to avoid consuming the body here,
92
+ * because that would mean that the body never gets sent with the actual fetch request.
93
+ *
94
+ * Either the first arg is a Request object, which can be cloned
95
+ * so we can clone that object and read the body of the clone
96
+ * without disturbing the original argument
97
+ * However, reading the body here can only be done async; the body() method returns a promise
98
+ * this means this entire function has to return a promise
99
+ *
100
+ * OR the first arg is a url/string
101
+ * in which case the second arg has type RequestInit
102
+ * RequestInit is NOT cloneable, but RequestInit.body is writable
103
+ * so we can chain it into ReadableStream.pipeThrough()
104
+ *
105
+ * ReadableStream.pipeThrough() lets us process a stream and returns a new stream
106
+ * So we can measure the body length as it passes through the pie, but need to attach
107
+ * the new stream to the original request
108
+ * so that the browser still has access to the body.
109
+ *
110
+ * @param body
111
+ * @returns promise that resolves to the content length of the body
112
+ */
113
+ export function getFetchBodyLength() {
114
+ var args = [];
115
+ for (var _i = 0; _i < arguments.length; _i++) {
116
+ args[_i] = arguments[_i];
117
+ }
118
+ if (args[0] instanceof URL || typeof args[0] === 'string') {
119
+ var requestInit = args[1];
120
+ if (!(requestInit === null || requestInit === void 0 ? void 0 : requestInit.body)) {
121
+ return Promise.resolve();
122
+ }
123
+ if (requestInit.body instanceof ReadableStream) {
124
+ var _a = _getBodyNonDestructively(requestInit.body), body = _a.body, length_1 = _a.length;
125
+ requestInit.body = body;
126
+ return length_1;
127
+ }
128
+ else {
129
+ return Promise.resolve(getXHRBodyLength(requestInit.body));
130
+ }
131
+ }
132
+ else {
133
+ var info = args[0];
134
+ if (!(info === null || info === void 0 ? void 0 : info.body)) {
135
+ return Promise.resolve();
136
+ }
137
+ return info
138
+ .clone()
139
+ .text()
140
+ .then(function (t) { return getByteLength(t); });
141
+ }
142
+ }
143
+ function _getBodyNonDestructively(body) {
144
+ // can't read a ReadableStream without destroying it
145
+ // but we CAN pipe it through and return a new ReadableStream
146
+ // some (older) platforms don't expose the pipeThrough method and in that scenario, we're out of luck;
147
+ // there's no way to read the stream without consuming it.
148
+ if (!body.pipeThrough) {
149
+ DIAG_LOGGER.warn('Platform has ReadableStream but not pipeThrough!');
150
+ return {
151
+ body: body,
152
+ length: Promise.resolve(undefined),
153
+ };
154
+ }
155
+ var length = 0;
156
+ var resolveLength;
157
+ var lengthPromise = new Promise(function (resolve) {
158
+ resolveLength = resolve;
159
+ });
160
+ var transform = new TransformStream({
161
+ start: function () { },
162
+ transform: function (chunk, controller) {
163
+ return __awaiter(this, void 0, void 0, function () {
164
+ var bytearray;
165
+ return __generator(this, function (_a) {
166
+ switch (_a.label) {
167
+ case 0: return [4 /*yield*/, chunk];
168
+ case 1:
169
+ bytearray = (_a.sent());
170
+ length += bytearray.byteLength;
171
+ controller.enqueue(chunk);
172
+ return [2 /*return*/];
173
+ }
174
+ });
175
+ });
176
+ },
177
+ flush: function () {
178
+ resolveLength(length);
179
+ },
180
+ });
181
+ return {
182
+ body: body.pipeThrough(transform),
183
+ length: lengthPromise,
184
+ };
185
+ }
186
+ /**
187
+ * Helper function to determine payload content length for XHR requests
188
+ * @param body
189
+ * @returns content length
190
+ */
191
+ export function getXHRBodyLength(body) {
192
+ if (typeof Document !== 'undefined' && body instanceof Document) {
193
+ return new XMLSerializer().serializeToString(document).length;
194
+ }
195
+ // XMLHttpRequestBodyInit expands to the following:
196
+ if (body instanceof Blob) {
197
+ return body.size;
198
+ }
199
+ // ArrayBuffer | ArrayBufferView
200
+ if (body.byteLength !== undefined) {
201
+ return body.byteLength;
202
+ }
203
+ if (body instanceof FormData) {
204
+ return getFormDataSize(body);
205
+ }
206
+ if (body instanceof URLSearchParams) {
207
+ return getByteLength(body.toString());
208
+ }
209
+ if (typeof body === 'string') {
210
+ return getByteLength(body);
211
+ }
212
+ DIAG_LOGGER.warn('unknown body type');
213
+ return undefined;
214
+ }
215
+ var TEXT_ENCODER = new TextEncoder();
216
+ function getByteLength(s) {
217
+ return TEXT_ENCODER.encode(s).byteLength;
218
+ }
219
+ function getFormDataSize(formData) {
220
+ var e_1, _a;
221
+ var size = 0;
222
+ try {
223
+ for (var _b = __values(formData.entries()), _c = _b.next(); !_c.done; _c = _b.next()) {
224
+ var _d = __read(_c.value, 2), key = _d[0], value = _d[1];
225
+ size += key.length;
226
+ if (value instanceof Blob) {
227
+ size += value.size;
228
+ }
229
+ else {
230
+ size += value.length;
231
+ }
232
+ }
233
+ }
234
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
235
+ finally {
236
+ try {
237
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
238
+ }
239
+ finally { if (e_1) throw e_1.error; }
240
+ }
241
+ return size;
242
+ }
243
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +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';\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\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 (typeof Document !== 'undefined' && body instanceof Document) {\n return new XMLSerializer().serializeToString(document).length;\n }\n // XMLHttpRequestBodyInit expands to the following:\n if (body instanceof Blob) {\n return body.size;\n }\n\n // ArrayBuffer | ArrayBufferView\n if ((body as any).byteLength !== undefined) {\n return (body as any).byteLength as number;\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 if (typeof body === 'string') {\n return getByteLength(body);\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"]}
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "0.54.1";
1
+ export declare const VERSION = "0.55.0";
2
2
  //# sourceMappingURL=version.d.ts.map
@@ -14,5 +14,5 @@
14
14
  * limitations under the License.
15
15
  */
16
16
  // this is autogenerated file, see scripts/version-update.js
17
- export var VERSION = '0.54.1';
17
+ export var VERSION = '0.55.0';
18
18
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,4DAA4D;AAC5D,MAAM,CAAC,IAAM,OAAO,GAAG,QAAQ,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.54.1';\n"]}
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,4DAA4D;AAC5D,MAAM,CAAC,IAAM,OAAO,GAAG,QAAQ,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.55.0';\n"]}
@@ -20,6 +20,8 @@ export interface FetchInstrumentationConfig extends InstrumentationConfig {
20
20
  /** Function for adding custom attributes on the span */
21
21
  applyCustomAttributesOnSpan?: FetchCustomAttributeFunction;
22
22
  ignoreNetworkEvents?: boolean;
23
+ /** Measure outgoing request size */
24
+ measureRequestSize?: boolean;
23
25
  }
24
26
  /**
25
27
  * This class represents a fetch plugin for auto instrumentation
@@ -19,7 +19,8 @@ import { isWrapped, InstrumentationBase, safeExecuteInTheMiddle, } from '@opente
19
19
  import * as core from '@opentelemetry/core';
20
20
  import * as web from '@opentelemetry/sdk-trace-web';
21
21
  import { AttributeNames } from './enums/AttributeNames';
22
- import { SEMATTRS_HTTP_STATUS_CODE, SEMATTRS_HTTP_HOST, SEMATTRS_HTTP_USER_AGENT, SEMATTRS_HTTP_SCHEME, SEMATTRS_HTTP_URL, SEMATTRS_HTTP_METHOD, } from '@opentelemetry/semantic-conventions';
22
+ import { SEMATTRS_HTTP_STATUS_CODE, SEMATTRS_HTTP_HOST, SEMATTRS_HTTP_USER_AGENT, SEMATTRS_HTTP_SCHEME, SEMATTRS_HTTP_URL, SEMATTRS_HTTP_METHOD, SEMATTRS_HTTP_REQUEST_CONTENT_LENGTH_UNCOMPRESSED, } from '@opentelemetry/semantic-conventions';
23
+ import { getFetchBodyLength } from './utils';
23
24
  import { VERSION } from './version';
24
25
  import { _globalThis } from '@opentelemetry/core';
25
26
  // how long to wait for observer to collect information about resources
@@ -214,6 +215,17 @@ export class FetchInstrumentation extends InstrumentationBase {
214
215
  return original.apply(this, args);
215
216
  }
216
217
  const spanData = plugin._prepareSpanData(url);
218
+ if (plugin.getConfig().measureRequestSize) {
219
+ getFetchBodyLength(...args)
220
+ .then(length => {
221
+ if (!length)
222
+ return;
223
+ createdSpan.setAttribute(SEMATTRS_HTTP_REQUEST_CONTENT_LENGTH_UNCOMPRESSED, length);
224
+ })
225
+ .catch(error => {
226
+ plugin._diag.warn('getFetchBodyLength', error);
227
+ });
228
+ }
217
229
  function endSpanOnError(span, error) {
218
230
  plugin._applyAttributesAfterFetch(span, options, error);
219
231
  plugin._endSpan(span, spanData, {