Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion experimental/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ For notes on migrating to 2.x / 0.200.x see [the upgrade guide](doc/upgrade-to-2

### :rocket: Features

feat(configuration): parse config for rc 3 [#6304](https://github.com/open-telemetry/opentelemetry-js/pull/6304) @maryliag
* feat(otlp-exporter-base): implement fetch-later-transport [#6217](https://github.com/open-telemetry/opentelemetry-js/pull/6217) @YangJonghun
* feat(configuration): parse config for rc 3 [#6304](https://github.com/open-telemetry/opentelemetry-js/pull/6304) @maryliag

### :bug: Bug Fixes

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,41 @@ import {
describe('OTLPLogExporter', function () {
afterEach(() => {
sinon.restore();
delete (globalThis as any).fetchLater;
});

describe('export', function () {
describe('when fetchLater is available', function () {
it('should successfully send data using fetchLater', async function () {
// arrange
const fetchLaterStub = sinon.stub().returns({ activated: false });
(globalThis as any).fetchLater = fetchLaterStub;
const loggerProvider = new LoggerProvider({
processors: [new SimpleLogRecordProcessor(new OTLPLogExporter())],
});

// act
loggerProvider.getLogger('test-logger').emit({ body: 'test-body' });
await loggerProvider.shutdown();

// assert
assert.ok(fetchLaterStub.called, 'fetchLater should be called');
const [url, options] = fetchLaterStub.args[0];
assert.ok(url.endsWith('/v1/logs'), 'URL should end with /v1/logs');
assert.strictEqual(options.method, 'POST');
assert.doesNotThrow(
() => JSON.parse(new TextDecoder().decode(options.body)),
'expected requestBody to be in JSON format, but parsing failed'
);
});
});

describe('when sendBeacon is available', function () {
beforeEach(function () {
// disable fetchLater so sendBeacon is used
(globalThis as any).fetchLater = undefined;
});

it('should successfully send data using sendBeacon', async function () {
// arrange
const stubBeacon = sinon.stub(navigator, 'sendBeacon');
Expand All @@ -60,6 +91,8 @@ describe('OTLPLogExporter', function () {

describe('when sendBeacon is not available', function () {
beforeEach(function () {
// disable fetchLater so fetch is used
(globalThis as any).fetchLater = undefined;
// fake sendBeacon not being available
(window.navigator as any).sendBeacon = false;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,41 @@ import {
describe('OTLPLogExporter', function () {
afterEach(() => {
sinon.restore();
delete (globalThis as any).fetchLater;
});

describe('export', function () {
describe('when fetchLater is available', function () {
it('should successfully send data using fetchLater', async function () {
// arrange
const fetchLaterStub = sinon.stub().returns({ activated: false });
(globalThis as any).fetchLater = fetchLaterStub;
const loggerProvider = new LoggerProvider({
processors: [new SimpleLogRecordProcessor(new OTLPLogExporter())],
});

// act
loggerProvider.getLogger('test-logger').emit({ body: 'test-body' });
await loggerProvider.shutdown();

// assert
assert.ok(fetchLaterStub.called, 'fetchLater should be called');
const [url, options] = fetchLaterStub.args[0];
assert.ok(url.endsWith('/v1/logs'), 'URL should end with /v1/logs');
assert.strictEqual(options.method, 'POST');
assert.throws(
() => JSON.parse(new TextDecoder().decode(options.body)),
'expected requestBody to be in protobuf format, but parsing as JSON succeeded'
);
});
});

describe('when sendBeacon is available', function () {
beforeEach(function () {
// disable fetchLater so sendBeacon is used
(globalThis as any).fetchLater = undefined;
});

it('should successfully send data using sendBeacon', async function () {
// arrange
const stubBeacon = sinon.stub(navigator, 'sendBeacon');
Expand All @@ -60,6 +91,8 @@ describe('OTLPLogExporter', function () {

describe('when sendBeacon is not available', function () {
beforeEach(function () {
// disable fetchLater so fetch is used
(globalThis as any).fetchLater = undefined;
// fake sendBeacon not being available
(window.navigator as any).sendBeacon = false;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,41 @@ import { OTLPTraceExporter } from '../../src/platform/browser/index';
describe('OTLPTraceExporter', () => {
afterEach(() => {
sinon.restore();
delete (globalThis as any).fetchLater;
});

describe('export', function () {
describe('when fetchLater is available', function () {
it('should successfully send data using fetchLater', async function () {
// arrange
const fetchLaterStub = sinon.stub().returns({ activated: false });
(globalThis as any).fetchLater = fetchLaterStub;
const tracerProvider = new BasicTracerProvider({
spanProcessors: [new SimpleSpanProcessor(new OTLPTraceExporter())],
});

// act
tracerProvider.getTracer('test-tracer').startSpan('test-span').end();
await tracerProvider.shutdown();

// assert
assert.ok(fetchLaterStub.called, 'fetchLater should be called');
const [url, options] = fetchLaterStub.args[0];
assert.ok(url.endsWith('/v1/traces'), 'URL should end with /v1/traces');
assert.strictEqual(options.method, 'POST');
assert.doesNotThrow(
() => JSON.parse(new TextDecoder().decode(options.body)),
'expected requestBody to be in JSON format, but parsing failed'
);
});
});

describe('when sendBeacon is available', function () {
beforeEach(function () {
// disable fetchLater so sendBeacon is used
(globalThis as any).fetchLater = undefined;
});

it('should successfully send data using sendBeacon', async function () {
// arrange
const stubBeacon = sinon.stub(navigator, 'sendBeacon');
Expand All @@ -61,6 +92,8 @@ describe('OTLPTraceExporter', () => {

describe('when sendBeacon is not available', function () {
beforeEach(function () {
// disable fetchLater so fetch is used
(globalThis as any).fetchLater = undefined;
// fake sendBeacon not being available
(window.navigator as any).sendBeacon = false;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,41 @@ import { OTLPTraceExporter } from '../../src/platform/browser/index';
describe('OTLPTraceExporter', () => {
afterEach(() => {
sinon.restore();
delete (globalThis as any).fetchLater;
});

describe('export', function () {
describe('when fetchLater is available', function () {
it('should successfully send data using fetchLater', async function () {
// arrange
const fetchLaterStub = sinon.stub().returns({ activated: false });
(globalThis as any).fetchLater = fetchLaterStub;
const tracerProvider = new BasicTracerProvider({
spanProcessors: [new SimpleSpanProcessor(new OTLPTraceExporter())],
});

// act
tracerProvider.getTracer('test-tracer').startSpan('test-span').end();
await tracerProvider.shutdown();

// assert
assert.ok(fetchLaterStub.called, 'fetchLater should be called');
const [url, options] = fetchLaterStub.args[0];
assert.ok(url.endsWith('/v1/traces'), 'URL should end with /v1/traces');
assert.strictEqual(options.method, 'POST');
assert.throws(
() => JSON.parse(new TextDecoder().decode(options.body)),
'expected requestBody to be in protobuf format, but parsing as JSON succeeded'
);
});
});

describe('when sendBeacon is available', function () {
beforeEach(function () {
// disable fetchLater so sendBeacon is used
(globalThis as any).fetchLater = undefined;
});

it('should successfully send data using sendBeacon', async function () {
// arrange
const stubBeacon = sinon.stub(navigator, 'sendBeacon');
Expand All @@ -61,6 +92,8 @@ describe('OTLPTraceExporter', () => {

describe('when sendBeacon is not available', function () {
beforeEach(function () {
// disable fetchLater so fetch is used
(globalThis as any).fetchLater = undefined;
// fake sendBeacon not being available
(window.navigator as any).sendBeacon = false;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,51 @@ import { OTLPMetricExporter } from '../../src/platform/browser';
describe('OTLPMetricExporter', function () {
afterEach(() => {
sinon.restore();
delete (globalThis as any).fetchLater;
});

describe('export', function () {
describe('when fetchLater is available', function () {
it('should successfully send data using fetchLater', async function () {
// arrange
const fetchLaterStub = sinon.stub().returns({ activated: false });
(globalThis as any).fetchLater = fetchLaterStub;
const meterProvider = new MeterProvider({
readers: [
new PeriodicExportingMetricReader({
exporter: new OTLPMetricExporter(),
}),
],
});

// act
meterProvider
.getMeter('test-meter')
.createCounter('test-counter')
.add(1);
await meterProvider.shutdown();

// assert
assert.ok(fetchLaterStub.called, 'fetchLater should be called');
const [url, options] = fetchLaterStub.args[0];
assert.ok(
url.endsWith('/v1/metrics'),
'URL should end with /v1/metrics'
);
assert.strictEqual(options.method, 'POST');
assert.doesNotThrow(
() => JSON.parse(new TextDecoder().decode(options.body)),
'expected requestBody to be in JSON format, but parsing failed'
);
});
});

describe('when sendBeacon is available', function () {
beforeEach(function () {
// disable fetchLater so sendBeacon is used
(globalThis as any).fetchLater = undefined;
});

it('should successfully send data using sendBeacon', async function () {
// arrange
const stubBeacon = sinon.stub(navigator, 'sendBeacon');
Expand Down Expand Up @@ -72,6 +113,8 @@ describe('OTLPMetricExporter', function () {

describe('when sendBeacon is not available', function () {
beforeEach(function () {
// disable fetchLater so fetch is used
(globalThis as any).fetchLater = undefined;
// fake sendBeacon not being available
(window.navigator as any).sendBeacon = false;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,51 @@ import { OTLPMetricExporter } from '../../src/platform/browser';
describe('OTLPTraceExporter', () => {
afterEach(() => {
sinon.restore();
delete (globalThis as any).fetchLater;
});

describe('export', function () {
describe('when fetchLater is available', function () {
it('should successfully send data using fetchLater', async function () {
// arrange
const fetchLaterStub = sinon.stub().returns({ activated: false });
(globalThis as any).fetchLater = fetchLaterStub;
const meterProvider = new MeterProvider({
readers: [
new PeriodicExportingMetricReader({
exporter: new OTLPMetricExporter(),
}),
],
});

// act
meterProvider
.getMeter('test-meter')
.createCounter('test-counter')
.add(1);
await meterProvider.shutdown();

// assert
assert.ok(fetchLaterStub.called, 'fetchLater should be called');
const [url, options] = fetchLaterStub.args[0];
assert.ok(
url.endsWith('/v1/metrics'),
'URL should end with /v1/metrics'
);
assert.strictEqual(options.method, 'POST');
assert.throws(
() => JSON.parse(new TextDecoder().decode(options.body)),
'expected requestBody to be in protobuf format, but parsing as JSON succeeded'
);
});
});

describe('when sendBeacon is available', function () {
beforeEach(function () {
// disable fetchLater so sendBeacon is used
(globalThis as any).fetchLater = undefined;
});

it('should successfully send data using sendBeacon', async function () {
// arrange
const stubBeacon = sinon.stub(navigator, 'sendBeacon');
Expand Down Expand Up @@ -68,6 +109,8 @@ describe('OTLPTraceExporter', () => {

describe('when sendBeacon is not available', function () {
beforeEach(function () {
// disable fetchLater so fetch is used
(globalThis as any).fetchLater = undefined;
// fake sendBeacon not being available
(window.navigator as any).sendBeacon = false;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import { ISerializer } from '@opentelemetry/otlp-transformer';
import {
createOtlpFetchExportDelegate,
createOtlpFetchLaterExportDelegate,
createOtlpSendBeaconExportDelegate,
} from '../otlp-browser-http-export-delegate';
import { convertLegacyBrowserHttpOptions } from './convert-legacy-browser-http-options';
Expand Down Expand Up @@ -49,7 +50,13 @@ export function createLegacyOtlpBrowserExportDelegate<Internal, Response>(
export function inferExportDelegateToUse(
configHeaders: OTLPExporterConfigBase['headers']
) {
if (!configHeaders && typeof navigator.sendBeacon === 'function') {
if (
'fetchLater' in globalThis &&
/* eslint-disable @typescript-eslint/no-explicit-any */
typeof (globalThis as any).fetchLater !== 'undefined'
) {
return createOtlpFetchLaterExportDelegate;
} else if (!configHeaders && typeof navigator.sendBeacon === 'function') {
return createOtlpSendBeaconExportDelegate;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { createRetryingTransport } from './retrying-transport';
import { createSendBeaconTransport } from './transport/send-beacon-transport';
import { createOtlpNetworkExportDelegate } from './otlp-network-export-delegate';
import { createFetchTransport } from './transport/fetch-transport';
import { createFetchLaterTransport } from './transport/fetch-later-transport';

export function createOtlpFetchExportDelegate<Internal, Response>(
options: OtlpHttpConfiguration,
Expand Down Expand Up @@ -49,3 +50,16 @@ export function createOtlpSendBeaconExportDelegate<Internal, Response>(
})
);
}

export function createOtlpFetchLaterExportDelegate<Internal, Response>(
options: OtlpHttpConfiguration,
serializer: ISerializer<Internal, Response>
): IOtlpExportDelegate<Internal> {
return createOtlpNetworkExportDelegate(
options,
serializer,
createRetryingTransport({
transport: createFetchLaterTransport(options),
})
);
}
Loading