@ogcio/o11y-sdk-react
Version:
Opentelemetry standard instrumentation SDK for React based project
104 lines (95 loc) • 2.99 kB
text/typescript
import {
ErrorsInstrumentation,
getWebInstrumentations,
initializeFaro,
WebVitalsInstrumentation,
type Faro,
} from "@grafana/faro-react";
import { TracingInstrumentation } from "@grafana/faro-web-tracing";
import { diag, DiagConsoleLogger, DiagLogLevel } from "@opentelemetry/api";
import { W3CTraceContextPropagator } from "@opentelemetry/core";
import { DocumentLoadInstrumentation } from "@opentelemetry/instrumentation-document-load";
import { FetchInstrumentation } from "@opentelemetry/instrumentation-fetch";
import { UserInteractionInstrumentation } from "@opentelemetry/instrumentation-user-interaction";
import type { FaroSDKConfig } from "./index.js";
import { _beforeSend } from "./internals/hooks.js";
export default function buildFaroInstrumentation(
config?: FaroSDKConfig,
): Faro | undefined {
if (!config) {
console.warn(
"observability config not set. Skipping Faro OpenTelemetry instrumentation.",
);
return;
}
if (!config.collectorUrl) {
console.warn(
"collectorUrl not set. Skipping Faro OpenTelemetry instrumentation.",
);
return;
}
if (!isUrl(config.collectorUrl)) {
console.error(
"collectorUrl does not use a valid format. Skipping Faro OpenTelemetry instrumentation.",
);
return;
}
if (!config.detection) {
config.detection = {
email: true,
};
}
if (config.detection.email === undefined) {
config.detection.email = true;
}
try {
diag.setLogger(
new DiagConsoleLogger(),
config.diagLogLevel
? DiagLogLevel[config.diagLogLevel]
: DiagLogLevel.INFO,
);
const faro = initializeFaro({
url: config.collectorUrl,
app: {
name: config.serviceName,
},
batching: {
enabled: !(config.collectorMode === "single"),
},
beforeSend: config.detection.email ? _beforeSend : undefined,
instrumentations: [
...getWebInstrumentations({
captureConsole: true,
}),
new ErrorsInstrumentation(),
new WebVitalsInstrumentation(),
new TracingInstrumentation({
propagator: new W3CTraceContextPropagator(),
instrumentations: [
new DocumentLoadInstrumentation(),
new FetchInstrumentation({
ignoreUrls: [config.collectorUrl], // ignore collector to avoid fetch loop
propagateTraceHeaderCorsUrls: config.corsTraceHeaders
? config.corsTraceHeaders.split(",").map((s) => new RegExp(s))
: undefined,
}),
new UserInteractionInstrumentation(),
],
}),
],
});
console.log("Faro OpenTelemetry instrumentation started successfully.");
return faro;
} catch (error) {
console.error("Error starting Faro OpenTelemetry instrumentation:", error);
}
}
function isUrl(url: string): boolean {
try {
new URL(url);
return true;
} catch (_) {
return false;
}
}