export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
/**
 * Structured tags for log entries.
 * Used to filter logs across addons for a specific device, integration, etc.
 */
export interface LogTags {
    /** Top-level cluster agent ID (e.g., 'hub', 'dev-agent-0'). Always the root node, never a child process. */
    readonly agentId?: string;
    /** Moleculer node ID (e.g., 'hub', 'hub/decoder-nodeav', 'agent-1') */
    readonly nodeId?: string;
    /**
     * OS process PID that actually emitted the entry. Hub services emit the
     * hub PID; forked Moleculer workers emit their own PID. The formatter
     * renders this in the `<pid>` column so operators can distinguish
     * hub-local addons from in-hub forked workers at a glance. Falls back
     * to the cached `process.pid` of the renderer when absent.
     */
    readonly pid?: number;
    /**
     * Device ID (numeric progressive id, e.g. 2). Always `number` —
     * string deviceIds are a pre-migration artifact and should not be
     * logged: if you have a stableId (external-only identifier), use
     * `meta.stableId` instead. The post-migration rule is: deviceId
     * everywhere internal is the numeric id allocated by the hub's
     * device-manager.
     */
    readonly deviceId?: number;
    /** Human-readable device name (e.g., 'Salone') */
    readonly deviceName?: string;
    /** Integration ID (e.g., 'int_0001') */
    readonly integrationId?: string;
    /** Addon ID (e.g., 'stream-broker', 'webrtc-adaptive') */
    readonly addonId?: string;
    /** Stream ID (e.g., '2/main') */
    readonly streamId?: string;
    /** Human-readable stream name — `main` / `mid` / `low` or a custom label. */
    readonly streamName?: string;
    /**
     * Session identifier when a log entry belongs to a particular session —
     * decoder session id, webrtc session id, rtsp session id, etc. Useful
     * to cross-reference entries emitted from different addons for the
     * same session. Intentionally untyped as a free-form string so
     * emitting code can reuse whatever handle the addon already has.
     */
    readonly sessionId?: string;
    /** Arbitrary extra tags */
    readonly [key: string]: string | number | undefined;
}
export interface LogEntry {
    timestamp: Date;
    level: LogLevel;
    /** Single free-form label (e.g. 'EventPersistence', 'rtsp', 'AddonRegistry').
     *  The addon/agent identity lives in `tags.addonId` / `tags.agentId`; `scope`
     *  is only for the sub-component label that appears before the message. */
    scope?: string;
    message: string;
    meta?: Record<string, unknown>;
    /** Structured tags for cross-cutting log filtering */
    tags?: LogTags;
}
export interface LogFilter {
    level?: LogLevel;
    since?: Date;
    until?: Date;
    limit?: number;
    /** Filter by tags — all specified tags must match (AND logic) */
    tags?: Partial<LogTags>;
}
export interface ILogDestination {
    initialize(): Promise<void>;
    shutdown(): Promise<void>;
    write(entry: LogEntry): void;
    query?(filter: LogFilter): Promise<readonly LogEntry[]>;
}
/**
 * Inline, per-call extras passed to every `IScopedLogger` method.
 *
 * - `tags`: cross-cutting structured identifiers — device, integration,
 *   stream — merged with any baseline tags already bound on the logger
 *   via `withTags()`. Renderable in fixed columns; queryable.
 * - `meta`: free-form operational context — error objects, counts,
 *   urls. Shown inline at the end of the log line as `{k=v}`.
 *
 * Pattern:
 *   logger.info('Probe failed', { tags: { deviceId: 7 }, meta: { err } })
 *   logger.warn('Retry scheduled', { meta: { attempt: 2 } })
 *   logger.info('Addon initialized')  // no extras
 *
 * `withTags()` survives only for binding a long-lived child logger
 * (e.g. `this.deviceLogger = ctx.logger.withTags({ deviceId })` in a
 * device constructor). Per-call tags always go in `extras.tags`.
 */
export interface LogExtras {
    readonly tags?: LogTags;
    readonly meta?: Record<string, unknown>;
}
export interface IScopedLogger {
    debug(message: string, extras?: LogExtras): void;
    info(message: string, extras?: LogExtras): void;
    warn(message: string, extras?: LogExtras): void;
    error(message: string, extras?: LogExtras): void;
    /** Create a new logger whose entries carry `scope = childScope`.
     *  Replaces (does not append to) any existing scope — scope is a
     *  single label, hierarchy is not modelled. Addon/agent identity
     *  lives in `tags.addonId`/`tags.agentId`, not in scope. */
    child(childScope: string): IScopedLogger;
    /** Create a new logger with additional tags (merged with existing tags) */
    withTags(tags: LogTags): IScopedLogger;
}
/** Factory that creates scoped loggers */
export type LoggerFactory = {
    createLogger(scope?: string): IScopedLogger;
};
//# sourceMappingURL=logging.d.ts.map