Skip to content

Commit

Permalink
feat(exporter-trace-otlp-http): fallback to XHR if sendBeacon fails
Browse files Browse the repository at this point in the history
  • Loading branch information
njoy89 committed Mar 13, 2024
1 parent 7be35c7 commit dc6106a
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,12 @@ export abstract class OTLPExporterBrowserBase<
const body = JSON.stringify(serviceRequest);

const promise = new Promise<void>((resolve, reject) => {
if (this._useXHR) {
if (
!this._useXHR &&
sendWithBeacon(body, this.url, { type: 'application/json' })
) {
resolve();
} else {
sendWithXhr(
body,
this.url,
Expand All @@ -78,14 +83,6 @@ export abstract class OTLPExporterBrowserBase<
resolve,
reject
);
} else {
sendWithBeacon(
body,
this.url,
{ type: 'application/json' },
resolve,
reject
);
}
}).then(onSuccess, onError);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ import {
parseRetryAfterToMills,
} from '../../util';

let minimumFailedSendBeaconPayloadSize = Infinity;

// exported only for test files
export const resetSendWithBeacon = () => {
minimumFailedSendBeaconPayloadSize = Infinity;
};

/**
* Send metrics/spans using browser navigator.sendBeacon
* @param body
Expand All @@ -36,16 +43,25 @@ export function sendWithBeacon(
body: string,
url: string,
blobPropertyBag: BlobPropertyBag,
onSuccess: () => void,
onError: (error: OTLPExporterError) => void
): void {
if (navigator.sendBeacon(url, new Blob([body], blobPropertyBag))) {
): boolean {
// navigator.sendBeacon returns 'false' if the given payload exceeds the user agent limit.
// See https://w3c.github.io/beacon/#return-value for specification.
// Because we don't know what the limit is and to keep user's console clean, we only try to send payloads that may suceed.
const blob = new Blob([body], blobPropertyBag);
if (
blob.size < minimumFailedSendBeaconPayloadSize &&
navigator.sendBeacon(url, blob)
) {
diag.debug('sendBeacon - can send', body);
onSuccess();
} else {
const error = new OTLPExporterError(`sendBeacon - cannot send ${body}`);
onError(error);
return true;
}

minimumFailedSendBeaconPayloadSize = blob.size;
diag.info(
'sendBeacon failed because the given payload was too big; try to lower your span processor limits',
);

return false;
}

/**
Expand Down

0 comments on commit dc6106a

Please sign in to comment.