@patricio0312rev/skillset 0.1.0
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/CHANGELOG.md +29 -0
- package/LICENSE +21 -0
- package/README.md +176 -0
- package/bin/cli.js +37 -0
- package/package.json +55 -0
- package/src/commands/init.js +301 -0
- package/src/index.js +168 -0
- package/src/lib/config.js +200 -0
- package/src/lib/generator.js +166 -0
- package/src/utils/display.js +95 -0
- package/src/utils/readme.js +196 -0
- package/src/utils/tool-specific.js +233 -0
- package/templates/ai-engineering/agent-orchestration-planner/ SKILL.md +266 -0
- package/templates/ai-engineering/cost-latency-optimizer/ SKILL.md +270 -0
- package/templates/ai-engineering/doc-to-vector-dataset-generator/ SKILL.md +239 -0
- package/templates/ai-engineering/evaluation-harness/ SKILL.md +219 -0
- package/templates/ai-engineering/guardrails-safety-filter-builder/ SKILL.md +226 -0
- package/templates/ai-engineering/llm-debugger/ SKILL.md +283 -0
- package/templates/ai-engineering/prompt-regression-tester/ SKILL.md +216 -0
- package/templates/ai-engineering/prompt-template-builder/ SKILL.md +393 -0
- package/templates/ai-engineering/rag-pipeline-builder/ SKILL.md +244 -0
- package/templates/ai-engineering/tool-function-schema-designer/ SKILL.md +219 -0
- package/templates/architecture/adr-writer/ SKILL.md +250 -0
- package/templates/architecture/api-versioning-deprecation-planner/ SKILL.md +331 -0
- package/templates/architecture/domain-model-boundaries-mapper/ SKILL.md +300 -0
- package/templates/architecture/migration-planner/ SKILL.md +376 -0
- package/templates/architecture/performance-budget-setter/ SKILL.md +318 -0
- package/templates/architecture/reliability-strategy-builder/ SKILL.md +286 -0
- package/templates/architecture/rfc-generator/ SKILL.md +362 -0
- package/templates/architecture/scalability-playbook/ SKILL.md +279 -0
- package/templates/architecture/system-design-generator/ SKILL.md +339 -0
- package/templates/architecture/tech-debt-prioritizer/ SKILL.md +329 -0
- package/templates/backend/api-contract-normalizer/ SKILL.md +487 -0
- package/templates/backend/api-endpoint-generator/ SKILL.md +415 -0
- package/templates/backend/auth-module-builder/ SKILL.md +99 -0
- package/templates/backend/background-jobs-designer/ SKILL.md +166 -0
- package/templates/backend/caching-strategist/ SKILL.md +190 -0
- package/templates/backend/error-handling-standardizer/ SKILL.md +174 -0
- package/templates/backend/rate-limiting-abuse-protection/ SKILL.md +147 -0
- package/templates/backend/rbac-permissions-builder/ SKILL.md +158 -0
- package/templates/backend/service-layer-extractor/ SKILL.md +269 -0
- package/templates/backend/webhook-receiver-hardener/ SKILL.md +211 -0
- package/templates/ci-cd/artifact-sbom-publisher/ SKILL.md +236 -0
- package/templates/ci-cd/caching-strategy-optimizer/ SKILL.md +195 -0
- package/templates/ci-cd/deployment-checklist-generator/ SKILL.md +381 -0
- package/templates/ci-cd/github-actions-pipeline-creator/ SKILL.md +348 -0
- package/templates/ci-cd/monorepo-ci-optimizer/ SKILL.md +298 -0
- package/templates/ci-cd/preview-environments-builder/ SKILL.md +187 -0
- package/templates/ci-cd/quality-gates-enforcer/ SKILL.md +342 -0
- package/templates/ci-cd/release-automation-builder/ SKILL.md +281 -0
- package/templates/ci-cd/rollback-workflow-builder/ SKILL.md +372 -0
- package/templates/ci-cd/secrets-env-manager/ SKILL.md +242 -0
- package/templates/db-management/backup-restore-runbook-generator/ SKILL.md +505 -0
- package/templates/db-management/data-integrity-auditor/ SKILL.md +505 -0
- package/templates/db-management/data-retention-archiving-planner/ SKILL.md +430 -0
- package/templates/db-management/data-seeding-fixtures-builder/ SKILL.md +375 -0
- package/templates/db-management/db-performance-watchlist/ SKILL.md +425 -0
- package/templates/db-management/etl-sync-job-builder/ SKILL.md +457 -0
- package/templates/db-management/multi-tenant-safety-checker/ SKILL.md +398 -0
- package/templates/db-management/prisma-migration-assistant/ SKILL.md +379 -0
- package/templates/db-management/schema-consistency-checker/ SKILL.md +440 -0
- package/templates/db-management/sql-query-optimizer/ SKILL.md +324 -0
- package/templates/foundation/changelog-writer/ SKILL.md +431 -0
- package/templates/foundation/code-formatter-installer/ SKILL.md +320 -0
- package/templates/foundation/codebase-summarizer/ SKILL.md +360 -0
- package/templates/foundation/dependency-doctor/ SKILL.md +163 -0
- package/templates/foundation/dev-environment-bootstrapper/ SKILL.md +259 -0
- package/templates/foundation/dev-onboarding-builder/ SKILL.md +556 -0
- package/templates/foundation/docs-starter-kit/ SKILL.md +574 -0
- package/templates/foundation/explaining-code/SKILL.md +13 -0
- package/templates/foundation/git-hygiene-enforcer/ SKILL.md +455 -0
- package/templates/foundation/project-scaffolder/ SKILL.md +65 -0
- package/templates/foundation/project-scaffolder/references/templates.md +126 -0
- package/templates/foundation/repo-structure-linter/ SKILL.md +0 -0
- package/templates/foundation/repo-structure-linter/references/conventions.md +98 -0
- package/templates/frontend/animation-micro-interaction-pack/ SKILL.md +41 -0
- package/templates/frontend/component-scaffold-generator/ SKILL.md +562 -0
- package/templates/frontend/design-to-component-translator/ SKILL.md +547 -0
- package/templates/frontend/form-wizard-builder/ SKILL.md +553 -0
- package/templates/frontend/frontend-refactor-planner/ SKILL.md +37 -0
- package/templates/frontend/i18n-frontend-implementer/ SKILL.md +44 -0
- package/templates/frontend/modal-drawer-system/ SKILL.md +377 -0
- package/templates/frontend/page-layout-builder/ SKILL.md +630 -0
- package/templates/frontend/state-ux-flow-builder/ SKILL.md +23 -0
- package/templates/frontend/table-builder/ SKILL.md +350 -0
- package/templates/performance/alerting-dashboard-builder/ SKILL.md +162 -0
- package/templates/performance/backend-latency-profiler-helper/ SKILL.md +108 -0
- package/templates/performance/caching-cdn-strategy-planner/ SKILL.md +150 -0
- package/templates/performance/capacity-planning-helper/ SKILL.md +242 -0
- package/templates/performance/core-web-vitals-tuner/ SKILL.md +126 -0
- package/templates/performance/incident-runbook-generator/ SKILL.md +162 -0
- package/templates/performance/load-test-scenario-builder/ SKILL.md +256 -0
- package/templates/performance/observability-setup/ SKILL.md +232 -0
- package/templates/performance/postmortem-writer/ SKILL.md +203 -0
- package/templates/performance/structured-logging-standardizer/ SKILL.md +122 -0
- package/templates/security/auth-security-reviewer/ SKILL.md +428 -0
- package/templates/security/dependency-vulnerability-triage/ SKILL.md +495 -0
- package/templates/security/input-validation-sanitization-auditor/ SKILL.md +76 -0
- package/templates/security/pii-redaction-logging-policy-builder/ SKILL.md +65 -0
- package/templates/security/rbac-policy-tester/ SKILL.md +80 -0
- package/templates/security/secrets-scanner/ SKILL.md +462 -0
- package/templates/security/secure-headers-csp-builder/ SKILL.md +404 -0
- package/templates/security/security-incident-playbook-generator/ SKILL.md +76 -0
- package/templates/security/security-pr-checklist-skill/ SKILL.md +62 -0
- package/templates/security/threat-model-generator/ SKILL.md +394 -0
- package/templates/testing/contract-testing-builder/ SKILL.md +492 -0
- package/templates/testing/coverage-strategist/ SKILL.md +436 -0
- package/templates/testing/e2e-test-builder/ SKILL.md +382 -0
- package/templates/testing/flaky-test-detective/ SKILL.md +416 -0
- package/templates/testing/integration-test-builder/ SKILL.md +525 -0
- package/templates/testing/mocking-assistant/ SKILL.md +383 -0
- package/templates/testing/snapshot-test-refactorer/ SKILL.md +375 -0
- package/templates/testing/test-data-factory-builder/ SKILL.md +449 -0
- package/templates/testing/test-reporting-triage-skill/ SKILL.md +469 -0
- package/templates/testing/unit-test-generator/ SKILL.md +548 -0
|
@@ -0,0 +1,425 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: db-performance-watchlist
|
|
3
|
+
description: Defines database performance monitoring strategy with slow query detection, resource usage alerts, query execution thresholds, and automated alerting. Use for "database monitoring", "performance alerts", "slow queries", or "DB metrics".
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# DB Performance Watchlist
|
|
7
|
+
|
|
8
|
+
Monitor database performance and prevent regressions.
|
|
9
|
+
|
|
10
|
+
## Key Performance Metrics
|
|
11
|
+
|
|
12
|
+
```typescript
|
|
13
|
+
// performance-metrics.ts
|
|
14
|
+
export interface DBMetrics {
|
|
15
|
+
// Query Performance
|
|
16
|
+
slowQueries: {
|
|
17
|
+
threshold: number; // ms
|
|
18
|
+
count: number;
|
|
19
|
+
queries: SlowQuery[];
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
// Connection Pool
|
|
23
|
+
connections: {
|
|
24
|
+
active: number;
|
|
25
|
+
idle: number;
|
|
26
|
+
total: number;
|
|
27
|
+
maxConnections: number;
|
|
28
|
+
utilizationPercent: number;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
// Resource Usage
|
|
32
|
+
resources: {
|
|
33
|
+
cpuPercent: number;
|
|
34
|
+
memoryPercent: number;
|
|
35
|
+
diskUsagePercent: number;
|
|
36
|
+
iops: number;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
// Query Statistics
|
|
40
|
+
queryStats: {
|
|
41
|
+
selectsPerSecond: number;
|
|
42
|
+
insertsPerSecond: number;
|
|
43
|
+
updatesPerSecond: number;
|
|
44
|
+
deletesPerSecond: number;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
// Cache Performance
|
|
48
|
+
cache: {
|
|
49
|
+
hitRate: number; // %
|
|
50
|
+
size: number; // MB
|
|
51
|
+
evictions: number;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
// Index Usage
|
|
55
|
+
indexes: {
|
|
56
|
+
unusedIndexes: string[];
|
|
57
|
+
missingIndexes: string[];
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
interface SlowQuery {
|
|
62
|
+
query: string;
|
|
63
|
+
duration: number;
|
|
64
|
+
calls: number;
|
|
65
|
+
avgDuration: number;
|
|
66
|
+
table: string;
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Slow Query Detection
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
// scripts/detect-slow-queries.ts
|
|
74
|
+
async function detectSlowQueries(thresholdMs: number = 100) {
|
|
75
|
+
// Enable slow query logging (PostgreSQL)
|
|
76
|
+
await prisma.$executeRaw`
|
|
77
|
+
ALTER DATABASE mydb
|
|
78
|
+
SET log_min_duration_statement = ${thresholdMs};
|
|
79
|
+
`;
|
|
80
|
+
|
|
81
|
+
// Query pg_stat_statements for slow queries
|
|
82
|
+
const slowQueries = await prisma.$queryRaw<SlowQuery[]>`
|
|
83
|
+
SELECT
|
|
84
|
+
query,
|
|
85
|
+
calls,
|
|
86
|
+
total_exec_time / 1000 as total_time_ms,
|
|
87
|
+
mean_exec_time / 1000 as avg_time_ms,
|
|
88
|
+
max_exec_time / 1000 as max_time_ms,
|
|
89
|
+
(total_exec_time / sum(total_exec_time) OVER()) * 100 as percent_of_total
|
|
90
|
+
FROM pg_stat_statements
|
|
91
|
+
WHERE mean_exec_time > ${thresholdMs}
|
|
92
|
+
ORDER BY mean_exec_time DESC
|
|
93
|
+
LIMIT 20
|
|
94
|
+
`;
|
|
95
|
+
|
|
96
|
+
console.log("🐌 Slow Queries Detected:\n");
|
|
97
|
+
|
|
98
|
+
slowQueries.forEach((q, i) => {
|
|
99
|
+
console.log(`${i + 1}. ${q.query.substring(0, 80)}...`);
|
|
100
|
+
console.log(` Calls: ${q.calls}`);
|
|
101
|
+
console.log(` Avg: ${q.avg_time_ms.toFixed(2)}ms`);
|
|
102
|
+
console.log(` Max: ${q.max_time_ms.toFixed(2)}ms`);
|
|
103
|
+
console.log(` % of total time: ${q.percent_of_total.toFixed(1)}%\n`);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
return slowQueries;
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Connection Pool Monitoring
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
async function monitorConnectionPool() {
|
|
114
|
+
const stats = await prisma.$queryRaw<any[]>`
|
|
115
|
+
SELECT
|
|
116
|
+
sum(numbackends) as total_connections,
|
|
117
|
+
sum(CASE WHEN state = 'active' THEN 1 ELSE 0 END) as active,
|
|
118
|
+
sum(CASE WHEN state = 'idle' THEN 1 ELSE 0 END) as idle,
|
|
119
|
+
max_connections
|
|
120
|
+
FROM pg_stat_database
|
|
121
|
+
CROSS JOIN (SELECT setting::int as max_connections FROM pg_settings WHERE name = 'max_connections')
|
|
122
|
+
WHERE datname = current_database()
|
|
123
|
+
GROUP BY max_connections
|
|
124
|
+
`;
|
|
125
|
+
|
|
126
|
+
const { total_connections, active, idle, max_connections } = stats[0];
|
|
127
|
+
const utilization = (total_connections / max_connections) * 100;
|
|
128
|
+
|
|
129
|
+
console.log("🔌 Connection Pool Status:");
|
|
130
|
+
console.log(
|
|
131
|
+
` Total: ${total_connections}/${max_connections} (${utilization.toFixed(
|
|
132
|
+
1
|
|
133
|
+
)}%)`
|
|
134
|
+
);
|
|
135
|
+
console.log(` Active: ${active}`);
|
|
136
|
+
console.log(` Idle: ${idle}`);
|
|
137
|
+
|
|
138
|
+
// Alert if > 80% utilization
|
|
139
|
+
if (utilization > 80) {
|
|
140
|
+
console.warn("⚠️ Connection pool >80% utilized!");
|
|
141
|
+
await sendAlert({
|
|
142
|
+
title: "High connection pool usage",
|
|
143
|
+
message: `${utilization.toFixed(1)}% of connections in use`,
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Resource Monitoring
|
|
150
|
+
|
|
151
|
+
```typescript
|
|
152
|
+
async function monitorResources() {
|
|
153
|
+
// CPU Usage
|
|
154
|
+
const cpuStats = await prisma.$queryRaw<any[]>`
|
|
155
|
+
SELECT
|
|
156
|
+
(sum(total_exec_time) / (extract(epoch from (now() - stats_reset)) * 1000 * 100)) as cpu_percent
|
|
157
|
+
FROM pg_stat_statements, pg_stat_database
|
|
158
|
+
WHERE datname = current_database()
|
|
159
|
+
`;
|
|
160
|
+
|
|
161
|
+
// Memory Usage
|
|
162
|
+
const memStats = await prisma.$queryRaw<any[]>`
|
|
163
|
+
SELECT
|
|
164
|
+
pg_size_pretty(pg_database_size(current_database())) as db_size,
|
|
165
|
+
pg_size_pretty(sum(pg_relation_size(schemaname||'.'||tablename))) as tables_size
|
|
166
|
+
FROM pg_tables
|
|
167
|
+
WHERE schemaname = 'public'
|
|
168
|
+
`;
|
|
169
|
+
|
|
170
|
+
// Cache Hit Rate
|
|
171
|
+
const cacheStats = await prisma.$queryRaw<any[]>`
|
|
172
|
+
SELECT
|
|
173
|
+
sum(heap_blks_hit) / (sum(heap_blks_hit) + sum(heap_blks_read)) * 100 as cache_hit_rate
|
|
174
|
+
FROM pg_statio_user_tables
|
|
175
|
+
`;
|
|
176
|
+
|
|
177
|
+
console.log("📊 Resource Usage:");
|
|
178
|
+
console.log(` CPU: ${cpuStats[0].cpu_percent.toFixed(1)}%`);
|
|
179
|
+
console.log(` Database Size: ${memStats[0].db_size}`);
|
|
180
|
+
console.log(` Cache Hit Rate: ${cacheStats[0].cache_hit_rate.toFixed(1)}%`);
|
|
181
|
+
|
|
182
|
+
// Alert if cache hit rate < 90%
|
|
183
|
+
if (cacheStats[0].cache_hit_rate < 90) {
|
|
184
|
+
console.warn("⚠️ Cache hit rate below 90%!");
|
|
185
|
+
await sendAlert({
|
|
186
|
+
title: "Low cache hit rate",
|
|
187
|
+
message: `Cache hit rate: ${cacheStats[0].cache_hit_rate.toFixed(1)}%`,
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## Index Usage Analysis
|
|
194
|
+
|
|
195
|
+
```typescript
|
|
196
|
+
async function analyzeIndexUsage() {
|
|
197
|
+
// Find unused indexes
|
|
198
|
+
const unusedIndexes = await prisma.$queryRaw<any[]>`
|
|
199
|
+
SELECT
|
|
200
|
+
schemaname,
|
|
201
|
+
tablename,
|
|
202
|
+
indexname,
|
|
203
|
+
idx_scan
|
|
204
|
+
FROM pg_stat_user_indexes
|
|
205
|
+
WHERE idx_scan = 0
|
|
206
|
+
AND indexname NOT LIKE '%_pkey'
|
|
207
|
+
ORDER BY pg_relation_size(indexrelid) DESC
|
|
208
|
+
`;
|
|
209
|
+
|
|
210
|
+
console.log("🗂️ Unused Indexes:\n");
|
|
211
|
+
unusedIndexes.forEach((idx) => {
|
|
212
|
+
console.log(` ${idx.tablename}.${idx.indexname} (0 scans)`);
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
// Find missing indexes (sequential scans on large tables)
|
|
216
|
+
const missingIndexes = await prisma.$queryRaw<any[]>`
|
|
217
|
+
SELECT
|
|
218
|
+
schemaname,
|
|
219
|
+
tablename,
|
|
220
|
+
seq_scan,
|
|
221
|
+
seq_tup_read,
|
|
222
|
+
idx_scan,
|
|
223
|
+
n_live_tup
|
|
224
|
+
FROM pg_stat_user_tables
|
|
225
|
+
WHERE seq_scan > 1000
|
|
226
|
+
AND n_live_tup > 10000
|
|
227
|
+
ORDER BY seq_scan * n_live_tup DESC
|
|
228
|
+
LIMIT 10
|
|
229
|
+
`;
|
|
230
|
+
|
|
231
|
+
console.log("\n📉 Tables with High Sequential Scans:\n");
|
|
232
|
+
missingIndexes.forEach((table) => {
|
|
233
|
+
console.log(` ${table.tablename}:`);
|
|
234
|
+
console.log(` Sequential scans: ${table.seq_scan}`);
|
|
235
|
+
console.log(` Rows: ${table.n_live_tup}`);
|
|
236
|
+
console.log(` Index scans: ${table.idx_scan}`);
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
## Alert Thresholds
|
|
242
|
+
|
|
243
|
+
```typescript
|
|
244
|
+
const ALERT_THRESHOLDS = {
|
|
245
|
+
slowQuery: {
|
|
246
|
+
avgDuration: 500, // ms
|
|
247
|
+
maxDuration: 2000, // ms
|
|
248
|
+
callsPerMinute: 100,
|
|
249
|
+
},
|
|
250
|
+
connections: {
|
|
251
|
+
utilizationWarning: 70, // %
|
|
252
|
+
utilizationCritical: 85, // %
|
|
253
|
+
},
|
|
254
|
+
resources: {
|
|
255
|
+
cpuWarning: 70, // %
|
|
256
|
+
cpuCritical: 85, // %
|
|
257
|
+
memoryWarning: 80, // %
|
|
258
|
+
memoryCritical: 90, // %
|
|
259
|
+
diskWarning: 75, // %
|
|
260
|
+
diskCritical: 85, // %
|
|
261
|
+
},
|
|
262
|
+
cache: {
|
|
263
|
+
hitRateWarning: 90, // %
|
|
264
|
+
hitRateCritical: 80, // %
|
|
265
|
+
},
|
|
266
|
+
queryRate: {
|
|
267
|
+
maxSelectsPerSecond: 10000,
|
|
268
|
+
maxWritesPerSecond: 1000,
|
|
269
|
+
},
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
async function checkThresholds() {
|
|
273
|
+
const metrics = await gatherMetrics();
|
|
274
|
+
|
|
275
|
+
// Check slow queries
|
|
276
|
+
if (metrics.slowQueries.count > 10) {
|
|
277
|
+
await sendAlert({
|
|
278
|
+
level: "warning",
|
|
279
|
+
title: "Slow queries detected",
|
|
280
|
+
message: `${metrics.slowQueries.count} queries exceeding ${ALERT_THRESHOLDS.slowQuery.avgDuration}ms`,
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// Check connection pool
|
|
285
|
+
if (
|
|
286
|
+
metrics.connections.utilizationPercent >
|
|
287
|
+
ALERT_THRESHOLDS.connections.utilizationCritical
|
|
288
|
+
) {
|
|
289
|
+
await sendAlert({
|
|
290
|
+
level: "critical",
|
|
291
|
+
title: "Connection pool critical",
|
|
292
|
+
message: `${metrics.connections.utilizationPercent.toFixed(
|
|
293
|
+
1
|
|
294
|
+
)}% utilization`,
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// Check cache hit rate
|
|
299
|
+
if (metrics.cache.hitRate < ALERT_THRESHOLDS.cache.hitRateCritical) {
|
|
300
|
+
await sendAlert({
|
|
301
|
+
level: "critical",
|
|
302
|
+
title: "Cache hit rate critical",
|
|
303
|
+
message: `${metrics.cache.hitRate.toFixed(1)}% hit rate`,
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
## Monitoring Dashboard
|
|
310
|
+
|
|
311
|
+
```typescript
|
|
312
|
+
// Generate monitoring report
|
|
313
|
+
async function generatePerformanceReport() {
|
|
314
|
+
console.log("📊 Database Performance Report\n");
|
|
315
|
+
console.log("=".repeat(50) + "\n");
|
|
316
|
+
|
|
317
|
+
// Slow queries
|
|
318
|
+
const slowQueries = await detectSlowQueries(100);
|
|
319
|
+
console.log(`Slow Queries (>100ms): ${slowQueries.length}\n`);
|
|
320
|
+
|
|
321
|
+
// Connection pool
|
|
322
|
+
await monitorConnectionPool();
|
|
323
|
+
console.log();
|
|
324
|
+
|
|
325
|
+
// Resources
|
|
326
|
+
await monitorResources();
|
|
327
|
+
console.log();
|
|
328
|
+
|
|
329
|
+
// Index usage
|
|
330
|
+
await analyzeIndexUsage();
|
|
331
|
+
console.log();
|
|
332
|
+
|
|
333
|
+
// Query rates
|
|
334
|
+
const queryStats = await prisma.$queryRaw<any[]>`
|
|
335
|
+
SELECT
|
|
336
|
+
sum(xact_commit + xact_rollback) as transactions,
|
|
337
|
+
sum(tup_returned) as rows_read,
|
|
338
|
+
sum(tup_inserted) as rows_inserted,
|
|
339
|
+
sum(tup_updated) as rows_updated,
|
|
340
|
+
sum(tup_deleted) as rows_deleted
|
|
341
|
+
FROM pg_stat_database
|
|
342
|
+
WHERE datname = current_database()
|
|
343
|
+
`;
|
|
344
|
+
|
|
345
|
+
console.log("📈 Query Statistics:");
|
|
346
|
+
console.log(` Transactions: ${queryStats[0].transactions}`);
|
|
347
|
+
console.log(` Rows read: ${queryStats[0].rows_read}`);
|
|
348
|
+
console.log(` Rows inserted: ${queryStats[0].rows_inserted}`);
|
|
349
|
+
console.log(` Rows updated: ${queryStats[0].rows_updated}`);
|
|
350
|
+
console.log(` Rows deleted: ${queryStats[0].rows_deleted}`);
|
|
351
|
+
}
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
## Automated Monitoring Script
|
|
355
|
+
|
|
356
|
+
```typescript
|
|
357
|
+
// scripts/monitor-db.ts
|
|
358
|
+
import cron from "node-cron";
|
|
359
|
+
|
|
360
|
+
// Run every 5 minutes
|
|
361
|
+
cron.schedule("*/5 * * * *", async () => {
|
|
362
|
+
await checkThresholds();
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
// Generate report every hour
|
|
366
|
+
cron.schedule("0 * * * *", async () => {
|
|
367
|
+
await generatePerformanceReport();
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
// Analyze indexes weekly
|
|
371
|
+
cron.schedule("0 0 * * 0", async () => {
|
|
372
|
+
await analyzeIndexUsage();
|
|
373
|
+
});
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
## Grafana Dashboard Queries
|
|
377
|
+
|
|
378
|
+
```sql
|
|
379
|
+
-- Query latency over time
|
|
380
|
+
SELECT
|
|
381
|
+
bucket,
|
|
382
|
+
AVG(mean_exec_time) as avg_latency,
|
|
383
|
+
MAX(max_exec_time) as max_latency,
|
|
384
|
+
SUM(calls) as total_calls
|
|
385
|
+
FROM pg_stat_statements
|
|
386
|
+
WHERE query NOT LIKE '%pg_stat_statements%'
|
|
387
|
+
GROUP BY time_bucket('5 minutes', queryid)
|
|
388
|
+
ORDER BY bucket;
|
|
389
|
+
|
|
390
|
+
-- Connection count over time
|
|
391
|
+
SELECT
|
|
392
|
+
now() as time,
|
|
393
|
+
count(*) as total,
|
|
394
|
+
count(*) FILTER (WHERE state = 'active') as active,
|
|
395
|
+
count(*) FILTER (WHERE state = 'idle') as idle
|
|
396
|
+
FROM pg_stat_activity;
|
|
397
|
+
|
|
398
|
+
-- Cache hit rate
|
|
399
|
+
SELECT
|
|
400
|
+
sum(heap_blks_hit) / (sum(heap_blks_hit) + sum(heap_blks_read)) * 100 as cache_hit_rate
|
|
401
|
+
FROM pg_statio_user_tables;
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
## Best Practices
|
|
405
|
+
|
|
406
|
+
1. **Monitor continuously**: Don't wait for problems
|
|
407
|
+
2. **Set appropriate thresholds**: Based on your SLAs
|
|
408
|
+
3. **Alert on trends**: Not just absolute values
|
|
409
|
+
4. **Review regularly**: Weekly performance reviews
|
|
410
|
+
5. **Automate everything**: No manual checks
|
|
411
|
+
6. **Document baselines**: Know what's normal
|
|
412
|
+
7. **Test alerts**: Ensure they work
|
|
413
|
+
|
|
414
|
+
## Output Checklist
|
|
415
|
+
|
|
416
|
+
- [ ] Slow query detection configured
|
|
417
|
+
- [ ] Connection pool monitoring
|
|
418
|
+
- [ ] Resource usage tracking
|
|
419
|
+
- [ ] Cache hit rate monitoring
|
|
420
|
+
- [ ] Index usage analysis
|
|
421
|
+
- [ ] Alert thresholds defined
|
|
422
|
+
- [ ] Monitoring dashboard setup
|
|
423
|
+
- [ ] Automated checks scheduled
|
|
424
|
+
- [ ] Grafana/alerting integration
|
|
425
|
+
- [ ] Performance baseline documented
|