UNPKG

@codebayu/nuxt-plugins-signoz

Version:

Reusable plugin to implement signoz on Nuxt project

117 lines (107 loc) 4.62 kB
import { Span, SpanStatusCode, context, trace } from '@opentelemetry/api'; import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'; import { WebTracerProvider } from '@opentelemetry/sdk-trace-web'; import { Resource } from '@opentelemetry/resources'; import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions'; import { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base'; import { ZoneContextManager } from '@opentelemetry/context-zone'; import { B3Propagator } from '@opentelemetry/propagator-b3'; import { registerInstrumentations } from '@opentelemetry/instrumentation'; import { getWebAutoInstrumentations } from '@opentelemetry/auto-instrumentations-web'; import { ICreateSpan, IInitTracer } from '../types'; export const initTracer = ({ serviceName, exporterUrl, attributes }: IInitTracer) => { 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() }) const excludeHost = ['www.google-analytics.com', 'api-js.mixpanel.com', 'sdk-01.moengage.com', 'stats.g.doubleclick.net'] const customAttributes = (span: Span) => { span.setAttribute('http.path', attributes.path) span.setAttribute('user.uuid', attributes.uuid) } const customAttributesToResourceFetchSpan = (span: Span, resource: PerformanceResourceTiming) => { span.setAttribute('resource.tcp.duration_ms', resource.connectEnd - resource.connectStart) } registerInstrumentations({ instrumentations: [ getWebAutoInstrumentations({ '@opentelemetry/instrumentation-document-load': { applyCustomAttributesOnSpan: { documentLoad: customAttributes, resourceFetch: customAttributesToResourceFetchSpan } }, '@opentelemetry/instrumentation-xml-http-request': { propagateTraceHeaderCorsUrls: [/.+/g], clearTimingResources: true, applyCustomAttributesOnSpan: (span: Span | any, xhr: XMLHttpRequest | any) => { const attributes = span.attributes const hostRequest = attributes['http.url'] const urlHost = new URL(hostRequest).hostname const isExclude = excludeHost.some(host => urlHost.includes(host)) const spanName = `${attributes['http.method']} ${isExclude ? urlHost : xhr.__zone_symbol__xhrURL || attributes['http.url']}` span.setAttribute('response', xhr.response) span.setAttribute('responseText', xhr.responseText) span.updateName(spanName) customAttributes(span) } }, '@opentelemetry/instrumentation-fetch': { propagateTraceHeaderCorsUrls: [/.+/g], clearTimingResources: true, applyCustomAttributesOnSpan: (span: Span | any, 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) } customAttributes(span) } } }) ] }) return provider.getTracer(serviceName); }; export const createSpan = ({ tracer, name, func = () => {}, attributes, events }: ICreateSpan) => { 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 } }) }