diff --git a/CHANGELOG.md b/CHANGELOG.md index a018b9bf3e..2991926fa6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,8 @@ All notable changes to this project will be documented in this file. ### :bug: (Bug Fix) +* fix(sdk-web): parse url with relative url string [#2972](https://github.com/open-telemetry/opentelemetry-js/pull/2972) @legendecas + ### :books: (Refine Doc) ### :house: (Internal) diff --git a/experimental/packages/opentelemetry-instrumentation-fetch/src/fetch.ts b/experimental/packages/opentelemetry-instrumentation-fetch/src/fetch.ts index 8c02cc1ede..ba4a2f422b 100644 --- a/experimental/packages/opentelemetry-instrumentation-fetch/src/fetch.ts +++ b/experimental/packages/opentelemetry-instrumentation-fetch/src/fetch.ts @@ -29,12 +29,6 @@ import { FetchError, FetchResponse, SpanData } from './types'; import { VERSION } from './version'; import { _globalThis } from '@opentelemetry/core'; -function parseUrl(url: string): web.URLLike { - const element = document.createElement('a'); - element.href = url; - return element; -} - // how long to wait for observer to collect information about resources // this is needed as event "load" is called before observer // hard to say how long it should really wait, seems like 300ms is @@ -126,7 +120,7 @@ export class FetchInstrumentation extends InstrumentationBase> span: api.Span, response: FetchResponse ): void { - const parsedUrl = parseUrl(response.url); + const parsedUrl = web.parseUrl(response.url); span.setAttribute(SemanticAttributes.HTTP_STATUS_CODE, response.status); if (response.statusText != null) { span.setAttribute(AttributeNames.HTTP_STATUS_TEXT, response.statusText); @@ -301,7 +295,7 @@ export class FetchInstrumentation extends InstrumentationBase> ...args: Parameters ): Promise { const self = this; - const url = parseUrl(args[0] instanceof Request ? args[0].url : args[0]).href; + const url = web.parseUrl(args[0] instanceof Request ? args[0].url : args[0]).href; const options = args[0] instanceof Request ? args[0] : args[1] || {}; const createdSpan = plugin._createSpan(url, options); @@ -437,17 +431,16 @@ export class FetchInstrumentation extends InstrumentationBase> private _prepareSpanData(spanUrl: string): SpanData { const startTime = core.hrTime(); const entries: PerformanceResourceTiming[] = []; - if (PerformanceObserver == null) { + if (typeof PerformanceObserver !== 'function') { return { entries, startTime, spanUrl }; } - const observer: PerformanceObserver = new PerformanceObserver(list => { + const observer = new PerformanceObserver(list => { const perfObsEntries = list.getEntries() as PerformanceResourceTiming[]; - const parsedUrl = parseUrl(spanUrl); perfObsEntries.forEach(entry => { if ( entry.initiatorType === 'fetch' && - entry.name === parsedUrl.href + entry.name === spanUrl ) { entries.push(entry); } diff --git a/experimental/packages/opentelemetry-instrumentation-xml-http-request/src/xhr.ts b/experimental/packages/opentelemetry-instrumentation-xml-http-request/src/xhr.ts index 011dcfe8d1..062d6fde4a 100644 --- a/experimental/packages/opentelemetry-instrumentation-xml-http-request/src/xhr.ts +++ b/experimental/packages/opentelemetry-instrumentation-xml-http-request/src/xhr.ts @@ -28,7 +28,7 @@ import { getResource, PerformanceTimingNames as PTN, shouldPropagateTraceHeaders, - URLLike + parseUrl, } from '@opentelemetry/sdk-trace-web'; import { EventNames } from './enums/EventNames'; import { @@ -40,12 +40,6 @@ import { import { VERSION } from './version'; import { AttributeNames } from './enums/AttributeNames'; -function parseUrl(url: string): URLLike { - const element = document.createElement('a'); - element.href = url; - return element; -} - // how long to wait for observer to collect information about resources // this is needed as event "load" is called before observer // hard to say how long it should really wait, seems like 300ms is @@ -215,8 +209,8 @@ export class XMLHttpRequestInstrumentation extends InstrumentationBase { assert.strictEqual(typeof url[field], 'string'); }); }); + + it('should parse relative url', () => { + const url = parseUrl('/foo'); + urlFields.forEach(field => { + assert.strictEqual(typeof url[field], 'string'); + }); + }); }); describe('normalizeUrl', () => { @@ -497,5 +504,11 @@ describe('utils', () => { const url = normalizeUrl('https://opentelemetry.io/你好'); assert.strictEqual(url, 'https://opentelemetry.io/%E4%BD%A0%E5%A5%BD'); }); + + it('should normalize relative url', () => { + const url = normalizeUrl('/你好'); + const urlObj = new URL(url); + assert.strictEqual(urlObj.pathname, '/%E4%BD%A0%E5%A5%BD'); + }); }); });