forked from weroperking/Betterbase
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathquery-log.ts
More file actions
115 lines (94 loc) · 2.7 KB
/
Copy pathquery-log.ts
File metadata and controls
115 lines (94 loc) · 2.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/**
* BetterBase Dev Mode Query Log
*
* Shows queries executed during development with timing and warnings.
*/
import chalk from "chalk";
export interface QueryLogEntry {
timestamp: Date;
kind: "query" | "mutation" | "action";
path: string;
duration: number;
success: boolean;
error?: string;
}
export class QueryLog {
private entries: QueryLogEntry[] = [];
private enabled = false;
private maxEntries = 100;
enable(): void {
this.enabled = true;
console.log(chalk.dim("\n[query-log] Enabled query logging\n"));
}
disable(): void {
this.enabled = false;
this.printSummary();
}
log(entry: Omit<QueryLogEntry, "timestamp">): void {
if (!this.enabled) return;
const fullEntry: QueryLogEntry = {
...entry,
timestamp: new Date(),
};
this.entries.push(fullEntry);
if (this.entries.length > this.maxEntries) {
this.entries.shift();
}
this.printEntry(fullEntry);
}
private printEntry(entry: QueryLogEntry): void {
const icon = entry.success ? chalk.green("✓") : chalk.red("✗");
const kindIcon = entry.kind === "query" ? "Q" : entry.kind === "mutation" ? "M" : "A";
const durationStr = `${entry.duration}ms`;
const durationColor =
entry.duration > 500 ? chalk.yellow : entry.duration > 1000 ? chalk.red : chalk.dim;
const line = [
chalk.dim(`[${entry.timestamp.toLocaleTimeString()}]`),
chalk.blue(kindIcon),
icon,
chalk.white(entry.path),
durationColor(durationStr),
].join(" ");
console.log(line);
if (entry.error) {
console.log(chalk.red(` Error: ${entry.error}`));
}
// Warn about slow queries
if (entry.duration > 1000 && entry.success) {
console.log(chalk.yellow(" ⚠ Slow query - consider adding an index"));
}
}
private printSummary(): void {
if (this.entries.length === 0) return;
const total = this.entries.length;
const successful = this.entries.filter((e) => e.success).length;
const failed = total - successful;
const avgDuration = this.entries.reduce((sum, e) => sum + e.duration, 0) / this.entries.length;
const slow = this.entries.filter((e) => e.duration > 1000).length;
console.log(chalk.dim("\n" + "═".repeat(60)));
console.log(chalk.bold("Query Log Summary"));
console.log(
chalk.dim(" Total:") +
` ${total} | ` +
chalk.green("✓ OK:") +
` ${successful} | ` +
chalk.red("✗ Failed:") +
` ${failed}`,
);
console.log(
chalk.dim(" Avg:") +
` ${Math.round(avgDuration)}ms | ` +
chalk.yellow("⚠ Slow:") +
` ${slow}`,
);
console.log(chalk.dim("═".repeat(60) + "\n"));
}
getEntries(): QueryLogEntry[] {
return [...this.entries];
}
clear(): void {
this.entries = [];
}
}
// Singleton instance for global access
export const queryLog = new QueryLog();