cursor-kit-cli 1.2.0-beta → 1.2.0-beta.2
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/dist/cli.cjs +333 -56
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +334 -57
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +39 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.js +33 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/templates/commands/docs.md +5 -3
- package/templates/commands/explain.md +5 -3
- package/templates/commands/fix.md +5 -3
- package/templates/commands/implement.md +5 -3
- package/templates/commands/refactor.md +5 -3
- package/templates/commands/review.md +5 -3
- package/templates/commands/test.md +5 -3
- package/templates/manifest.json +11 -8
- package/templates/rules/git.mdc +0 -2
- package/templates/rules/toc.mdc +17 -9
- package/templates/skills/aesthetic/SKILL.md +121 -0
- package/templates/skills/aesthetic/assets/design-guideline-template.md +163 -0
- package/templates/skills/aesthetic/assets/design-story-template.md +135 -0
- package/templates/skills/aesthetic/references/design-principles.md +62 -0
- package/templates/skills/aesthetic/references/design-resources.md +75 -0
- package/templates/skills/aesthetic/references/micro-interactions.md +53 -0
- package/templates/skills/aesthetic/references/storytelling-design.md +50 -0
- package/templates/skills/backend-development/SKILL.mdc +95 -0
- package/templates/skills/backend-development/references/backend-api-design.md +495 -0
- package/templates/skills/backend-development/references/backend-architecture.md +454 -0
- package/templates/skills/backend-development/references/backend-authentication.md +338 -0
- package/templates/skills/backend-development/references/backend-code-quality.md +659 -0
- package/templates/skills/backend-development/references/backend-debugging.md +904 -0
- package/templates/skills/backend-development/references/backend-devops.md +494 -0
- package/templates/skills/backend-development/references/backend-mindset.md +387 -0
- package/templates/skills/backend-development/references/backend-performance.md +397 -0
- package/templates/skills/backend-development/references/backend-security.md +290 -0
- package/templates/skills/backend-development/references/backend-technologies.md +256 -0
- package/templates/skills/backend-development/references/backend-testing.md +429 -0
- package/templates/skills/frontend-design/SKILL.mdc +41 -0
- package/templates/skills/frontend-design/references/animejs.md +396 -0
- package/templates/skills/frontend-development/SKILL.mdc +399 -0
- package/templates/skills/frontend-development/resources/common-patterns.md +331 -0
- package/templates/skills/frontend-development/resources/complete-examples.md +872 -0
- package/templates/skills/frontend-development/resources/component-patterns.md +502 -0
- package/templates/skills/frontend-development/resources/data-fetching.md +767 -0
- package/templates/skills/frontend-development/resources/file-organization.md +502 -0
- package/templates/skills/frontend-development/resources/loading-and-error-states.md +501 -0
- package/templates/skills/frontend-development/resources/performance.md +406 -0
- package/templates/skills/frontend-development/resources/routing-guide.md +364 -0
- package/templates/skills/frontend-development/resources/styling-guide.md +428 -0
- package/templates/skills/frontend-development/resources/typescript-standards.md +418 -0
- package/templates/skills/problem-solving/SKILL.mdc +96 -0
- package/templates/skills/problem-solving/references/attribution.md +69 -0
- package/templates/skills/problem-solving/references/collision-zone-thinking.md +79 -0
- package/templates/skills/problem-solving/references/inversion-exercise.md +91 -0
- package/templates/skills/problem-solving/references/meta-pattern-recognition.md +87 -0
- package/templates/skills/problem-solving/references/scale-game.md +95 -0
- package/templates/skills/problem-solving/references/simplification-cascades.md +80 -0
- package/templates/skills/problem-solving/references/when-stuck.md +72 -0
- package/templates/skills/research/SKILL.mdc +168 -0
- package/templates/skills/sequential-thinking/.env.example +8 -0
- package/templates/skills/sequential-thinking/README.md +183 -0
- package/templates/skills/sequential-thinking/SKILL.mdc +94 -0
- package/templates/skills/sequential-thinking/package.json +31 -0
- package/templates/skills/sequential-thinking/references/advanced-strategies.md +79 -0
- package/templates/skills/sequential-thinking/references/advanced-techniques.md +76 -0
- package/templates/skills/sequential-thinking/references/core-patterns.md +95 -0
- package/templates/skills/sequential-thinking/references/examples-api.md +88 -0
- package/templates/skills/sequential-thinking/references/examples-architecture.md +94 -0
- package/templates/skills/sequential-thinking/references/examples-debug.md +90 -0
- package/templates/skills/sequential-thinking/scripts/format-thought.js +159 -0
- package/templates/skills/sequential-thinking/scripts/process-thought.js +236 -0
- package/templates/skills/sequential-thinking/tests/format-thought.test.js +133 -0
- package/templates/skills/sequential-thinking/tests/process-thought.test.js +215 -0
- package/templates/skills/ui-styling/LICENSE.txt +202 -0
- package/templates/skills/ui-styling/SKILL.mdc +321 -0
- package/templates/skills/ui-styling/references/canvas-design-system.md +320 -0
- package/templates/skills/ui-styling/references/shadcn-accessibility.md +471 -0
- package/templates/skills/ui-styling/references/shadcn-components.md +424 -0
- package/templates/skills/ui-styling/references/shadcn-theming.md +373 -0
- package/templates/skills/ui-styling/references/tailwind-customization.md +483 -0
- package/templates/skills/ui-styling/references/tailwind-responsive.md +382 -0
- package/templates/skills/ui-styling/references/tailwind-utilities.md +455 -0
- package/templates/rules/frontend-design.mdc +0 -48
- package/templates/rules/performance.mdc +0 -54
- package/templates/rules/react.mdc +0 -58
- package/templates/rules/security.mdc +0 -50
- package/templates/rules/testing.mdc +0 -54
- package/templates/rules/typescript.mdc +0 -36
|
@@ -0,0 +1,904 @@
|
|
|
1
|
+
# Backend Debugging Strategies
|
|
2
|
+
|
|
3
|
+
Comprehensive debugging techniques, tools, and best practices for backend systems (2025).
|
|
4
|
+
|
|
5
|
+
## Debugging Mindset
|
|
6
|
+
|
|
7
|
+
### The Scientific Method for Debugging
|
|
8
|
+
|
|
9
|
+
1. **Observe** - Gather symptoms and data
|
|
10
|
+
2. **Hypothesize** - Form theories about the cause
|
|
11
|
+
3. **Test** - Verify or disprove theories
|
|
12
|
+
4. **Iterate** - Refine understanding
|
|
13
|
+
5. **Fix** - Apply solution
|
|
14
|
+
6. **Verify** - Confirm fix works
|
|
15
|
+
|
|
16
|
+
### Golden Rules
|
|
17
|
+
|
|
18
|
+
1. **Reproduce first** - Debugging without reproduction is guessing
|
|
19
|
+
2. **Simplify the problem** - Isolate variables
|
|
20
|
+
3. **Read the logs** - Error messages contain clues
|
|
21
|
+
4. **Check assumptions** - "It should work" isn't debugging
|
|
22
|
+
5. **Use scientific method** - Avoid random changes
|
|
23
|
+
6. **Document findings** - Future you will thank you
|
|
24
|
+
|
|
25
|
+
## Logging Best Practices
|
|
26
|
+
|
|
27
|
+
### Structured Logging
|
|
28
|
+
|
|
29
|
+
**Node.js (Pino - Fastest)**
|
|
30
|
+
```typescript
|
|
31
|
+
import pino from 'pino';
|
|
32
|
+
|
|
33
|
+
const logger = pino({
|
|
34
|
+
level: process.env.LOG_LEVEL || 'info',
|
|
35
|
+
transport: {
|
|
36
|
+
target: 'pino-pretty',
|
|
37
|
+
options: { colorize: true }
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
// Structured logging with context
|
|
42
|
+
logger.info({ userId: '123', action: 'login' }, 'User logged in');
|
|
43
|
+
|
|
44
|
+
// Error logging with stack trace
|
|
45
|
+
try {
|
|
46
|
+
await riskyOperation();
|
|
47
|
+
} catch (error) {
|
|
48
|
+
logger.error({ err: error, userId: '123' }, 'Operation failed');
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**Python (Structlog)**
|
|
53
|
+
```python
|
|
54
|
+
import structlog
|
|
55
|
+
|
|
56
|
+
logger = structlog.get_logger()
|
|
57
|
+
|
|
58
|
+
# Structured context
|
|
59
|
+
logger.info("user_login", user_id="123", ip="192.168.1.1")
|
|
60
|
+
|
|
61
|
+
# Error with exception
|
|
62
|
+
try:
|
|
63
|
+
risky_operation()
|
|
64
|
+
except Exception as e:
|
|
65
|
+
logger.error("operation_failed", user_id="123", exc_info=True)
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**Go (Zap - High Performance)**
|
|
69
|
+
```go
|
|
70
|
+
import "go.uber.org/zap"
|
|
71
|
+
|
|
72
|
+
logger, _ := zap.NewProduction()
|
|
73
|
+
defer logger.Sync()
|
|
74
|
+
|
|
75
|
+
// Structured fields
|
|
76
|
+
logger.Info("user logged in",
|
|
77
|
+
zap.String("user_id", "123"),
|
|
78
|
+
zap.String("ip", "192.168.1.1"),
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
// Error logging
|
|
82
|
+
if err := riskyOperation(); err != nil {
|
|
83
|
+
logger.Error("operation failed",
|
|
84
|
+
zap.Error(err),
|
|
85
|
+
zap.String("user_id", "123"),
|
|
86
|
+
)
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Log Levels
|
|
91
|
+
|
|
92
|
+
| Level | Purpose | Example |
|
|
93
|
+
|-------|---------|---------|
|
|
94
|
+
| **TRACE** | Very detailed, dev only | Request/response bodies |
|
|
95
|
+
| **DEBUG** | Detailed info for debugging | SQL queries, cache hits |
|
|
96
|
+
| **INFO** | General informational | User login, API calls |
|
|
97
|
+
| **WARN** | Potential issues | Deprecated API usage |
|
|
98
|
+
| **ERROR** | Error conditions | Failed API calls, exceptions |
|
|
99
|
+
| **FATAL** | Critical failures | Database connection lost |
|
|
100
|
+
|
|
101
|
+
### What to Log
|
|
102
|
+
|
|
103
|
+
**✅ DO LOG:**
|
|
104
|
+
- Request/response metadata (not bodies in prod)
|
|
105
|
+
- Error messages with context
|
|
106
|
+
- Performance metrics (duration, size)
|
|
107
|
+
- Security events (login, permission changes)
|
|
108
|
+
- Business events (orders, payments)
|
|
109
|
+
|
|
110
|
+
**❌ DON'T LOG:**
|
|
111
|
+
- Passwords or secrets
|
|
112
|
+
- Credit card numbers
|
|
113
|
+
- Personal identifiable information (PII)
|
|
114
|
+
- Session tokens
|
|
115
|
+
- Full request bodies in production
|
|
116
|
+
|
|
117
|
+
## Debugging Tools by Language
|
|
118
|
+
|
|
119
|
+
### Node.js / TypeScript
|
|
120
|
+
|
|
121
|
+
**1. Chrome DevTools (Built-in)**
|
|
122
|
+
```bash
|
|
123
|
+
# Run with inspect flag
|
|
124
|
+
node --inspect-brk app.js
|
|
125
|
+
|
|
126
|
+
# Open chrome://inspect in Chrome
|
|
127
|
+
# Set breakpoints, step through code
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**2. VS Code Debugger**
|
|
131
|
+
```json
|
|
132
|
+
// .vscode/launch.json
|
|
133
|
+
{
|
|
134
|
+
"version": "0.2.0",
|
|
135
|
+
"configurations": [
|
|
136
|
+
{
|
|
137
|
+
"type": "node",
|
|
138
|
+
"request": "launch",
|
|
139
|
+
"name": "Debug Server",
|
|
140
|
+
"skipFiles": ["<node_internals>/**"],
|
|
141
|
+
"program": "${workspaceFolder}/src/index.ts",
|
|
142
|
+
"preLaunchTask": "npm: build",
|
|
143
|
+
"outFiles": ["${workspaceFolder}/dist/**/*.js"]
|
|
144
|
+
}
|
|
145
|
+
]
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
**3. Debug Module**
|
|
150
|
+
```typescript
|
|
151
|
+
import debug from 'debug';
|
|
152
|
+
|
|
153
|
+
const log = debug('app:server');
|
|
154
|
+
const error = debug('app:error');
|
|
155
|
+
|
|
156
|
+
log('Starting server on port %d', 3000);
|
|
157
|
+
error('Failed to connect to database');
|
|
158
|
+
|
|
159
|
+
// Run with: DEBUG=app:* node app.js
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Python
|
|
163
|
+
|
|
164
|
+
**1. PDB (Built-in Debugger)**
|
|
165
|
+
```python
|
|
166
|
+
import pdb
|
|
167
|
+
|
|
168
|
+
def problematic_function(data):
|
|
169
|
+
# Set breakpoint
|
|
170
|
+
pdb.set_trace()
|
|
171
|
+
|
|
172
|
+
# Debugger commands:
|
|
173
|
+
# l - list code
|
|
174
|
+
# n - next line
|
|
175
|
+
# s - step into
|
|
176
|
+
# c - continue
|
|
177
|
+
# p variable - print variable
|
|
178
|
+
# q - quit
|
|
179
|
+
result = process(data)
|
|
180
|
+
return result
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
**2. IPython Debugger (Better)**
|
|
184
|
+
```python
|
|
185
|
+
from IPython import embed
|
|
186
|
+
|
|
187
|
+
def problematic_function(data):
|
|
188
|
+
# Drop into IPython shell
|
|
189
|
+
embed()
|
|
190
|
+
|
|
191
|
+
result = process(data)
|
|
192
|
+
return result
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
**3. VS Code Debugger**
|
|
196
|
+
```json
|
|
197
|
+
// .vscode/launch.json
|
|
198
|
+
{
|
|
199
|
+
"version": "0.2.0",
|
|
200
|
+
"configurations": [
|
|
201
|
+
{
|
|
202
|
+
"name": "Python: FastAPI",
|
|
203
|
+
"type": "python",
|
|
204
|
+
"request": "launch",
|
|
205
|
+
"module": "uvicorn",
|
|
206
|
+
"args": ["main:app", "--reload"],
|
|
207
|
+
"jinja": true
|
|
208
|
+
}
|
|
209
|
+
]
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Go
|
|
214
|
+
|
|
215
|
+
**1. Delve (Standard Debugger)**
|
|
216
|
+
```bash
|
|
217
|
+
# Install
|
|
218
|
+
go install github.com/go-delve/delve/cmd/dlv@latest
|
|
219
|
+
|
|
220
|
+
# Debug
|
|
221
|
+
dlv debug main.go
|
|
222
|
+
|
|
223
|
+
# Commands:
|
|
224
|
+
# b main.main - set breakpoint
|
|
225
|
+
# c - continue
|
|
226
|
+
# n - next line
|
|
227
|
+
# s - step into
|
|
228
|
+
# p variable - print variable
|
|
229
|
+
# q - quit
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
**2. VS Code Debugger**
|
|
233
|
+
```json
|
|
234
|
+
// .vscode/launch.json
|
|
235
|
+
{
|
|
236
|
+
"version": "0.2.0",
|
|
237
|
+
"configurations": [
|
|
238
|
+
{
|
|
239
|
+
"name": "Launch Package",
|
|
240
|
+
"type": "go",
|
|
241
|
+
"request": "launch",
|
|
242
|
+
"mode": "debug",
|
|
243
|
+
"program": "${workspaceFolder}"
|
|
244
|
+
}
|
|
245
|
+
]
|
|
246
|
+
}
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### Rust
|
|
250
|
+
|
|
251
|
+
**1. LLDB/GDB (Native Debuggers)**
|
|
252
|
+
```bash
|
|
253
|
+
# Build with debug info
|
|
254
|
+
cargo build
|
|
255
|
+
|
|
256
|
+
# Debug with LLDB
|
|
257
|
+
rust-lldb ./target/debug/myapp
|
|
258
|
+
|
|
259
|
+
# Debug with GDB
|
|
260
|
+
rust-gdb ./target/debug/myapp
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
**2. VS Code Debugger (CodeLLDB)**
|
|
264
|
+
```json
|
|
265
|
+
// .vscode/launch.json
|
|
266
|
+
{
|
|
267
|
+
"version": "0.2.0",
|
|
268
|
+
"configurations": [
|
|
269
|
+
{
|
|
270
|
+
"type": "lldb",
|
|
271
|
+
"request": "launch",
|
|
272
|
+
"name": "Debug",
|
|
273
|
+
"program": "${workspaceFolder}/target/debug/myapp",
|
|
274
|
+
"args": [],
|
|
275
|
+
"cwd": "${workspaceFolder}"
|
|
276
|
+
}
|
|
277
|
+
]
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
## Database Debugging
|
|
282
|
+
|
|
283
|
+
### SQL Query Debugging (PostgreSQL)
|
|
284
|
+
|
|
285
|
+
**1. EXPLAIN ANALYZE**
|
|
286
|
+
```sql
|
|
287
|
+
-- Show query execution plan and actual timings
|
|
288
|
+
EXPLAIN ANALYZE
|
|
289
|
+
SELECT u.name, COUNT(o.id) as order_count
|
|
290
|
+
FROM users u
|
|
291
|
+
LEFT JOIN orders o ON u.id = o.user_id
|
|
292
|
+
WHERE u.created_at > '2024-01-01'
|
|
293
|
+
GROUP BY u.id, u.name
|
|
294
|
+
ORDER BY order_count DESC
|
|
295
|
+
LIMIT 10;
|
|
296
|
+
|
|
297
|
+
-- Look for:
|
|
298
|
+
-- - Seq Scan on large tables (missing indexes)
|
|
299
|
+
-- - High execution time
|
|
300
|
+
-- - Large row estimates
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
**2. Enable Slow Query Logging**
|
|
304
|
+
```sql
|
|
305
|
+
-- PostgreSQL configuration
|
|
306
|
+
ALTER DATABASE mydb SET log_min_duration_statement = 1000; -- Log queries >1s
|
|
307
|
+
|
|
308
|
+
-- Check slow queries
|
|
309
|
+
SELECT query, calls, total_exec_time, mean_exec_time
|
|
310
|
+
FROM pg_stat_statements
|
|
311
|
+
ORDER BY mean_exec_time DESC
|
|
312
|
+
LIMIT 10;
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
**3. Active Query Monitoring**
|
|
316
|
+
```sql
|
|
317
|
+
-- See currently running queries
|
|
318
|
+
SELECT pid, now() - query_start as duration, query, state
|
|
319
|
+
FROM pg_stat_activity
|
|
320
|
+
WHERE state = 'active'
|
|
321
|
+
ORDER BY duration DESC;
|
|
322
|
+
|
|
323
|
+
-- Kill a long-running query
|
|
324
|
+
SELECT pg_terminate_backend(pid);
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
### MongoDB Debugging
|
|
328
|
+
|
|
329
|
+
**1. Explain Query Performance**
|
|
330
|
+
```javascript
|
|
331
|
+
db.users.find({ email: 'test@example.com' }).explain('executionStats')
|
|
332
|
+
|
|
333
|
+
// Look for:
|
|
334
|
+
// - totalDocsExamined vs nReturned (should be close)
|
|
335
|
+
// - COLLSCAN (collection scan - needs index)
|
|
336
|
+
// - executionTimeMillis (should be low)
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
**2. Profile Slow Queries**
|
|
340
|
+
```javascript
|
|
341
|
+
// Enable profiling for queries >100ms
|
|
342
|
+
db.setProfilingLevel(1, { slowms: 100 })
|
|
343
|
+
|
|
344
|
+
// View slow queries
|
|
345
|
+
db.system.profile.find().limit(5).sort({ ts: -1 }).pretty()
|
|
346
|
+
|
|
347
|
+
// Disable profiling
|
|
348
|
+
db.setProfilingLevel(0)
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
### Redis Debugging
|
|
352
|
+
|
|
353
|
+
**1. Monitor Commands**
|
|
354
|
+
```bash
|
|
355
|
+
# See all commands in real-time
|
|
356
|
+
redis-cli MONITOR
|
|
357
|
+
|
|
358
|
+
# Check slow log
|
|
359
|
+
redis-cli SLOWLOG GET 10
|
|
360
|
+
|
|
361
|
+
# Set slow log threshold (microseconds)
|
|
362
|
+
redis-cli CONFIG SET slowlog-log-slower-than 10000
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
**2. Memory Analysis**
|
|
366
|
+
```bash
|
|
367
|
+
# Memory usage by key pattern
|
|
368
|
+
redis-cli --bigkeys
|
|
369
|
+
|
|
370
|
+
# Memory usage details
|
|
371
|
+
redis-cli INFO memory
|
|
372
|
+
|
|
373
|
+
# Analyze specific key
|
|
374
|
+
redis-cli MEMORY USAGE mykey
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
## API Debugging
|
|
378
|
+
|
|
379
|
+
### HTTP Request Debugging
|
|
380
|
+
|
|
381
|
+
**1. cURL Testing**
|
|
382
|
+
```bash
|
|
383
|
+
# Verbose output with headers
|
|
384
|
+
curl -v https://api.example.com/users
|
|
385
|
+
|
|
386
|
+
# Include response headers
|
|
387
|
+
curl -i https://api.example.com/users
|
|
388
|
+
|
|
389
|
+
# POST with JSON
|
|
390
|
+
curl -X POST https://api.example.com/users \
|
|
391
|
+
-H "Content-Type: application/json" \
|
|
392
|
+
-d '{"name":"John","email":"john@example.com"}' \
|
|
393
|
+
-v
|
|
394
|
+
|
|
395
|
+
# Save response to file
|
|
396
|
+
curl https://api.example.com/users -o response.json
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
**2. HTTPie (User-Friendly)**
|
|
400
|
+
```bash
|
|
401
|
+
# Install
|
|
402
|
+
pip install httpie
|
|
403
|
+
|
|
404
|
+
# Simple GET
|
|
405
|
+
http GET https://api.example.com/users
|
|
406
|
+
|
|
407
|
+
# POST with JSON
|
|
408
|
+
http POST https://api.example.com/users name=John email=john@example.com
|
|
409
|
+
|
|
410
|
+
# Custom headers
|
|
411
|
+
http GET https://api.example.com/users Authorization:"Bearer token123"
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
**3. Request Logging Middleware**
|
|
415
|
+
|
|
416
|
+
**Express/Node.js:**
|
|
417
|
+
```typescript
|
|
418
|
+
import morgan from 'morgan';
|
|
419
|
+
|
|
420
|
+
// Development
|
|
421
|
+
app.use(morgan('dev'));
|
|
422
|
+
|
|
423
|
+
// Production (JSON format)
|
|
424
|
+
app.use(morgan('combined'));
|
|
425
|
+
|
|
426
|
+
// Custom format
|
|
427
|
+
app.use(morgan(':method :url :status :response-time ms - :res[content-length]'));
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
**FastAPI/Python:**
|
|
431
|
+
```python
|
|
432
|
+
from fastapi import Request
|
|
433
|
+
import time
|
|
434
|
+
|
|
435
|
+
@app.middleware("http")
|
|
436
|
+
async def log_requests(request: Request, call_next):
|
|
437
|
+
start_time = time.time()
|
|
438
|
+
response = await call_next(request)
|
|
439
|
+
duration = time.time() - start_time
|
|
440
|
+
|
|
441
|
+
logger.info(
|
|
442
|
+
"request_processed",
|
|
443
|
+
method=request.method,
|
|
444
|
+
path=request.url.path,
|
|
445
|
+
status_code=response.status_code,
|
|
446
|
+
duration_ms=duration * 1000
|
|
447
|
+
)
|
|
448
|
+
return response
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
## Performance Debugging
|
|
452
|
+
|
|
453
|
+
### CPU Profiling
|
|
454
|
+
|
|
455
|
+
**Node.js (0x)**
|
|
456
|
+
```bash
|
|
457
|
+
# Install
|
|
458
|
+
npm install -g 0x
|
|
459
|
+
|
|
460
|
+
# Profile application
|
|
461
|
+
0x node app.js
|
|
462
|
+
|
|
463
|
+
# Open flamegraph in browser
|
|
464
|
+
# Identify hot spots (red areas)
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
**Node.js (Clinic.js)**
|
|
468
|
+
```bash
|
|
469
|
+
# Install
|
|
470
|
+
npm install -g clinic
|
|
471
|
+
|
|
472
|
+
# CPU profiling
|
|
473
|
+
clinic doctor -- node app.js
|
|
474
|
+
|
|
475
|
+
# Heap profiling
|
|
476
|
+
clinic heapprofiler -- node app.js
|
|
477
|
+
|
|
478
|
+
# Event loop analysis
|
|
479
|
+
clinic bubbleprof -- node app.js
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
**Python (cProfile)**
|
|
483
|
+
```python
|
|
484
|
+
import cProfile
|
|
485
|
+
import pstats
|
|
486
|
+
|
|
487
|
+
# Profile function
|
|
488
|
+
profiler = cProfile.Profile()
|
|
489
|
+
profiler.enable()
|
|
490
|
+
|
|
491
|
+
# Your code
|
|
492
|
+
result = expensive_operation()
|
|
493
|
+
|
|
494
|
+
profiler.disable()
|
|
495
|
+
stats = pstats.Stats(profiler)
|
|
496
|
+
stats.sort_stats('cumulative')
|
|
497
|
+
stats.print_stats(10) # Top 10 functions
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
**Go (pprof)**
|
|
501
|
+
```go
|
|
502
|
+
import (
|
|
503
|
+
"net/http"
|
|
504
|
+
_ "net/http/pprof"
|
|
505
|
+
)
|
|
506
|
+
|
|
507
|
+
func main() {
|
|
508
|
+
// Enable profiling endpoint
|
|
509
|
+
go func() {
|
|
510
|
+
http.ListenAndServe("localhost:6060", nil)
|
|
511
|
+
}()
|
|
512
|
+
|
|
513
|
+
// Your application
|
|
514
|
+
startServer()
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
// Profile CPU
|
|
518
|
+
// go tool pprof http://localhost:6060/debug/pprof/profile?seconds=30
|
|
519
|
+
|
|
520
|
+
// Profile heap
|
|
521
|
+
// go tool pprof http://localhost:6060/debug/pprof/heap
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
### Memory Debugging
|
|
525
|
+
|
|
526
|
+
**Node.js (Heap Snapshots)**
|
|
527
|
+
```typescript
|
|
528
|
+
// Take heap snapshot programmatically
|
|
529
|
+
import { writeHeapSnapshot } from 'v8';
|
|
530
|
+
|
|
531
|
+
app.get('/debug/heap', (req, res) => {
|
|
532
|
+
const filename = writeHeapSnapshot();
|
|
533
|
+
res.send(`Heap snapshot written to ${filename}`);
|
|
534
|
+
});
|
|
535
|
+
|
|
536
|
+
// Analyze in Chrome DevTools
|
|
537
|
+
// 1. Load heap snapshot
|
|
538
|
+
// 2. Compare snapshots to find memory leaks
|
|
539
|
+
// 3. Look for detached DOM nodes, large arrays
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
**Python (Memory Profiler)**
|
|
543
|
+
```python
|
|
544
|
+
from memory_profiler import profile
|
|
545
|
+
|
|
546
|
+
@profile
|
|
547
|
+
def memory_intensive_function():
|
|
548
|
+
large_list = [i for i in range(1000000)]
|
|
549
|
+
return sum(large_list)
|
|
550
|
+
|
|
551
|
+
# Run with: python -m memory_profiler script.py
|
|
552
|
+
# Shows line-by-line memory usage
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
## Production Debugging
|
|
556
|
+
|
|
557
|
+
### Application Performance Monitoring (APM)
|
|
558
|
+
|
|
559
|
+
**New Relic**
|
|
560
|
+
```typescript
|
|
561
|
+
// newrelic.js
|
|
562
|
+
export const config = {
|
|
563
|
+
app_name: ['My Backend API'],
|
|
564
|
+
license_key: process.env.NEW_RELIC_LICENSE_KEY,
|
|
565
|
+
logging: { level: 'info' },
|
|
566
|
+
distributed_tracing: { enabled: true },
|
|
567
|
+
};
|
|
568
|
+
|
|
569
|
+
// Import at app entry
|
|
570
|
+
import 'newrelic';
|
|
571
|
+
```
|
|
572
|
+
|
|
573
|
+
**DataDog**
|
|
574
|
+
```typescript
|
|
575
|
+
import tracer from 'dd-trace';
|
|
576
|
+
|
|
577
|
+
tracer.init({
|
|
578
|
+
service: 'backend-api',
|
|
579
|
+
env: process.env.NODE_ENV,
|
|
580
|
+
version: '1.0.0',
|
|
581
|
+
logInjection: true
|
|
582
|
+
});
|
|
583
|
+
```
|
|
584
|
+
|
|
585
|
+
**Sentry (Error Tracking)**
|
|
586
|
+
```typescript
|
|
587
|
+
import * as Sentry from '@sentry/node';
|
|
588
|
+
|
|
589
|
+
Sentry.init({
|
|
590
|
+
dsn: process.env.SENTRY_DSN,
|
|
591
|
+
environment: process.env.NODE_ENV,
|
|
592
|
+
tracesSampleRate: 1.0,
|
|
593
|
+
});
|
|
594
|
+
|
|
595
|
+
// Capture errors
|
|
596
|
+
try {
|
|
597
|
+
await riskyOperation();
|
|
598
|
+
} catch (error) {
|
|
599
|
+
Sentry.captureException(error, {
|
|
600
|
+
user: { id: userId },
|
|
601
|
+
tags: { operation: 'payment' },
|
|
602
|
+
});
|
|
603
|
+
}
|
|
604
|
+
```
|
|
605
|
+
|
|
606
|
+
### Distributed Tracing
|
|
607
|
+
|
|
608
|
+
**OpenTelemetry (Vendor-Agnostic)**
|
|
609
|
+
```typescript
|
|
610
|
+
import { NodeSDK } from '@opentelemetry/sdk-node';
|
|
611
|
+
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
|
|
612
|
+
import { JaegerExporter } from '@opentelemetry/exporter-jaeger';
|
|
613
|
+
|
|
614
|
+
const sdk = new NodeSDK({
|
|
615
|
+
traceExporter: new JaegerExporter({
|
|
616
|
+
endpoint: 'http://localhost:14268/api/traces',
|
|
617
|
+
}),
|
|
618
|
+
instrumentations: [getNodeAutoInstrumentations()],
|
|
619
|
+
});
|
|
620
|
+
|
|
621
|
+
sdk.start();
|
|
622
|
+
|
|
623
|
+
// Traces HTTP, database, Redis automatically
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
### Log Aggregation
|
|
627
|
+
|
|
628
|
+
**ELK Stack (Elasticsearch, Logstash, Kibana)**
|
|
629
|
+
```yaml
|
|
630
|
+
# docker-compose.yml
|
|
631
|
+
version: '3'
|
|
632
|
+
services:
|
|
633
|
+
elasticsearch:
|
|
634
|
+
image: docker.elastic.co/elasticsearch/elasticsearch:8.11.0
|
|
635
|
+
environment:
|
|
636
|
+
- discovery.type=single-node
|
|
637
|
+
ports:
|
|
638
|
+
- 9200:9200
|
|
639
|
+
|
|
640
|
+
logstash:
|
|
641
|
+
image: docker.elastic.co/logstash/logstash:8.11.0
|
|
642
|
+
volumes:
|
|
643
|
+
- ./logstash.conf:/usr/share/logstash/pipeline/logstash.conf
|
|
644
|
+
|
|
645
|
+
kibana:
|
|
646
|
+
image: docker.elastic.co/kibana/kibana:8.11.0
|
|
647
|
+
ports:
|
|
648
|
+
- 5601:5601
|
|
649
|
+
```
|
|
650
|
+
|
|
651
|
+
**Loki + Grafana (Lightweight)**
|
|
652
|
+
```yaml
|
|
653
|
+
# promtail config for log shipping
|
|
654
|
+
server:
|
|
655
|
+
http_listen_port: 9080
|
|
656
|
+
|
|
657
|
+
positions:
|
|
658
|
+
filename: /tmp/positions.yaml
|
|
659
|
+
|
|
660
|
+
clients:
|
|
661
|
+
- url: http://loki:3100/loki/api/v1/push
|
|
662
|
+
|
|
663
|
+
scrape_configs:
|
|
664
|
+
- job_name: system
|
|
665
|
+
static_configs:
|
|
666
|
+
- targets:
|
|
667
|
+
- localhost
|
|
668
|
+
labels:
|
|
669
|
+
job: backend-api
|
|
670
|
+
__path__: /var/log/app/*.log
|
|
671
|
+
```
|
|
672
|
+
|
|
673
|
+
## Common Debugging Scenarios
|
|
674
|
+
|
|
675
|
+
### 1. High CPU Usage
|
|
676
|
+
|
|
677
|
+
**Steps:**
|
|
678
|
+
1. Profile CPU (flamegraph)
|
|
679
|
+
2. Identify hot functions
|
|
680
|
+
3. Check for:
|
|
681
|
+
- Infinite loops
|
|
682
|
+
- Heavy regex operations
|
|
683
|
+
- Inefficient algorithms (O(n²))
|
|
684
|
+
- Blocking operations in event loop (Node.js)
|
|
685
|
+
|
|
686
|
+
**Node.js Example:**
|
|
687
|
+
```typescript
|
|
688
|
+
// ❌ Bad: Blocking event loop
|
|
689
|
+
function fibonacci(n) {
|
|
690
|
+
if (n <= 1) return n;
|
|
691
|
+
return fibonacci(n - 1) + fibonacci(n - 2); // Exponential time
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
// ✅ Good: Memoized or iterative
|
|
695
|
+
const memo = new Map();
|
|
696
|
+
function fibonacciMemo(n) {
|
|
697
|
+
if (n <= 1) return n;
|
|
698
|
+
if (memo.has(n)) return memo.get(n);
|
|
699
|
+
const result = fibonacciMemo(n - 1) + fibonacciMemo(n - 2);
|
|
700
|
+
memo.set(n, result);
|
|
701
|
+
return result;
|
|
702
|
+
}
|
|
703
|
+
```
|
|
704
|
+
|
|
705
|
+
### 2. Memory Leaks
|
|
706
|
+
|
|
707
|
+
**Symptoms:**
|
|
708
|
+
- Memory usage grows over time
|
|
709
|
+
- Eventually crashes (OOM)
|
|
710
|
+
- Performance degradation
|
|
711
|
+
|
|
712
|
+
**Common Causes:**
|
|
713
|
+
```typescript
|
|
714
|
+
// ❌ Memory leak: Event listeners not removed
|
|
715
|
+
class DataService {
|
|
716
|
+
constructor(eventBus) {
|
|
717
|
+
eventBus.on('data', (data) => this.processData(data));
|
|
718
|
+
// Listener never removed, holds reference to DataService
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
// ✅ Fix: Remove listeners
|
|
723
|
+
class DataService {
|
|
724
|
+
constructor(eventBus) {
|
|
725
|
+
this.eventBus = eventBus;
|
|
726
|
+
this.handler = (data) => this.processData(data);
|
|
727
|
+
eventBus.on('data', this.handler);
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
destroy() {
|
|
731
|
+
this.eventBus.off('data', this.handler);
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
// ❌ Memory leak: Global cache without limits
|
|
736
|
+
const cache = new Map();
|
|
737
|
+
function getCachedData(key) {
|
|
738
|
+
if (!cache.has(key)) {
|
|
739
|
+
cache.set(key, expensiveOperation(key)); // Grows forever
|
|
740
|
+
}
|
|
741
|
+
return cache.get(key);
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
// ✅ Fix: LRU cache with size limit
|
|
745
|
+
import LRU from 'lru-cache';
|
|
746
|
+
const cache = new LRU({ max: 1000, ttl: 1000 * 60 * 60 });
|
|
747
|
+
```
|
|
748
|
+
|
|
749
|
+
**Detection:**
|
|
750
|
+
```bash
|
|
751
|
+
# Node.js: Check heap size over time
|
|
752
|
+
node --expose-gc --max-old-space-size=4096 app.js
|
|
753
|
+
|
|
754
|
+
# Take periodic heap snapshots
|
|
755
|
+
# Compare snapshots in Chrome DevTools
|
|
756
|
+
```
|
|
757
|
+
|
|
758
|
+
### 3. Slow Database Queries
|
|
759
|
+
|
|
760
|
+
**Steps:**
|
|
761
|
+
1. Enable slow query log
|
|
762
|
+
2. Analyze with EXPLAIN
|
|
763
|
+
3. Add indexes
|
|
764
|
+
4. Optimize query
|
|
765
|
+
|
|
766
|
+
**PostgreSQL Example:**
|
|
767
|
+
```sql
|
|
768
|
+
-- Before: Slow full table scan
|
|
769
|
+
SELECT * FROM orders
|
|
770
|
+
WHERE user_id = 123
|
|
771
|
+
ORDER BY created_at DESC
|
|
772
|
+
LIMIT 10;
|
|
773
|
+
|
|
774
|
+
-- EXPLAIN shows: Seq Scan on orders
|
|
775
|
+
|
|
776
|
+
-- Fix: Add index
|
|
777
|
+
CREATE INDEX idx_orders_user_id_created_at
|
|
778
|
+
ON orders(user_id, created_at DESC);
|
|
779
|
+
|
|
780
|
+
-- After: Index Scan using idx_orders_user_id_created_at
|
|
781
|
+
-- 100x faster
|
|
782
|
+
```
|
|
783
|
+
|
|
784
|
+
### 4. Connection Pool Exhaustion
|
|
785
|
+
|
|
786
|
+
**Symptoms:**
|
|
787
|
+
- "Connection pool exhausted" errors
|
|
788
|
+
- Requests hang indefinitely
|
|
789
|
+
- Database connections at max
|
|
790
|
+
|
|
791
|
+
**Causes & Fixes:**
|
|
792
|
+
```typescript
|
|
793
|
+
// ❌ Bad: Connection leak
|
|
794
|
+
async function getUser(id) {
|
|
795
|
+
const client = await pool.connect();
|
|
796
|
+
const result = await client.query('SELECT * FROM users WHERE id = $1', [id]);
|
|
797
|
+
return result.rows[0];
|
|
798
|
+
// Connection never released!
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
// ✅ Good: Always release
|
|
802
|
+
async function getUser(id) {
|
|
803
|
+
const client = await pool.connect();
|
|
804
|
+
try {
|
|
805
|
+
const result = await client.query('SELECT * FROM users WHERE id = $1', [id]);
|
|
806
|
+
return result.rows[0];
|
|
807
|
+
} finally {
|
|
808
|
+
client.release(); // Always release
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
// ✅ Better: Use pool directly
|
|
813
|
+
async function getUser(id) {
|
|
814
|
+
const result = await pool.query('SELECT * FROM users WHERE id = $1', [id]);
|
|
815
|
+
return result.rows[0];
|
|
816
|
+
// Automatically releases
|
|
817
|
+
}
|
|
818
|
+
```
|
|
819
|
+
|
|
820
|
+
### 5. Race Conditions
|
|
821
|
+
|
|
822
|
+
**Example:**
|
|
823
|
+
```typescript
|
|
824
|
+
// ❌ Bad: Race condition
|
|
825
|
+
let counter = 0;
|
|
826
|
+
|
|
827
|
+
async function incrementCounter() {
|
|
828
|
+
const current = counter; // Thread 1 reads 0
|
|
829
|
+
await doSomethingAsync(); // Thread 2 reads 0
|
|
830
|
+
counter = current + 1; // Thread 1 writes 1, Thread 2 writes 1
|
|
831
|
+
// Expected: 2, Actual: 1
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
// ✅ Fix: Atomic operations (Redis)
|
|
835
|
+
async function incrementCounter() {
|
|
836
|
+
return await redis.incr('counter');
|
|
837
|
+
// Atomic, thread-safe
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
// ✅ Fix: Database transactions
|
|
841
|
+
async function incrementCounter(userId) {
|
|
842
|
+
await db.transaction(async (trx) => {
|
|
843
|
+
const user = await trx('users')
|
|
844
|
+
.where({ id: userId })
|
|
845
|
+
.forUpdate() // Row-level lock
|
|
846
|
+
.first();
|
|
847
|
+
|
|
848
|
+
await trx('users')
|
|
849
|
+
.where({ id: userId })
|
|
850
|
+
.update({ counter: user.counter + 1 });
|
|
851
|
+
});
|
|
852
|
+
}
|
|
853
|
+
```
|
|
854
|
+
|
|
855
|
+
## Debugging Checklist
|
|
856
|
+
|
|
857
|
+
**Before Diving Into Code:**
|
|
858
|
+
- [ ] Read error message completely
|
|
859
|
+
- [ ] Check logs for context
|
|
860
|
+
- [ ] Reproduce the issue reliably
|
|
861
|
+
- [ ] Isolate the problem (binary search)
|
|
862
|
+
- [ ] Verify assumptions
|
|
863
|
+
|
|
864
|
+
**Investigation:**
|
|
865
|
+
- [ ] Enable debug logging
|
|
866
|
+
- [ ] Add strategic log points
|
|
867
|
+
- [ ] Use debugger breakpoints
|
|
868
|
+
- [ ] Profile performance if slow
|
|
869
|
+
- [ ] Check database queries
|
|
870
|
+
- [ ] Monitor system resources
|
|
871
|
+
|
|
872
|
+
**Production Issues:**
|
|
873
|
+
- [ ] Check APM dashboards
|
|
874
|
+
- [ ] Review distributed traces
|
|
875
|
+
- [ ] Analyze error rates
|
|
876
|
+
- [ ] Compare with previous baseline
|
|
877
|
+
- [ ] Check for recent deployments
|
|
878
|
+
- [ ] Review infrastructure changes
|
|
879
|
+
|
|
880
|
+
**After Fix:**
|
|
881
|
+
- [ ] Verify fix in development
|
|
882
|
+
- [ ] Add regression test
|
|
883
|
+
- [ ] Document the issue
|
|
884
|
+
- [ ] Deploy with monitoring
|
|
885
|
+
- [ ] Confirm fix in production
|
|
886
|
+
|
|
887
|
+
## Debugging Resources
|
|
888
|
+
|
|
889
|
+
**Tools:**
|
|
890
|
+
- Node.js: https://nodejs.org/en/docs/guides/debugging-getting-started/
|
|
891
|
+
- Chrome DevTools: https://developer.chrome.com/docs/devtools/
|
|
892
|
+
- Clinic.js: https://clinicjs.org/
|
|
893
|
+
- Sentry: https://docs.sentry.io/
|
|
894
|
+
- DataDog: https://docs.datadoghq.com/
|
|
895
|
+
- New Relic: https://docs.newrelic.com/
|
|
896
|
+
|
|
897
|
+
**Best Practices:**
|
|
898
|
+
- 12 Factor App Logs: https://12factor.net/logs
|
|
899
|
+
- Google SRE Book: https://sre.google/sre-book/table-of-contents/
|
|
900
|
+
- OpenTelemetry: https://opentelemetry.io/docs/
|
|
901
|
+
|
|
902
|
+
**Database:**
|
|
903
|
+
- PostgreSQL EXPLAIN: https://www.postgresql.org/docs/current/using-explain.html
|
|
904
|
+
- MongoDB Performance: https://www.mongodb.com/docs/manual/administration/analyzing-mongodb-performance/
|