@trifrost/core
Version:
Blazingly fast, runtime-agnostic server framework for modern edge and node environments
71 lines (70 loc) • 2.58 kB
JavaScript
import { ctx as getCtx } from '../../utils/Als';
/**
* Symbol attached to methods to prevent duplicate span wraps
*/
export const Sym_TriFrostSpan = Symbol('trifrost.logger.is_span');
function hasLogger(val) {
return typeof val?.logger?.span === 'function';
}
/**
* Resolve a TriFrost logger instance from any combination of:
* - ALS-bound context (if available)
* - First argument (if it's a TriFrostContext)
* - `this.logger` or `this.ctx.logger` (for instance methods)
*/
function resolveLogger(self, args) {
// ALS-bound context
const ctxAls = getCtx();
if (hasLogger(ctxAls))
return ctxAls?.logger;
// First argument
const ctxArg = Array.isArray(args) && args.length ? args[0] : undefined;
if (hasLogger(ctxArg))
return ctxArg?.logger;
// Fallback to self.logger
if (hasLogger(self))
return self.logger;
// Fallback to self.ctx.logger
if (hasLogger(self?.ctx))
return self.ctx.logger;
return null;
}
export function span(name) {
return function (method, context) {
/* Prevent re-decoration */
if (Reflect.get(method, Sym_TriFrostSpan))
return method;
/* Define span name */
const span_name = typeof name === 'string' && name.length ? name : String(context.name);
const wrapped = function (...fn_args) {
const logger = resolveLogger(this, fn_args);
if (!logger)
return method.call(this, ...fn_args);
return logger.span(span_name, () => method.call(this, ...fn_args));
};
/* Set to prevent re-decoration */
Reflect.set(wrapped, Sym_TriFrostSpan, true);
return wrapped;
};
}
export function spanFn(...args) {
const [name_or_fn, maybe_fn] = args;
/* Define function */
const fn = typeof name_or_fn === 'function' ? name_or_fn : maybe_fn;
/* Prevent re-decoration */
if (Reflect.get(fn, Sym_TriFrostSpan))
return fn;
/* Define name */
// eslint-disable-next-line prettier/prettier
const span_name = typeof name_or_fn === 'string' && name_or_fn.length ? name_or_fn : typeof fn.name === 'string' && fn.name.length ? fn.name : 'anonymous';
/* Span function */
const fn_span = function (...fn_args) {
const logger = resolveLogger(this, fn_args);
if (!logger)
return fn.apply(this, fn_args);
return logger.span(span_name, () => fn.apply(this, fn_args));
};
/* Set to prevent re-decoration */
Reflect.set(fn_span, Sym_TriFrostSpan, true);
return fn_span;
}