import { DisposableSymbols } from '@whatwg-node/disposablestack';

type MaybeLazy<T> = T | (() => T);
type AttributeValue = any;
type Attributes = AttributeValue[] | {
    [key: string | number]: AttributeValue;
};

declare function jsonStringify(val: unknown, pretty?: boolean): string;
interface LogWriter {
    write(level: LogLevel, attrs: Attributes | null | undefined, msg: string | null | undefined): void | Promise<void>;
    flush?(): void | Promise<void>;
}

type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error';
type RedactOptions = string[] | {
    paths: string[];
    censor?: string | ((value: unknown, path: string[]) => unknown) | undefined;
    remove?: boolean;
};
interface LoggerOptions {
    /**
     * The minimum log level to log.
     *
     * Providing `false` will disable all logging.
     *
     * Provided function will always be invoked to get the current log level.
     *
     * @default env.LOG_LEVEL || env.DEBUG ? 'debug' : 'info'
     */
    level?: MaybeLazy<LogLevel | false>;
    /** A prefix to include in every log's message. */
    prefix?: string;
    /**
     * The attributes to include in all logs. Is mainly used to pass the parent
     * attributes when creating {@link Logger.child child loggers}.
     */
    attrs?: Attributes;
    /**
     * The log writers to use when writing logs.
     *
     * @default env.LOG_JSON ? [new JSONLogWriter()] : [new ConsoleLogWriter()]
     */
    writers?: [LogWriter, ...LogWriter[]];
    /**
     * Paths that should have their values redacted from any log output.
     *
     * Can be an array of path strings or an object with `paths`, `censor`, and `remove` options.
     *
     * Note that using the `remove` option will set the value at the specified paths to `undefined`
     * instead of a deleting the key. This is the more performant option.
     *
     * @default undefined
     */
    redact?: RedactOptions;
}
declare class Logger implements AsyncDisposable {
    #private;
    constructor(opts?: LoggerOptions);
    /** The prefix that's prepended to each log message. */
    get prefix(): string | undefined;
    /**
     * The attributes that are added to each log. If the log itself contains
     * attributes with keys existing in {@link attrs}, the log's attributes will
     * override.
     */
    get attrs(): Attributes | undefined;
    /** The current {@link LogLevel} of the logger. You can change the level using the {@link setLevel} method. */
    get level(): false | LogLevel;
    /**
     * Sets the new {@link LogLevel} of the logger. All subsequent logs, and {@link child child loggers} whose
     * level did not change, will respect the new level.
     */
    setLevel(level: MaybeLazy<LogLevel | false>): void;
    write(level: LogLevel, attrs: Attributes | null | undefined, msg: string | null | undefined): void;
    flush(): Promise<void> | undefined;
    [DisposableSymbols.asyncDispose](): Promise<void | undefined>;
    child(prefix: string): Logger;
    child(attrs: Attributes, prefix?: string): Logger;
    log(level: LogLevel): void;
    log(level: LogLevel, attrs: MaybeLazy<Attributes>): void;
    log(level: LogLevel, msg: string, ...interpol: unknown[]): void;
    log(level: LogLevel, attrs: MaybeLazy<Attributes>, msg: string, ...interpol: unknown[]): void;
    trace(): void;
    trace(attrs: MaybeLazy<Attributes>): void;
    trace(msg: string, ...interpol: unknown[]): void;
    trace(attrs: MaybeLazy<Attributes>, msg: string, ...interpol: unknown[]): void;
    debug(): void;
    debug(attrs: MaybeLazy<Attributes>): void;
    debug(msg: string, ...interpol: unknown[]): void;
    debug(attrs: MaybeLazy<Attributes>, msg: string, ...interpol: unknown[]): void;
    info(): void;
    info(attrs: MaybeLazy<Attributes>): void;
    info(msg: string, ...interpol: unknown[]): void;
    info(attrs: MaybeLazy<Attributes>, msg: string, ...interpol: unknown[]): void;
    warn(): void;
    warn(attrs: MaybeLazy<Attributes>): void;
    warn(msg: string, ...interpol: unknown[]): void;
    warn(attrs: MaybeLazy<Attributes>, msg: string, ...interpol: unknown[]): void;
    error(): void;
    error(attrs: MaybeLazy<Attributes>): void;
    error(msg: string, ...interpol: unknown[]): void;
    error(attrs: MaybeLazy<Attributes>, msg: string, ...interpol: unknown[]): void;
}

export { type AttributeValue as A, type LogLevel as L, type MaybeLazy as M, type RedactOptions as R, type Attributes as a, type LogWriter as b, Logger as c, type LoggerOptions as d, jsonStringify as j };
