UNPKG

nestjs-otel

Version:
66 lines (65 loc) 2.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Span = Span; const api_1 = require("@opentelemetry/api"); const opentelemetry_utils_1 = require("../../opentelemetry.utils"); const recordException = (span, error) => { span.recordException(error); span.setStatus({ code: api_1.SpanStatusCode.ERROR, message: error.message }); }; function Span(nameOrOptions, maybeOptions) { return (target, propertyKey, propertyDescriptor) => { let name; let options; if (typeof nameOrOptions === 'string') { name = nameOrOptions; options = maybeOptions ?? {}; } else { name = `${target.constructor.name}.${String(propertyKey)}`; options = nameOrOptions ?? {}; } const originalFunction = propertyDescriptor.value; if (typeof originalFunction !== 'function') { throw new Error(`The @Span decorator can be only used on functions, but ${propertyKey.toString()} is not a function.`); } const wrappedFunction = function PropertyDescriptor(...args) { const tracer = api_1.trace.getTracer('default'); const spanOptions = typeof options === 'function' ? options(...args) : options; return tracer.startActiveSpan(name, spanOptions, span => { if (originalFunction.constructor.name === 'AsyncFunction') { return originalFunction .apply(this, args) .catch((error) => { recordException(span, error); // Throw error to propagate it further throw error; }) .finally(() => { span.end(); }); } try { return originalFunction.apply(this, args); } catch (error) { recordException(span, error); // Throw error to propagate it further throw error; } finally { span.end(); } }); }; // Wrap the original function in a proxy to ensure that the function name is preserved. // This should also preserve parameters for OpenAPI and other libraries // that rely on the function name as metadata key. propertyDescriptor.value = new Proxy(originalFunction, { apply: (_, thisArg, args) => { return wrappedFunction.apply(thisArg, args); }, }); (0, opentelemetry_utils_1.copyMetadataFromFunctionToFunction)(originalFunction, propertyDescriptor.value); }; }