UNPKG

@dudousxd/nestjs-telescope

Version:

Laravel Telescope-style observability console for NestJS — core: watchers, recorder, correlation, SQLite store, headless API.

180 lines 8.06 kB
import { type OnApplicationShutdown, type OnModuleInit } from '@nestjs/common'; import { DiagnosisCoordinator } from '../ai/diagnosis-coordinator.js'; import type { AuthMode, ResolvedDashboardAuth } from '../auth/dashboard-auth-config.js'; import type { ResolvedCoreConfig } from '../config/options.js'; import { type ContextAccessor } from '../context/context-accessor.js'; import { TelescopeContext } from '../context/telescope-context.js'; import { type BatchOrigin, type RecordInput } from '../entry/entry.js'; import { ExtensionRegistry } from '../extension/registry.js'; import type { DashboardSection, Panel } from '../extension/types.js'; import { type RecorderSelfMetrics } from '../recorder/recorder.js'; import { EntryEvents } from '../sse/entry-events.js'; import type { StorageProvider } from '../storage/storage-provider.js'; import { type TelescopeModuleOptions } from './telescope.options.js'; import type { BatchHandle } from './watcher.js'; export interface TelescopeMeta { enabled: boolean; droppedCount: number; watchers: string[]; traceLink: string | null; /** * Whether the host wired a `traceContext` provider. When `false`, every entry's * `trace_id` is null, so the dashboard's Traces page is permanently empty — the * UI hides that nav item, mirroring how unregistered watchers hide their types. */ tracesEnabled: boolean; /** Resolved retention window from `prune`, or `null` when unbounded. */ retention: { afterMs: number; keepLast: number | null; } | null; /** * Whether on-demand pruning is available from the dashboard: requires both a * configured retention window (`prune`) AND mutations enabled (`authorizeAction` * present, the same default-deny gate the queue mutations use). When `false`, * the dashboard hides/disables the "Prune now" control. */ pruneEnabled: boolean; /** * Whether the query EXPLAIN feature is available (the host configured an * `explainQuery` hook). When `false`, the dashboard hides the "Explain" button. */ explainEnabled: boolean; /** Resolved per-type sample rates (0..1). Empty when no sampling configured. */ sampling: Record<string, number>; /** * Dashboard cookie-auth state for the AUTHENTICATED UI (e.g. showing a logout * button + the active modes). The UNauthenticated SPA learns the modes from * the 401 body of `GET /api/auth/me` instead — meta stays behind the gate. */ auth: { enabled: boolean; modes: AuthMode[]; }; /** * Webhook alerting state: whether `alerts` is configured and how many rules * are armed. The dashboard surfaces this as a read-only "Alerts: N rules" badge. */ alerts: { enabled: boolean; ruleCount: number; }; /** * AI exception-diagnosis state. `enabled` is true when the host configured a * `diagnoser`; the dashboard renders the "Diagnose with AI" button on exception * detail pages only then. `mode` mirrors the configured mode (`'on-demand'` by * default), purely informational for the UI. */ ai: { enabled: boolean; mode: 'auto' | 'on-demand' | null; }; /** * CPU flamegraph profiling state. `enabled` gates the dashboard's Profiles tab; * `sampleRate` is surfaced as a read-only badge. Both come straight from the * resolved config (off by default). */ profiling: { enabled: boolean; sampleRate: number; }; /** Entry types contributed by extensions (id/label/dot) — feeds the UI nav. */ entryTypes: { id: string; label: string; dot: string; }[]; /** Dashboards contributed by extensions — feeds the UI nav + routes + panel rendering. */ dashboards: { id: string; label: string; navGroup?: string; panels: Panel[]; sections?: DashboardSection[]; }[]; } /** * Self-observability snapshot for surfacing Telescope's OWN overhead. Combines * the Recorder's cheap self-metrics with whether capture is enabled and an * on-demand micro-benchmark of the per-capture cost (never measured on the live * `record()` path). */ export interface TelescopeHealth extends RecorderSelfMetrics { /** Whether capture is currently enabled (from config). */ enabled: boolean; /** Mean nanoseconds per capture, from an on-demand micro-benchmark. */ captureCostNanos: number; } export declare class TelescopeService implements OnModuleInit, OnApplicationShutdown { private readonly config; private readonly storage; private readonly options; private readonly dashboardAuth; private readonly extensions; private readonly contextAccessor; private readonly entryEvents; readonly context: TelescopeContext; private readonly recorder; private readonly logger; private flushTimer; private watcherTypes; /** Resolved (boot-validated) alerting config, or `null` when unconfigured. */ private readonly alerts; private alerter; /** AI exception-diagnosis coordinator, or `null` when `ai` is unconfigured. */ private readonly diagnosis; constructor(config: ResolvedCoreConfig, storage: StorageProvider, options: TelescopeModuleOptions, dashboardAuth?: ResolvedDashboardAuth | null, extensions?: ExtensionRegistry, contextAccessor?: ContextAccessor | undefined, entryEvents?: EntryEvents); /** * Record a developer debug dump into the Dumps tab. The value is redacted by * the Recorder and correlated to the active batch automatically. Prefer the * free `telescopeDump()` at call sites that don't already inject this service. */ dump(value: unknown, label?: string): void; /** Normalized mount segment (no leading/trailing slash). Default `'telescope'`. */ get path(): string; /** * Host-supplied hook to resolve the authenticated user from a raw request * (used by the request middleware). `undefined` when the host didn't supply * one — the middleware then falls back to reading `request.user`. */ get resolveUser(): ((request: unknown) => unknown) | undefined; onModuleInit(): Promise<void>; onApplicationShutdown(): Promise<void>; /** Register the set of active watcher type names (for meta). */ /** @internal Used by TelescopeWatcherRegistrar; not part of the public API. */ setWatchers(types: string[]): void; record(input: RecordInput): void; runInBatch<T>(origin: BatchOrigin, fn: () => Promise<T>): Promise<T>; /** * Open a batch and make it active for the current async execution (no * callback scope). Returns a handle; `end()` is a no-op today (the async * scope ends naturally) but is part of the contract for future cleanup. */ beginBatch(origin: BatchOrigin): BatchHandle; flush(): Promise<void>; /** * Pause capture (overload protection). While paused the Recorder drops new * `record()` calls; flushing continues so the buffer drains. Driven by the * OverloadGuard when event-loop lag crosses its threshold. */ pause(): void; /** Resume capture after a {@link pause}. */ resume(): void; /** Whether capture is currently paused by overload protection. */ get isPaused(): boolean; getMeta(): Promise<TelescopeMeta>; /** * AI exception-diagnosis coordinator, or `null` when `ai` is unconfigured. The * gated controller reads this to run the on-demand `diagnose` endpoint (and to * 404 when AI is off). */ get diagnosisCoordinator(): DiagnosisCoordinator | null; /** * Self-observability snapshot: the Recorder's cheap self-metrics plus an * on-demand micro-benchmark of the per-capture cost. The benchmark runs the * synchronous enrich path on a representative input WITHOUT enqueuing, so it * never pollutes the live buffer or taxes real records. */ getHealth(): TelescopeHealth; } //# sourceMappingURL=telescope.service.d.ts.map