@codebayu/usesignoz
Version:
The reusable plugin to implement signoz on Nuxt project
107 lines (106 loc) • 4.99 kB
JavaScript
import { context, trace, SpanStatusCode } from '@opentelemetry/api';
import { WebTracerProvider } from '@opentelemetry/sdk-trace-web';
import { Resource } from '@opentelemetry/resources';
import { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base';
import { ZoneContextManager } from '@opentelemetry/context-zone';
import { FetchInstrumentation } from '@opentelemetry/instrumentation-fetch';
import { registerInstrumentations } from '@opentelemetry/instrumentation';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
import { B3Propagator } from '@opentelemetry/propagator-b3';
import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions';
import { XMLHttpRequestInstrumentation } from '@opentelemetry/instrumentation-xml-http-request';
import { DocumentLoadInstrumentation } from '@opentelemetry/instrumentation-document-load';
import { excludeHost } from '../utils/common/constants';
import { customAttributesToResourceFetchSpan, mappingAttributes, } from '../utils/common/functions';
export const initTracerVue = ({ serviceName, exporterUrl, globalAttributes, }) => {
const exporter = new OTLPTraceExporter({ url: exporterUrl });
const resource = new Resource({
[SemanticResourceAttributes.SERVICE_NAME]: serviceName,
});
const provider = new WebTracerProvider({ resource });
provider.addSpanProcessor(new BatchSpanProcessor(exporter));
provider.register({
contextManager: new ZoneContextManager(),
propagator: new B3Propagator(),
});
registerInstrumentations({
instrumentations: [
new DocumentLoadInstrumentation({
applyCustomAttributesOnSpan: {
documentLoad: (span) => mappingAttributes(span, globalAttributes),
resourceFetch: customAttributesToResourceFetchSpan,
},
}),
new XMLHttpRequestInstrumentation({
propagateTraceHeaderCorsUrls: [/.+/g],
clearTimingResources: true,
applyCustomAttributesOnSpan: (span, xhr) => {
const attributes = span.attributes;
const hostRequest = attributes['http.url'];
const urlHost = new URL(hostRequest).hostname;
const isExclude = excludeHost.some((host) => urlHost.includes(host));
span.setAttribute('response', xhr.response);
span.setAttribute('responseText', xhr.responseText);
const name = `${attributes['http.method']} ${isExclude
? urlHost
: xhr.__zone_symbol__xhrURL || attributes['http.url']}`;
span.updateName(name);
mappingAttributes(span, globalAttributes);
},
}),
new FetchInstrumentation({
propagateTraceHeaderCorsUrls: ['/.*/g'],
clearTimingResources: true,
applyCustomAttributesOnSpan: (span, request, result) => {
const attributes = span.attributes;
const hostRequest = attributes['http.host'];
if (excludeHost.includes(hostRequest)) {
return;
}
if (attributes.component === 'fetch') {
span.updateName(`${attributes['http.method']} ${attributes['http.url']}`);
}
if (result instanceof Error) {
span.setStatus({
code: SpanStatusCode.ERROR,
message: result.message,
});
span.recordException(result.stack || result.name);
}
mappingAttributes(span, globalAttributes);
},
}),
],
});
return provider.getTracer(serviceName);
};
// This is the function that we will be using to trace function calls
export const createSpanVue = ({ tracer, name, func = () => { }, attributes, events, }) => {
const span = tracer.startSpan(name);
return context.with(trace.setSpan(context.active(), span), () => {
// mapping custom attributes
if (span.isRecording() && attributes) {
for (const key in attributes) {
if (attributes.hasOwnProperty(key)) {
const value = attributes[key];
span.setAttribute(key, value);
}
}
}
// mapping custom attributes
if (events) {
span.addEvent(events.name, events.keyValue);
}
// execute function to trace
try {
const result = func();
span.end();
return result;
}
catch (error) {
span.setStatus({ code: SpanStatusCode.ERROR });
span.end();
throw error;
}
});
};