@ogcio/o11y-sdk-node
Version:
Opentelemetry standard instrumentation SDK for NodeJS based project
79 lines (73 loc) • 2.3 kB
text/typescript
import { Span, SpanOptions, SpanStatusCode, trace } from "@opentelemetry/api";
import { getNodeSdkConfig } from "./config-manager.js";
export type WithSpanParams<T> = {
/**
* The name of the trace the span should belong to.
* NOTE: If you want the new span to belong to an already existing trace, you should provide the same tracer name
*/
traceName?: string;
spanName: string;
spanOptions?: SpanOptions;
/** A function defining the task you want to be wrapped by this span */
fn: (span: Span) => T | Promise<T>;
};
/**
* Generates a function wrapping a given Callable `fn` into an error handling block.
* Setting Span status and recording any caught exception before bubbling it up.
*
* Marks the span as ended once the provided callable has ended or an error has been caught.
*
* @returns {Promise<T>} where T is the type returned by the Callable.
* @throws any error thrown by the original Callable `fn` provided.
*/
function selfContainedSpanHandlerGenerator<T>(
fn: (span: Span) => T | Promise<T>,
): (span: Span) => Promise<T> {
return async (span: Span) => {
try {
const fnResult = await fn(span);
span.setStatus({ code: SpanStatusCode.OK });
return fnResult;
} catch (err) {
if (err instanceof Error) {
span.recordException(err);
span.setStatus({ code: SpanStatusCode.ERROR, message: err.message });
throw err;
}
span.recordException({ message: JSON.stringify(err) });
span.setStatus({
code: SpanStatusCode.ERROR,
message: JSON.stringify(err),
});
throw err;
} finally {
span.end();
}
};
}
/**
* Gets the currently active OpenTelemetry span.
*
* @returns {Span | undefined} The active span with redaction logic applied,
* or `undefined` if there is no active span in context.
*/
export function getActiveSpan() {
return trace.getActiveSpan();
}
export function withSpan<T>({
traceName,
spanName,
spanOptions = {},
fn,
}: WithSpanParams<T>) {
const sdkConfig = getNodeSdkConfig();
const tracer = trace.getTracer(
traceName ?? sdkConfig.serviceName ?? "o11y-sdk",
sdkConfig.serviceVersion,
);
return tracer.startActiveSpan(
spanName,
spanOptions,
selfContainedSpanHandlerGenerator<T>(fn),
);
}