Files
EvoBGP/web/src/lib/monitoring/postgres.ts
T
Denozordec 9efa3bbc8a
CI / changes (push) Successful in 8s
CI / commitlint (push) Has been skipped
CI / openapi (push) Has been skipped
CI / web (push) Successful in 30s
CI / go (push) Failing after 24s
CI / bird2 (push) Has been skipped
CI / release (push) Has been skipped
feat(db): enhance PostgreSQL statistics monitoring and error handling
Updated the PostgreSQL monitoring service to improve handling of `pg_stat_statements` availability. Introduced a new method to check if the extension is queryable and updated the response structure to include availability status and hints. Enhanced the documentation to clarify the requirements for enabling `pg_stat_statements`. Adjusted related components to reflect these changes, ensuring better user feedback in the monitoring interface.
2026-06-01 14:15:38 +07:00

119 lines
2.4 KiB
TypeScript

/** Types and helpers for PostgreSQL monitoring API. */
export const POSTGRES_POLL_MS = 20_000;
export const POSTGRES_SLOW_POLL_MS = 60_000;
export type PostgresOverview = {
collected_at: string;
connections: {
active: number;
idle: number;
total: number;
max_connections: number;
};
database: {
backends: number;
xact_commit: number;
xact_rollback: number;
deadlocks: number;
blks_hit: number;
blks_read: number;
cache_hit_pct: number;
};
database_size_bytes: number;
memory_settings: {
shared_buffers: string;
work_mem: string;
effective_cache_size: string;
};
replication: Array<{
client_addr?: string;
state: string;
sync_state?: string;
lag_ms?: number;
}>;
pg_stat_statements_enabled: boolean;
};
export type PostgresQueryRow = {
queryid?: number;
query: string;
calls: number;
total_exec_ms: number;
mean_exec_ms: number;
rows: number;
};
export type PostgresQueriesResponse = {
collected_at: string;
source: string;
items: PostgresQueryRow[];
statements_available?: boolean;
statements_hint?: string;
};
export type PostgresLockRow = {
locktype: string;
mode: string;
granted: boolean;
pid: number;
usename?: string;
state?: string;
query?: string;
blocked: boolean;
};
export type PostgresTableRow = {
relname: string;
total_bytes: number;
idx_scan: number;
seq_scan: number;
n_dead_tup: number;
bloat_ratio?: number;
last_autovacuum?: string;
};
export type PostgresRecommendation = {
severity: string;
code: string;
title: string;
detail: string;
refs?: string[];
};
export type PostgresRecommendationsResponse = {
collected_at: string;
items: PostgresRecommendation[];
};
export type PostgresMaintLog = {
id: string;
kind: string;
target_table?: string;
dry_run: boolean;
status: string;
error?: string;
created_at: string;
};
export type CorrelationResponse = {
window_minutes: number;
points: Array<{
timestamp: string;
pipeline_refresh_p99_ms?: number;
cache_hit_pct?: number;
}>;
};
export function formatBytes(n: number): string {
if (n >= 1 << 30) return `${(n / (1 << 30)).toFixed(1)} GiB`;
if (n >= 1 << 20) return `${(n / (1 << 20)).toFixed(1)} MiB`;
if (n >= 1 << 10) return `${(n / (1 << 10)).toFixed(1)} KiB`;
return `${n} B`;
}
export function connUsagePct(ov: PostgresOverview | null): number {
if (!ov?.connections.max_connections) return 0;
return Math.min(100, (ov.connections.total / ov.connections.max_connections) * 100);
}