Files
sim/packages/logger/src/request-context.ts
T
Theodore LiandClaude Opus 4.7 699bbfd16f feat(log): Add wrapper function for standardized logging (#4061)
* feat(log): Add wrapper function for standardized logging

* Add all routes to wrapper, handle background execution

* fix lint

* fix test

* fix test missing url

* fix lint

* fix tests

* fix build

* fix(build): unmangle generic in admin outbox requeue route

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 13:21:13 -04:00

47 lines
1.4 KiB
TypeScript

export interface RequestContext {
requestId: string
method?: string
path?: string
}
/**
* AsyncLocalStorage is only available in Node.js. In Edge/browser contexts
* we fall back to a no-op implementation so the logger import doesn't break.
*/
interface Storage<T> {
getStore(): T | undefined
run<R>(store: T, fn: () => R): R
}
let storage: Storage<RequestContext>
if (typeof globalThis.process !== 'undefined' && globalThis.process.versions?.node) {
// Node.js — use real AsyncLocalStorage
// eslint-disable-next-line @typescript-eslint/no-require-imports
const { AsyncLocalStorage } = require('node:async_hooks') as typeof import('node:async_hooks')
storage = new AsyncLocalStorage<RequestContext>()
} else {
// Edge / browser — no-op
storage = {
getStore: () => undefined,
run: <R>(_store: RequestContext, fn: () => R) => fn(),
}
}
/**
* Runs a callback within a request context. All loggers called inside
* the callback (and any async functions it awaits) will automatically
* include the request context metadata in their output.
*/
export function runWithRequestContext<T>(context: RequestContext, fn: () => T): T {
return storage.run(context, fn)
}
/**
* Returns the current request context, or undefined if called outside
* of a `runWithRequestContext` scope.
*/
export function getRequestContext(): RequestContext | undefined {
return storage.getStore()
}