@indiekitai/pg-dash 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -126,7 +126,7 @@ Options:
126
126
  -i, --interval <sec> Collection interval (default: 30)
127
127
  --threshold <score> Score threshold for check command (default: 70)
128
128
  -f, --format <fmt> Output format: text|json (default: text)
129
- --query-stats-interval <sec> Query stats snapshot interval (default: 300)
129
+ --query-stats-interval <min> Query stats snapshot interval in minutes (default: 5)
130
130
  --slack-webhook <url> Slack webhook URL for alert notifications
131
131
  --discord-webhook <url> Discord webhook URL for alert notifications
132
132
  -v, --version Show version
package/README.zh-CN.md CHANGED
@@ -126,7 +126,7 @@ Options:
126
126
  -i, --interval <sec> 采集间隔(默认:30)
127
127
  --threshold <score> check 命令的分数阈值(默认:70)
128
128
  -f, --format <fmt> 输出格式:text|json(默认:text)
129
- --query-stats-interval <sec> 查询统计快照间隔(默认:300
129
+ --query-stats-interval <min> 查询统计快照间隔,单位分钟(默认:5
130
130
  --slack-webhook <url> Slack webhook URL,用于告警通知
131
131
  --discord-webhook <url> Discord webhook URL,用于告警通知
132
132
  -v, --version 显示版本
package/dist/cli.js CHANGED
@@ -281,9 +281,9 @@ SHOW shared_buffers;`,
281
281
  extract(epoch from now() - state_change)::int AS idle_seconds
282
282
  FROM pg_stat_activity
283
283
  WHERE state IN ('idle', 'idle in transaction')
284
- AND now() - state_change > interval '${longQueryThreshold} minutes'
284
+ AND now() - state_change > $1 * interval '1 minute'
285
285
  AND pid != pg_backend_pid()
286
- `);
286
+ `, [longQueryThreshold]);
287
287
  for (const row of r.rows) {
288
288
  const isIdleTx = row.state === "idle in transaction";
289
289
  issues.push({
@@ -858,8 +858,10 @@ var TimeseriesStore = class {
858
858
  };
859
859
 
860
860
  // src/server/collector.ts
861
- var Collector = class {
861
+ import { EventEmitter } from "events";
862
+ var Collector = class extends EventEmitter {
862
863
  constructor(pool, store, intervalMs = 3e4) {
864
+ super();
863
865
  this.pool = pool;
864
866
  this.store = store;
865
867
  this.intervalMs = intervalMs;
@@ -979,6 +981,7 @@ var Collector = class {
979
981
  this.store.insertMany(points);
980
982
  }
981
983
  this.lastSnapshot = snapshot;
984
+ this.emit("collected", snapshot);
982
985
  return snapshot;
983
986
  }
984
987
  };
@@ -2017,6 +2020,7 @@ function registerExplainRoutes(app, pool) {
2017
2020
  const query = body?.query?.trim();
2018
2021
  if (!query) return c.json({ error: "Missing query" }, 400);
2019
2022
  if (DDL_PATTERN.test(query)) return c.json({ error: "DDL statements are not allowed" }, 400);
2023
+ if (!/^\s*SELECT\b/i.test(query)) return c.json({ error: "Only SELECT queries can be explained for safety. DELETE/UPDATE/INSERT are blocked." }, 400);
2020
2024
  const client = await pool.connect();
2021
2025
  try {
2022
2026
  await client.query("SET statement_timeout = '30s'");
@@ -2599,9 +2603,7 @@ async function startServer(opts) {
2599
2603
  ws.on("error", () => clients.delete(ws));
2600
2604
  });
2601
2605
  let collectCycleCount = 0;
2602
- const origCollect = collector.collect.bind(collector);
2603
- collector.collect = async () => {
2604
- const snapshot = await origCollect();
2606
+ collector.on("collected", async (snapshot) => {
2605
2607
  if (clients.size > 0 && Object.keys(snapshot).length > 0) {
2606
2608
  const metricsMsg = JSON.stringify({ type: "metrics", data: snapshot });
2607
2609
  let activityData = [];
@@ -2700,8 +2702,7 @@ async function startServer(opts) {
2700
2702
  console.error("[alerts] Error checking alerts:", err.message);
2701
2703
  }
2702
2704
  }
2703
- return snapshot;
2704
- };
2705
+ });
2705
2706
  const bindAddr = opts.bind || "127.0.0.1";
2706
2707
  server.listen(opts.port, bindAddr, async () => {
2707
2708
  console.log(`