Skip to content

Commit 610808d

Browse files
fix(sdk-web): parse url with relative url string (#2972)
Co-authored-by: Valentin Marchaud <[email protected]>
1 parent 69cced2 commit 610808d

File tree

6 files changed

+25
-29
lines changed

6 files changed

+25
-29
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ All notable changes to this project will be documented in this file.
1818

1919
### :bug: (Bug Fix)
2020

21+
* fix(sdk-web): parse url with relative url string [#2972](https://github.com/open-telemetry/opentelemetry-js/pull/2972) @legendecas
22+
2123
### :books: (Refine Doc)
2224

2325
### :house: (Internal)

experimental/packages/opentelemetry-instrumentation-fetch/src/fetch.ts

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,6 @@ import { FetchError, FetchResponse, SpanData } from './types';
2929
import { VERSION } from './version';
3030
import { _globalThis } from '@opentelemetry/core';
3131

32-
function parseUrl(url: string): web.URLLike {
33-
const element = document.createElement('a');
34-
element.href = url;
35-
return element;
36-
}
37-
3832
// how long to wait for observer to collect information about resources
3933
// this is needed as event "load" is called before observer
4034
// hard to say how long it should really wait, seems like 300ms is
@@ -126,7 +120,7 @@ export class FetchInstrumentation extends InstrumentationBase<Promise<Response>>
126120
span: api.Span,
127121
response: FetchResponse
128122
): void {
129-
const parsedUrl = parseUrl(response.url);
123+
const parsedUrl = web.parseUrl(response.url);
130124
span.setAttribute(SemanticAttributes.HTTP_STATUS_CODE, response.status);
131125
if (response.statusText != null) {
132126
span.setAttribute(AttributeNames.HTTP_STATUS_TEXT, response.statusText);
@@ -301,7 +295,7 @@ export class FetchInstrumentation extends InstrumentationBase<Promise<Response>>
301295
...args: Parameters<typeof fetch>
302296
): Promise<Response> {
303297
const self = this;
304-
const url = parseUrl(args[0] instanceof Request ? args[0].url : args[0]).href;
298+
const url = web.parseUrl(args[0] instanceof Request ? args[0].url : args[0]).href;
305299

306300
const options = args[0] instanceof Request ? args[0] : args[1] || {};
307301
const createdSpan = plugin._createSpan(url, options);
@@ -437,17 +431,16 @@ export class FetchInstrumentation extends InstrumentationBase<Promise<Response>>
437431
private _prepareSpanData(spanUrl: string): SpanData {
438432
const startTime = core.hrTime();
439433
const entries: PerformanceResourceTiming[] = [];
440-
if (PerformanceObserver == null) {
434+
if (typeof PerformanceObserver !== 'function') {
441435
return { entries, startTime, spanUrl };
442436
}
443437

444-
const observer: PerformanceObserver = new PerformanceObserver(list => {
438+
const observer = new PerformanceObserver(list => {
445439
const perfObsEntries = list.getEntries() as PerformanceResourceTiming[];
446-
const parsedUrl = parseUrl(spanUrl);
447440
perfObsEntries.forEach(entry => {
448441
if (
449442
entry.initiatorType === 'fetch' &&
450-
entry.name === parsedUrl.href
443+
entry.name === spanUrl
451444
) {
452445
entries.push(entry);
453446
}

experimental/packages/opentelemetry-instrumentation-xml-http-request/src/xhr.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import {
2828
getResource,
2929
PerformanceTimingNames as PTN,
3030
shouldPropagateTraceHeaders,
31-
URLLike
31+
parseUrl,
3232
} from '@opentelemetry/sdk-trace-web';
3333
import { EventNames } from './enums/EventNames';
3434
import {
@@ -40,12 +40,6 @@ import {
4040
import { VERSION } from './version';
4141
import { AttributeNames } from './enums/AttributeNames';
4242

43-
function parseUrl(url: string): URLLike {
44-
const element = document.createElement('a');
45-
element.href = url;
46-
return element;
47-
}
48-
4943
// how long to wait for observer to collect information about resources
5044
// this is needed as event "load" is called before observer
5145
// hard to say how long it should really wait, seems like 300ms is
@@ -215,8 +209,8 @@ export class XMLHttpRequestInstrumentation extends InstrumentationBase<XMLHttpRe
215209
const xhrMem = this._xhrMem.get(xhr);
216210
if (
217211
!xhrMem ||
218-
PerformanceObserver == null ||
219-
PerformanceResourceTiming == null
212+
typeof PerformanceObserver !== 'function' ||
213+
typeof PerformanceResourceTiming !== 'function'
220214
) {
221215
return;
222216
}

experimental/packages/opentelemetry-instrumentation-xml-http-request/test/xhr.test.ts

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import { SemanticAttributes } from '@opentelemetry/semantic-conventions';
2929
import {
3030
PerformanceTimingNames as PTN,
3131
WebTracerProvider,
32-
URLLike,
32+
parseUrl,
3333
} from '@opentelemetry/sdk-trace-web';
3434
import * as assert from 'assert';
3535
import * as sinon from 'sinon';
@@ -49,12 +49,6 @@ class DummySpanExporter implements tracing.SpanExporter {
4949
}
5050
}
5151

52-
function parseUrl(url: string): URLLike {
53-
const element = document.createElement('a');
54-
element.href = url;
55-
return element;
56-
}
57-
5852
const XHR_TIMEOUT = 2000;
5953

6054
const getData = (

packages/opentelemetry-sdk-trace-web/src/utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ export interface URLLike {
300300
*/
301301
export function parseUrl(url: string): URLLike {
302302
if (typeof URL === 'function') {
303-
return new URL(url);
303+
return new URL(url, location.href);
304304
}
305305
const element = getUrlNormalizingAnchor();
306306
element.href = url;

packages/opentelemetry-sdk-trace-web/test/utils.test.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,12 +490,25 @@ describe('utils', () => {
490490
assert.strictEqual(typeof url[field], 'string');
491491
});
492492
});
493+
494+
it('should parse relative url', () => {
495+
const url = parseUrl('/foo');
496+
urlFields.forEach(field => {
497+
assert.strictEqual(typeof url[field], 'string');
498+
});
499+
});
493500
});
494501

495502
describe('normalizeUrl', () => {
496503
it('should normalize url', () => {
497504
const url = normalizeUrl('https://opentelemetry.io/你好');
498505
assert.strictEqual(url, 'https://opentelemetry.io/%E4%BD%A0%E5%A5%BD');
499506
});
507+
508+
it('should normalize relative url', () => {
509+
const url = normalizeUrl('/你好');
510+
const urlObj = new URL(url);
511+
assert.strictEqual(urlObj.pathname, '/%E4%BD%A0%E5%A5%BD');
512+
});
500513
});
501514
});

0 commit comments

Comments
 (0)