import { type Context } from '@opentelemetry/api';
export declare const DEFAULT_WARN_THRESHOLD = 100;
export declare const DEFAULT_ERROR_THRESHOLD = 500;
export declare const DEFAULT_TICK_INTERVAL = 20;
export declare const ENV_WARN_THRESHOLD_MS = "LIVEKIT_AGENTS_LOOP_BLOCK_WARN_MS";
export declare const ENV_ERROR_THRESHOLD_MS = "LIVEKIT_AGENTS_LOOP_BLOCK_ERROR_MS";
export declare const MAX_SPANS_PER_MINUTE = 6;
export declare const MAX_LOGS_PER_MINUTE = 5;
export declare const SPAN_NAME = "event_loop_blocked";
export type LoopMonitorSeverity = 'warning' | 'error';
/**
 * What kept the loop from running: `code` is synchronous work on the loop thread, `host` is the
 * whole process not being scheduled (CPU contention on the host, a container CPU quota).
 */
export type LoopStallCause = 'code' | 'host';
/** What a report's `cpuTime` covers: the event-loop thread, or the whole process on older Node. */
export type LoopCpuScope = 'thread' | 'process';
export interface BlockedReport {
    /** Heartbeat lag in milliseconds. */
    duration: number;
    /** Approximate wall-clock start in milliseconds since the Unix epoch. */
    startedAt: number;
    warnThreshold: number;
    severity: LoopMonitorSeverity;
    /**
     * Garbage-collection pause time observed during the stall, in milliseconds. Node delivers GC
     * entries to observers a couple of loop turns after the fact, so a report is emitted one
     * heartbeat after its stall to include them.
     */
    gcTime: number;
    /**
     * CPU consumed during the stall, in milliseconds. Scoped to the event-loop thread where Node
     * offers `process.threadCpuUsage()` (22.15 / 23.9 and later); process-wide before that, which
     * also counts the libuv pool and the native media threads and can exceed the stall duration.
     */
    cpuTime: number;
    /** What `cpuTime` covers. */
    cpuScope: LoopCpuScope;
    /** How late the watchdog thread woke during the stall, in milliseconds. 0 without a watchdog. */
    watchdogGap: number;
    /**
     * `host` when the whole process stopped running (host CPU contention, a container CPU quota, a
     * suspended machine) rather than code blocking the loop. Without a watchdog every stall is
     * attributed to `code`.
     */
    cause: LoopStallCause;
}
export declare class LoopMonitorThresholds {
    readonly warn: number;
    readonly error: number;
    constructor(warn: number, error: number);
    static fromEnv(env?: NodeJS.ProcessEnv): LoopMonitorThresholds | undefined;
}
export interface EventLoopMonitorOptions {
    warnThreshold?: number;
    errorThreshold?: number;
    tickInterval?: number;
    name?: string;
    emitSpans?: boolean;
    /**
     * Run a watchdog worker thread whose own late wake-ups reveal when the whole process was not
     * scheduled, so host contention is reported as such. Without it every stall is attributed to
     * code on the loop. Default true.
     */
    watchdog?: boolean;
}
export type ReportContextRunner = <T>(fn: () => T) => T;
/** Detect synchronous work that prevents the Node event loop from servicing timers. */
export declare class EventLoopMonitor {
    #private;
    readonly warnThreshold: number;
    readonly errorThreshold: number;
    readonly tickInterval: number;
    private cpuScope;
    /** Observe every report that produced a span or a log, without going through OpenTelemetry. */
    onReport?: (report: BlockedReport) => void;
    constructor(options?: EventLoopMonitorOptions);
    /** Whether the watchdog thread is running, i.e. host contention can be told apart from code. */
    get watchdogActive(): boolean;
    /** Set the OTel parent and, optionally, a runner that restores job AsyncLocalStorage. */
    setReportContext(context: Context | undefined, runner?: ReportContextRunner): void;
    /** Start the heartbeat. Idempotent. */
    start(): void;
    /** Stop the heartbeat and the watchdog. Idempotent. */
    stop(): void;
    private buildReport;
    private report;
}
export interface StartMonitoringOptions {
    thresholds?: LoopMonitorThresholds;
    name?: string;
    emitSpans?: boolean;
    watchdog?: boolean;
}
/** Start the process event-loop monitor, or return undefined if disabled/already running. */
export declare function startMonitoring(options?: StartMonitoringOptions): EventLoopMonitor | undefined;
export declare function stopMonitoring(monitor?: EventLoopMonitor): void;
export declare function getMonitor(): EventLoopMonitor | undefined;
//# sourceMappingURL=loop_monitor.d.ts.map