/** * @fileoverview LogContext bridge — MDC (Mapped Diagnostic Context) management. * Encapsulates per-logger structured context, child logger creation, and * OTel resource merging. * * F4 MDC API reset: * - `withContext(bindings, fn?)` — if fn provided, run within AsyncLocalStorage. * Without fn: no-op (backwards compat shim for the old setter shape). * - `withContextAsync(bindings, fn)` — async callback variant. * - `child(bindings)` remains immutable (canonical MDC pattern). * - Feature-detect AsyncLocalStorage; browser fallback is a no-op. */ import type { ILogResourceRef } from '../types/index.js'; import type { LoggerConfig } from '../types/index.js'; /** * Snapshot of the bound context. Returned by {@link LogContext.getContext}. */ export type ContextSnapshot = Readonly>; /** * Factory function type for creating child Logger instances. * Passed to LogContext so `child()` can instantiate new loggers without * introducing a circular import. Returns unknown — the actual Logger class * is used by the caller and the returned instance has its `context` field * written to by LogContext. */ export type ChildLoggerFactory = (config: Partial) => unknown; /** * Minimal shape of a Logger instance needed by LogContext. * Used to avoid circular dependencies between LogContext and Logger. * The `_parentContextRecord` field is set by the parent Logger after * `LogContext.child()` returns, establishing the context chain. */ export interface ChildLoggerShape { _parentContextRecord?: Record; /** Legacy field — no longer the canonical context source (F4.5.5 fix). */ context?: Record; } /** * Options passed to {@link createLogContext}. */ export interface ILogContextOptions { /** Initial context key-value pairs. */ initialContext?: Record; /** Factory for creating child logger instances. */ childLoggerFactory: ChildLoggerFactory; /** Initial OTel resource to merge into every record. */ initialResource?: Partial; /** * Returns the parent logger's merged context record at child-creation time. * Used by _getContextRecord() to build the context chain. * @internal */ getParentContextRecord?: () => Record; /** * The ALS instance to use for withContext scoping. * @internal */ alsInstance?: ALS; } /** * Result returned by {@link createLogContext}. */ export interface LogContext { /** * Current bound context snapshot (shallow copy — mutation does NOT affect * what subsequent log calls emit). */ getContext(): ContextSnapshot; /** * Runs `fn` within an AsyncLocalStorage scope where `bindings` are * merged into the context for all log calls inside `fn`. * * If `fn` is not provided (the old setter shape), this is a no-op * for backwards compatibility. Prefer `child()` for persistent binding * or `withContextAsync()` for async callbacks. * * @param bindings - Key-value pairs to attach for the duration of `fn` * @param fn - Optional synchronous function to run with the scoped bindings * @returns The return value of `fn`, or undefined if no fn provided */ withContext(bindings: Record, fn?: () => R): R | undefined; /** * Async variant of `withContext`. Runs `fn` within an AsyncLocalStorage * scope so bindings are available to all async log calls inside `fn`. * * @param bindings - Key-value pairs to attach for the duration of `fn` * @param fn - Async function to run with the scoped bindings * @returns The return value of `fn` */ withContextAsync(bindings: Record, fn: () => Promise): Promise; /** * Drops every key from the bound context. After this call, emitted * records no longer carry `attributes` until {@link withContext} or * {@link child} re-establishes one. * * @returns The same LogContext instance, now context-free */ clearContext(): this; /** * Updates the default OTel resource (service.name, version, env). * Persisted into every emitted record's `resource` field unless the * record itself overrides it. * * @param resource - Partial OTel resource to merge into the current one * @returns The same LogContext instance, for chaining */ setResource(resource: Partial): this; /** * Returns an immutable copy of this logger with the extra context bound. * Future calls on the child emit with the merged context, without * mutating the parent — the canonical MDC pattern. * * @param extra - Key-value pairs to attach (requestId, userId, ...) * @returns A new Logger with merged context */ child(extra: Record): ChildLoggerShape; /** Internal context record. Exposed for TransportRecord assembly. */ _getContextRecord(): Record; /** * Returns the base context WITHOUT the ALS overlay. * Used by Logger.child() to capture the parent context snapshot for * child logger creation (F4.5.5 fix). * @internal */ _getBaseContextRecord(): Record; /** Internal resource record. Exposed for TransportRecord assembly. */ _getResource(): Partial | undefined; /** * Returns the current AsyncLocalStorage store, if ALS is active. * @internal */ _getAlsStore(): Record | undefined; } type ALS = { run(store: Record, fn: () => R): R; getStore(): Record | undefined; }; /** * Creates a LogContext instance. * * @param options - Configuration options * @returns A LogContext instance */ export declare function createLogContext(options: ILogContextOptions): LogContext; export {}; //# sourceMappingURL=LogContext.d.ts.map