export type LogValue = string | number | boolean | Date | null | undefined | { [key: string]: LogValue; } | LogValue[]; /** Log tags to attach to logs */ export type LogTags = { [key: string]: LogValue; }; /** Top-level fields to add to the log */ export type LogFields = LogTags; export type LogLevel = 'info' | 'log' | 'warn' | 'error' | 'debug'; export type ConsoleLog = { message?: string | Error | undefined; level: LogLevel; time: string; tags?: LogTags; }; type LogFn = (...msgs: any[]) => void; type LogLevelFns = { [K in LogLevel]: LogFn; }; /** Context stored in AsyncLocalStorage containing tags, log level, and method tracking */ export type LogContext = { tags: LogTags; logLevel?: LogLevel; method?: string; rootMethod?: string; }; export declare const als: any; export interface WorkersLoggerOptions { /** * Tags to add to all logs (overriding existing tags). * Only applies to this instance (and sub-instances) of the logger. */ tags?: LogTags; /** * Fields to apply to all logs in the current WorkersLogger. * Does not apply globally - only the logger instance * (or child instance) that logger.withFields() was called. */ fields?: LogFields; /** * Minimum log level for logger, inclusive. Logging levels below the minimum set are ignored. * * Defaults to the lowest level: `debug`. */ minimumLogLevel?: LogLevel; /** * Enable debug mode to show internal warning messages when AsyncLocalStorage context is missing. * When false (default), these warnings are suppressed to reduce noise in production. * * @default false */ debug?: boolean; } /** * Similar to WorkersLogger but allows setting * metadata for the returned logger instance rather * than applying globally. * * @example * * Create a typed logger * * ```ts * type MyTags = { * build_id: number * build_uuid: string * } * const logger = new WorkersLogger() * logger.setTags({ * build_id: 123 // auto-completes! * }) * ``` */ export declare class WorkersLogger implements LogLevelFns { private ctx; private constructorLogLevel?; private instanceLogLevel?; private debugMode; constructor(opts?: WorkersLoggerOptions); /** * Returns a new context logger where all logs will have these * tags added (overwriting conflicting tags.) Only this instance * (or sub-instances) will contain these tags. */ withTags(tags: Partial): WorkersLogger>; /** * Returns a new context logger where all logs will have these * fields added (overwriting conflicting fields.) Only this instance * (or sub-instances) will contain these fields. * * Fields are similar to tags, but are set at the top-level of the logger. * Most of the time, tags are preferred. But there are cases where * setting top-level fields is preferred (such as setting `timestamp`.) */ withFields(fields: Partial): WorkersLogger>; private getFields; /** * Log a debug warning message if debug mode is enabled. * Used for internal warnings about missing AsyncLocalStorage context. */ private logDebugWarning; /** * Get global tags stored in async context. Excludes * tags set on this instance using withTags()) */ private getParentTags; /** * Get all tags (including global + context tags) */ getTags(): Partial; /** Set tags used for all logs in this async context * and any child context (unless overridden using withTags) */ setTags(tags: Partial): void; /** Set minimum log level for all loggers in the current AsyncLocalStorage context */ setLogLevel(level: LogLevel): void; /** Create a new logger instance with the specified minimum log level */ withLogLevel(level: LogLevel): WorkersLogger; info: (...msgs: any[]) => void; log: (...msgs: any[]) => void; warn: (...msgs: any[]) => void; error: (...msgs: any[]) => void; debug: (...msgs: any[]) => void; private write; } export declare function stringifyMessages(...msgs: any[]): string; export declare function stringifyMessage(msg: any): string; interface WithLogTagsOptions { /** The source of the logs (e.g. the application name) */ source?: string; /** Tags to add to all logs in this async context */ tags?: Partial; } /** * Run a function with logging metadata attached to all logs. * Nested calls will inherit all metadata on the parent at the * time it was created. Future updates to the parent will not be * propagated to the child. * * @param opts.source Tag for source of these logs (e.g. the Worker name.) * @param opts.tags Additional tags to set * @param fn Function to run within the async context that * will allow using the WorkersLogger * * @see WithLogTags decorator for simpler use in classes */ export declare function withLogTags(opts: WithLogTagsOptions>, fn: () => R): R; /** Type alias for the actual decorator function returned */ type MethodDecoratorFn = (target: any, propertyKey: string | symbol, descriptor: PropertyDescriptor) => PropertyDescriptor | void; /** Tags for the WithLogTags decorator */ type WithLogTagsDecoratorTags = { /** * Explicit source for logs. If omitted, the class name containing the * decorated method will automatically be used as the source. * @default Class name */ source?: string; } & Partial; /** * Decorator: Wraps a class method with logging context. * Automatically uses the Class Name as the log source. * * **IMPORTANT**: Requires `"experimentalDecorators": true` to be added to tsconfig.json * * Automatically adds: * - `$logger.method`: The name of the currently executing decorated method. * - `$logger.rootMethod`: The name of the first decorated method entered in the async context. * Nested calls will inherit metadata. * * @example * * Create class to handle requests with log tags added * * ```ts * // ... imports and logger setup ... * class MyService { * // remove the \ before the @ (this is a workaround for VS Code docstring issues) * \@WithLogTags() // $logger.method: 'handleRequest' will be added * async handleRequest(requestId: string, request: Request) { * logger.setTags({ requestId }) * logger.info('Handling request') // -> tags: { source: 'MyService', $logger: { method: 'handleRequest', rootMethod: 'handleRequest' }, requestId: '...' } * await this.processRequest(request) * logger.info('Request handled') * } * * // $logger.method: 'processRequest' will be added * // and $logger.rootMethod will remain 'handleRequest' * \@WithLogTags() * async processRequest(request: Request) { * // Inherits requestId from handleRequest's context * // Tags here: { source: 'MyService', $logger: { method: 'processRequest', rootMethod: 'handleRequest' }, requestId: '...' } * logger.debug('Processing request...') * // ... * logger.debug('Request processed') * } * } * ``` */ export declare function WithLogTags(): MethodDecoratorFn; /** * Decorator: Wraps a class method with logging context. * Uses the provided string as the log source. * * **IMPORTANT**: Requires `"experimentalDecorators": true` to be added to tsconfig.json * * Automatically adds: * - `$logger.method`: The name of the currently executing decorated method. * - `$logger.rootMethod`: The name of the first decorated method entered in the async context. * Nested calls will inherit metadata. * * @param source Explicit source for logs. * * @example * * Create class to handle requests with log tags added * * ```ts * // ... imports and logger setup ... * class MyService { * // remove the \ before the @ (this is a workaround for VS Code docstring issues) * \@WithLogTags('MyService') // $logger.method: 'handleRequest' will be added * async handleRequest(requestId: string, request: Request) { * logger.setTags({ requestId }) * logger.info('Handling request') // -> tags: { source: 'MyService', $logger: { method: 'handleRequest', rootMethod: 'handleRequest' }, requestId: '...' } * await this.processRequest(request) * logger.info('Request handled') * } * * // $logger.method: 'processRequest' will be added * // and $logger.rootMethod will remain 'handleRequest' * \@WithLogTags('MyServiceHelper') * async processRequest(request: Request) { * // Inherits requestId from handleRequest's context * Tags here: { source: 'MyServiceHelper', $logger: { method: 'processRequest', rootMethod: 'handleRequest' }, requestId: '...' } * logger.debug('Processing request...') * // ... * logger.debug('Request processed') * } * } * ``` */ export declare function WithLogTags(source: string): MethodDecoratorFn; /** * Decorator: Wraps a class method with logging context. * Uses options to configure source (falls back to Class Name) and initial tags. * * **IMPORTANT**: Requires `"experimentalDecorators": true` to be added to tsconfig.json * * Automatically adds: * - `$logger.method`: The name of the currently executing decorated method. * - `$logger.rootMethod`: The name of the first decorated method entered in the async context. * Nested calls will inherit metadata. * * @param tags Additional tags to set for this context. User-provided tags * will override existing tags but NOT the automatically added logger tags. * @param tags.source Tag for the source of these logs (e.g., the Worker name or class name). Falls back to Class Name * * @example * * Create class to handle requests with log tags added * * ```ts * // ... imports and logger setup ... * class MyService { * // remove the \ before the @ (this is a workaround for VS Code docstring issues) * \@WithLogTags({ source: 'MyService' }) // $logger.method: 'handleRequest' will be added * async handleRequest(requestId: string, request: Request) { * logger.setTags({ requestId }) * logger.info('Handling request') // -> tags: { source: 'MyService', $logger: { method: 'handleRequest', rootMethod: 'handleRequest' }, requestId: '...' } * await this.processRequest(request) * logger.info('Request handled') * } * * // $logger.method: 'processRequest' will be added * // and $logger.rootMethod will remain 'handleRequest' * \@WithLogTags({ foo: 'bar' }) * async processRequest(request: Request) { * // Inherits requestId from handleRequest's context * // Tags here: { source: 'MyService', foo: 'bar', $logger: { method: 'processRequest', rootMethod: 'handleRequest' }, requestId: '...' } * logger.debug('Processing request...') * // ... * logger.debug('Request processed') * } * } * ``` */ export declare function WithLogTags(tags: WithLogTagsDecoratorTags>): MethodDecoratorFn; export {}; //# sourceMappingURL=logger.d.ts.map