Skip to content

Commit

Permalink
Use XHR sender by default, increase throughput (#537)
Browse files Browse the repository at this point in the history
  • Loading branch information
t2t2 authored Mar 22, 2023
1 parent 13cf3fd commit 22a9b72
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 9 deletions.
41 changes: 41 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/web/src/SplunkExporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ export class SplunkExporter implements SpanExporter {
spans = spans.filter(span => this._filter(span));
const zspans = spans.map(span => this._mapToZipkinSpan(span));
const zJson = JSON.stringify(zspans);
if (this._beaconSender) {
if (document.hidden && this._beaconSender && zJson.length <= 64000) {
this._beaconSender(this.beaconUrl, zJson);
} else {
this._xhrSender(this.beaconUrl, zJson);
Expand Down
4 changes: 2 additions & 2 deletions packages/web/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,8 @@ interface SplunkOtelWebConfigInternal extends SplunkOtelWebConfig {
const OPTIONS_DEFAULTS: SplunkOtelWebConfigInternal = {
app: 'unknown-browser-app',
beaconUrl: undefined,
bufferTimeout: 5000, //millis, tradeoff between batching and loss of spans by not sending before page close
bufferSize: 20, // spans, tradeoff between batching and hitting sendBeacon invididual limits
bufferTimeout: 4000, //millis, tradeoff between batching and loss of spans by not sending before page close
bufferSize: 50, // spans, tradeoff between batching and hitting sendBeacon invididual limits
instrumentations: {},
exporter: {
factory: (options) => new SplunkExporter(options),
Expand Down
28 changes: 22 additions & 6 deletions packages/web/test/SplunkExporter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,25 @@ describe('SplunkExporter', () => {
beaconSenderMock.restore();
});

it('uses Beacon API if available', () => {
it('uses Beacon API if in background', () => {
exporter = new SplunkExporter({
beaconUrl: 'https://domain1',
xhrSender: xhrSenderMock,
});

const targetDocProto = Object.getPrototypeOf(Object.getPrototypeOf(document));
const oldDef = Object.getOwnPropertyDescriptor(targetDocProto, 'hidden');
Object.defineProperty(targetDocProto, 'hidden', {
get() {
return true;
},
configurable: true,
enumerable: true,
});
const dummySpan = buildDummySpan();
exporter.export([dummySpan], () => {});
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
Object.defineProperty(targetDocProto, 'hidden', oldDef!);

expect(beaconSenderMock.args[0][0]).to.eq('https://domain1');
const sentSpan = JSON.parse(beaconSenderMock.args[0][1])[0];
Expand Down Expand Up @@ -94,20 +105,22 @@ describe('SplunkExporter', () => {
it('limits spans sent', () => {
exporter = new SplunkExporter({
beaconUrl: 'https://localhost',
xhrSender: xhrSenderMock,
});

const dummySpan = buildDummySpan();
const spans: (typeof dummySpan)[] = [];
for (let i = 0; i < 110; i++) { spans.push(dummySpan); }
exporter.export(spans, () => {});

const sentSpans = JSON.parse(beaconSenderMock.getCall(0).args[1]);
const sentSpans = JSON.parse(xhrSenderMock.getCall(0).args[1]);
expect(sentSpans).to.have.lengthOf(100);
});

it('still exports parent spans', () => {
exporter = new SplunkExporter({
beaconUrl: 'https://localhost',
xhrSender: xhrSenderMock,
});

const dummySpan = buildDummySpan();
Expand All @@ -122,13 +135,14 @@ describe('SplunkExporter', () => {
spans.push(parentSpan);
exporter.export(spans, () => {});

const sentSpans = JSON.parse(beaconSenderMock.getCall(0).args[1]);
const sentSpans = JSON.parse(xhrSenderMock.getCall(0).args[1]);
expect(sentSpans).to.have.lengthOf(101);
});

it('truncates long values', () => {
exporter = new SplunkExporter({
beaconUrl: 'https://localhost',
xhrSender: xhrSenderMock,
});

const dummySpan = buildDummySpan({
Expand All @@ -140,7 +154,7 @@ describe('SplunkExporter', () => {
});
exporter.export([dummySpan], () => {});

const sentSpan = JSON.parse(beaconSenderMock.getCall(0).args[1])[0];
const sentSpan = JSON.parse(xhrSenderMock.getCall(0).args[1])[0];
expect(sentSpan.name).to.eq('a'.repeat(4096));
expect(sentSpan.tags['longValue']).to.eq('b'.repeat(4096));
expect(sentSpan.tags['shortValue']).to.eq('c'.repeat(4000));
Expand All @@ -149,6 +163,7 @@ describe('SplunkExporter', () => {
it('filters out missing cors timings', () => {
exporter = new SplunkExporter({
beaconUrl: 'https://localhost',
xhrSender: xhrSenderMock,
});

const dummySpan = buildDummySpan({
Expand All @@ -175,13 +190,14 @@ describe('SplunkExporter', () => {
});
exporter.export([dummySpan], () => {});

const sentSpan = JSON.parse(beaconSenderMock.getCall(0).args[1])[0];
const sentSpan = JSON.parse(xhrSenderMock.getCall(0).args[1])[0];
expect(sentSpan.annotations.length).to.eq(2);
});

it('allows hooking into serialization', () => {
exporter = new SplunkExporter({
beaconUrl: 'https://localhost',
xhrSender: xhrSenderMock,
onAttributesSerializing: (attributes) => ({
...attributes,
key1: 'new value 1',
Expand All @@ -198,7 +214,7 @@ describe('SplunkExporter', () => {
});
exporter.export([dummySpan], () => {});

const sentSpan = JSON.parse(beaconSenderMock.getCall(0).args[1])[0];
const sentSpan = JSON.parse(xhrSenderMock.getCall(0).args[1])[0];
expect(sentSpan.name).to.eq('<name>');
console.log(sentSpan.tags);
expect(sentSpan.tags).to.deep.eq({
Expand Down

0 comments on commit 22a9b72

Please sign in to comment.