Skip to content

Commit

Permalink
Try export with XHR retry
Browse files Browse the repository at this point in the history
  • Loading branch information
myieye committed Oct 27, 2023
1 parent 7a7d781 commit 638d0e7
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 6 deletions.
12 changes: 6 additions & 6 deletions frontend/src/lib/otel/otel.client.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { BatchSpanProcessor, WebTracerProvider } from '@opentelemetry/sdk-trace-web'
import { SERVICE_NAME, ensureErrorIsTraced, tracer } from '.'

import {APP_VERSION} from '$lib/util/version';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'
import { APP_VERSION } from '$lib/util/version';
import { OTLPTraceExporterBrowserWithXhrRetry } from './trace-exporter-browser-with-xhr-retry';
import { Resource } from '@opentelemetry/resources'
import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions'
import { ZoneContextManager } from '@opentelemetry/context-zone'
Expand Down Expand Up @@ -47,15 +47,15 @@ const resource = Resource.default().merge(
)
const provider = new WebTracerProvider({
resource: resource,
})
const exporter = new OTLPTraceExporter({
});
const exporter = new OTLPTraceExporterBrowserWithXhrRetry({
url: '/v1/traces'
});
provider.addSpanProcessor(
new BatchSpanProcessor(exporter, {
// max number of spans pulled from the qeuue and exported in a single batch
// this can't be much higher or the export will be too big for the sendBeacon() API
maxExportBatchSize: 15,
// 30 is often too big for the sendBeacon() API, but we have a fallback to XHR.
maxExportBatchSize: 30,
// minimum time between exports
scheduledDelayMillis: 1000,
maxQueueSize: 5000, // default: 2048
Expand Down
39 changes: 39 additions & 0 deletions frontend/src/lib/otel/trace-exporter-browser-with-xhr-retry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// We explicitly reference the browser version so that we have proper types

import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http/build/src/platform/browser';
import type { ReadableSpan } from '@opentelemetry/sdk-trace-web';

// these save us a dependency
type SendOnErrorCallback = Parameters<OTLPTraceExporter['send']>[2];
type ExporterConfig = ConstructorParameters<typeof OTLPTraceExporter>[0];

export class OTLPTraceExporterBrowserWithXhrRetry extends OTLPTraceExporter {

private readonly xhrTraceExporter: OTLPTraceExporter;

constructor(config?: ExporterConfig) {
super(config);
this.xhrTraceExporter = new OTLPTraceExporter({
...(config ?? {}),
// passing a truthy value here causes XHR to be used: https://github.com/open-telemetry/opentelemetry-js/blob/main/experimental/packages/otlp-exporter-base/src/platform/browser/OTLPExporterBrowserBase.ts#L40
headers: {},
});
}

send(items: ReadableSpan[], onSuccess: () => void, onError: SendOnErrorCallback): void {
super.send(items, onSuccess, (error) => {
if (error.message.toLocaleLowerCase().includes('beacon')) {
this.xhrTraceExporter.send(items, onSuccess, (xhrError) => {
onError({
...error,
message: `${error.message} --- [XHR retry message: ${xhrError.message}; code: ${xhrError.code}].`,
code: error.code,
data: `${error.data} --- [XHR retry data: ${xhrError.data}].`,
});
});
} else {
onError(error);
}
});
}
}

0 comments on commit 638d0e7

Please sign in to comment.