@grafana/faro-web-tracing
Version:
Faro web tracing implementation.
102 lines • 5.7 kB
JavaScript
import { context, trace } from '@opentelemetry/api';
import { W3CTraceContextPropagator } from '@opentelemetry/core';
import { registerInstrumentations } from '@opentelemetry/instrumentation';
import { defaultResource, resourceFromAttributes } from '@opentelemetry/resources';
import { BatchSpanProcessor, WebTracerProvider } from '@opentelemetry/sdk-trace-web';
import { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION, ATTR_USER_AGENT_ORIGINAL, SEMRESATTRS_DEPLOYMENT_ENVIRONMENT, } from '@opentelemetry/semantic-conventions';
import { BaseInstrumentation, isArray, VERSION } from '@grafana/faro-web-sdk';
import { FaroMetaAttributesSpanProcessor } from './faroMetaAttributesSpanProcessor';
import { FaroTraceExporter } from './faroTraceExporter';
import { getDefaultOTELInstrumentations } from './getDefaultOTELInstrumentations';
import { getSamplingDecision } from './sampler';
import { ATTR_BROWSER_BRANDS, ATTR_BROWSER_LANGUAGE, ATTR_BROWSER_MOBILE, ATTR_BROWSER_PLATFORM, ATTR_DEPLOYMENT_ENVIRONMENT_NAME, ATTR_PROCESS_RUNTIME_NAME, ATTR_PROCESS_RUNTIME_VERSION, ATTR_SERVICE_NAMESPACE, ATTR_TELEMETRY_DISTRO_NAME, ATTR_TELEMETRY_DISTRO_VERSION, } from './semconv';
// the providing of app name here is not great
// should delay initialization and provide the full Faro config,
// taking app name from it
export class TracingInstrumentation extends BaseInstrumentation {
constructor(options = {}) {
super();
this.options = options;
this.name = '@grafana/faro-web-tracing';
this.version = VERSION;
}
initialize() {
var _a, _b, _c, _d, _e;
const options = this.options;
const attributes = {};
if (this.config.app.name) {
attributes[ATTR_SERVICE_NAME] = this.config.app.name;
}
if (this.config.app.namespace) {
attributes[ATTR_SERVICE_NAMESPACE] = this.config.app.namespace;
}
if (this.config.app.version) {
attributes[ATTR_SERVICE_VERSION] = this.config.app.version;
}
if (this.config.app.environment) {
attributes[ATTR_DEPLOYMENT_ENVIRONMENT_NAME] = this.config.app.environment;
/**
* @deprecated will be removed in the future and has been replaced by ATTR_DEPLOYMENT_ENVIRONMENT_NAME (deployment.environment.name)
* We need to keep this for compatibility with some internal services for now.
*/
attributes[SEMRESATTRS_DEPLOYMENT_ENVIRONMENT] = this.config.app.environment;
}
const browserMeta = this.metas.value.browser;
if (isArray(browserMeta === null || browserMeta === void 0 ? void 0 : browserMeta.brands)) {
attributes[ATTR_BROWSER_BRANDS] = browserMeta.brands.map((entry) => entry.brand);
}
if (browserMeta === null || browserMeta === void 0 ? void 0 : browserMeta.language) {
attributes[ATTR_BROWSER_LANGUAGE] = browserMeta.language;
}
if (typeof (browserMeta === null || browserMeta === void 0 ? void 0 : browserMeta.mobile) === 'boolean') {
attributes[ATTR_BROWSER_MOBILE] = Boolean(browserMeta.mobile);
}
if (browserMeta === null || browserMeta === void 0 ? void 0 : browserMeta.os) {
attributes[ATTR_BROWSER_PLATFORM] = browserMeta.os;
}
if (browserMeta === null || browserMeta === void 0 ? void 0 : browserMeta.userAgent) {
attributes[ATTR_USER_AGENT_ORIGINAL] = browserMeta.userAgent;
}
attributes[ATTR_PROCESS_RUNTIME_NAME] = 'browser';
attributes[ATTR_PROCESS_RUNTIME_VERSION] = (_a = this.metas.value.browser) === null || _a === void 0 ? void 0 : _a.userAgent;
attributes[ATTR_TELEMETRY_DISTRO_NAME] = 'faro-web-sdk';
attributes[ATTR_TELEMETRY_DISTRO_VERSION] = VERSION;
Object.assign(attributes, options.resourceAttributes);
const resource = defaultResource().merge(resourceFromAttributes(attributes));
const provider = new WebTracerProvider({
resource,
sampler: {
shouldSample: () => {
return {
decision: getSamplingDecision(this.api.getSession()),
};
},
},
spanProcessors: [
(_b = options.spanProcessor) !== null && _b !== void 0 ? _b : new FaroMetaAttributesSpanProcessor(new BatchSpanProcessor(new FaroTraceExporter({ api: this.api }), {
scheduledDelayMillis: TracingInstrumentation.SCHEDULED_BATCH_DELAY_MS,
maxExportBatchSize: 30,
}), this.metas),
],
});
provider.register({
propagator: (_c = options.propagator) !== null && _c !== void 0 ? _c : new W3CTraceContextPropagator(),
contextManager: options.contextManager,
});
const { propagateTraceHeaderCorsUrls, fetchInstrumentationOptions, xhrInstrumentationOptions } = (_d = this.options.instrumentationOptions) !== null && _d !== void 0 ? _d : {};
registerInstrumentations({
instrumentations: (_e = options.instrumentations) !== null && _e !== void 0 ? _e : getDefaultOTELInstrumentations({
ignoreUrls: this.getIgnoreUrls(),
propagateTraceHeaderCorsUrls,
fetchInstrumentationOptions,
xhrInstrumentationOptions,
}),
});
this.api.initOTEL(trace, context);
}
getIgnoreUrls() {
return this.transports.transports.flatMap((transport) => transport.getIgnoreUrls());
}
}
TracingInstrumentation.SCHEDULED_BATCH_DELAY_MS = 1000;
//# sourceMappingURL=instrumentation.js.map