diff --git a/src/biolink.ts b/src/biolink.ts index d9b7e25..1bab044 100644 --- a/src/biolink.ts +++ b/src/biolink.ts @@ -1,5 +1,5 @@ import { BioLink } from 'biolink-model'; -import Debug from 'debug'; +import { Debug } from "./debug"; const debug = Debug('bte:biothings-explorer-trapi:EdgeReverse'); class BioLinkModel { diff --git a/src/debug.ts b/src/debug.ts new file mode 100644 index 0000000..ad31b00 --- /dev/null +++ b/src/debug.ts @@ -0,0 +1,48 @@ +import debug, { Debugger } from 'debug'; +import async_hooks from 'async_hooks'; + +const debugInstances: {[namespace: string]: {[postfix: string]: Debugger}} = {}; +const asyncContext = new Map(); + +// any child async calls/promises will inherit the asyncContex from their parent (triggerAsyncId) +async_hooks.createHook({ + init(asyncId, type, triggerAsyncId, resource) { + if (asyncContext.has(triggerAsyncId)) { + asyncContext.set(asyncId, asyncContext.get(triggerAsyncId)); + } + }, + destroy(asyncId) { + asyncContext.delete(asyncId); + } +}).enable(); + +export function withDebugContext any>(postfix: string, fn: F) { + return async (...args: Parameters): Promise>> => { + // associates the promise created by this function with the postfix to be added to the debug namespace + const asyncId = async_hooks.executionAsyncId(); + asyncContext.set(asyncId, postfix); + + try { + return await fn(...args); + } finally { + asyncContext.delete(asyncId); + } + }; +} + +function getContext() { + const asyncId = async_hooks.executionAsyncId(); + return asyncContext.get(asyncId); +} + +export function Debug(namespace: string) { + // debug instances are organized by postfix to the namespace (default is no postfix) + debugInstances[namespace] = {'': debug(namespace)}; + return function(...args: Parameters) { + // getContext gives the postfix to the namespace (create new debug instance if we don't have one yet) + if (!debugInstances[namespace][getContext() ?? '']) { + debugInstances[namespace][getContext()] = debug(namespace + getContext()); + } + debugInstances[namespace][getContext() ?? ''](...args); + } +} \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 064e864..f27a01f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,3 +4,4 @@ export * from "./telemetry"; export * from "./misc"; export * from "./redis-client"; export * from "./biolink"; +export * from "./debug"; \ No newline at end of file diff --git a/src/redis-client.ts b/src/redis-client.ts index f4cad3d..6ba5584 100644 --- a/src/redis-client.ts +++ b/src/redis-client.ts @@ -1,5 +1,5 @@ import Redis, { Cluster, RedisKey } from "ioredis"; -import Debug from "debug"; +import { Debug } from "./debug"; const debug = Debug("bte:biothings-explorer-trapi:redis-client"); import Redlock, { RedlockAbortSignal } from "redlock"; diff --git a/src/telemetry.ts b/src/telemetry.ts index caf75ab..eab38e0 100644 --- a/src/telemetry.ts +++ b/src/telemetry.ts @@ -1,5 +1,5 @@ import * as Sentry from "@sentry/node"; -import Debug from "debug"; +import { Debug } from "./debug"; import opentelemetry, { Span as OtelSpan, SpanStatusCode,