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
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.
119 lines
2.4 KiB
TypeScript
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);
|
|
}
|