Add opt-in slow SQL and database diagnostics
This commit is contained in:
@@ -10,6 +10,7 @@ import { backfillLeaderboard } from '../fleet/leaderboard-ingest.js';
|
||||
import { initializeFleetSettings } from './fleet-settings.js';
|
||||
import { migrateServerHistory } from './server-history.js';
|
||||
import { migrateNativeInstances } from '../backends/schema.js';
|
||||
import { timeStatement } from './slow-statements.js';
|
||||
|
||||
let _db: Database.Database | null = null;
|
||||
|
||||
@@ -414,11 +415,12 @@ export function db(): Database.Database {
|
||||
// Callers share statement options (e.g. raw()); use consistent options for
|
||||
// identical SQL and pass values to run/get/all rather than binding permanently.
|
||||
const statements = new Map<string, Database.Statement>();
|
||||
const slowMs = Number(process.env.EC_SLOW_SQL_MS ?? 0);
|
||||
const prepare = handle.prepare.bind(handle);
|
||||
handle.prepare = ((sql: string) => {
|
||||
let statement = statements.get(sql);
|
||||
if (!statement) {
|
||||
statement = prepare(sql);
|
||||
statement = timeStatement(prepare(sql), sql, slowMs);
|
||||
statements.set(sql, statement);
|
||||
}
|
||||
return statement;
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
import type Database from 'better-sqlite3';
|
||||
|
||||
/** Log query shapes, never bound values or SQL string literals. Disabled by default. */
|
||||
export function timeStatement(statement: Database.Statement, sql: string, thresholdMs: number): Database.Statement {
|
||||
if (!Number.isFinite(thresholdMs) || thresholdMs <= 0) return statement;
|
||||
const shape = sql.replace(/'(?:''|[^'])*'/g, '?').replace(/\s+/g, ' ').trim().slice(0, 200);
|
||||
for (const method of ['run', 'get', 'all'] as const) {
|
||||
const original = statement[method].bind(statement) as (...args: unknown[]) => unknown;
|
||||
Object.defineProperty(statement, method, { value: (...args: unknown[]) => {
|
||||
const started = performance.now();
|
||||
try { return original(...args); }
|
||||
finally {
|
||||
const ms = performance.now() - started;
|
||||
if (ms >= thresholdMs) console.warn('[sql]', { ms: Math.round(ms), method, sql: shape });
|
||||
}
|
||||
} });
|
||||
}
|
||||
return statement;
|
||||
}
|
||||
Reference in New Issue
Block a user