@agimon-ai/log-sink-mcp 0.2.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/LICENSE +52 -0
- package/README.md +755 -0
- package/dist/cli.cjs +879 -0
- package/dist/cli.mjs +564 -0
- package/dist/index.cjs +1 -0
- package/dist/index.mjs +1 -0
- package/dist/stdio-J2VirkcY.mjs +70 -0
- package/dist/stdio-c5IGefy2.cjs +70 -0
- package/package.json +69 -0
package/README.md
ADDED
|
@@ -0,0 +1,755 @@
|
|
|
1
|
+
# log-sink-mcp
|
|
2
|
+
|
|
3
|
+
AI-powered log analysis MCP server with HTTP ingestion and SQLite storage.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
`log-sink-mcp` provides a complete log analysis solution for AI assistants like Claude. It combines:
|
|
8
|
+
|
|
9
|
+
- **HTTP Server**: REST endpoint for log ingestion from any application
|
|
10
|
+
- **MCP Server**: 7 AI-optimized tools for querying and analyzing logs
|
|
11
|
+
- **SQLite Database**: Fast local storage with FTS5 full-text search
|
|
12
|
+
- **Real-time Analysis**: Query logs, trace distributed requests, analyze error patterns
|
|
13
|
+
|
|
14
|
+
Perfect for debugging, monitoring, and understanding application behavior through AI-powered analysis.
|
|
15
|
+
|
|
16
|
+
## Features
|
|
17
|
+
|
|
18
|
+
- ✅ **HTTP Log Ingestion**: POST logs from any application via REST API
|
|
19
|
+
- ✅ **7 MCP Tools**: Query, search, trace, analyze, and manage logs
|
|
20
|
+
- ✅ **Full-Text Search**: Fast FTS5-powered search across messages and errors
|
|
21
|
+
- ✅ **Distributed Tracing**: Timeline view for trace IDs and span relationships
|
|
22
|
+
- ✅ **Error Analysis**: Pattern detection and error categorization
|
|
23
|
+
- ✅ **Structured Logging**: JSON metadata, trace IDs, span IDs
|
|
24
|
+
- ✅ **Auto-Migration**: Drizzle ORM with automatic schema migrations
|
|
25
|
+
- ✅ **Type-Safe**: Full TypeScript coverage with Drizzle schema inference
|
|
26
|
+
|
|
27
|
+
## Architecture
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
┌─────────────┐ HTTP POST ┌─────────────────┐
|
|
31
|
+
│ Application │ ───────────────────────> │ HTTP Server │
|
|
32
|
+
│ (Pino, │ /logs endpoint │ (Hono) │
|
|
33
|
+
│ Winston) │ │ Port 3100 │
|
|
34
|
+
└─────────────┘ └────────┬────────┘
|
|
35
|
+
│
|
|
36
|
+
▼
|
|
37
|
+
┌─────────────────┐
|
|
38
|
+
│ LogStorage │
|
|
39
|
+
│ Service │
|
|
40
|
+
└────────┬────────┘
|
|
41
|
+
│
|
|
42
|
+
▼
|
|
43
|
+
┌──────────────┐ MCP Protocol ┌─────────────────┐
|
|
44
|
+
│ Claude / │ <─────────────────────> │ MCP Server │
|
|
45
|
+
│ AI Agent │ 7 Analysis Tools │ (stdio) │
|
|
46
|
+
└──────────────┘ └────────┬────────┘
|
|
47
|
+
│
|
|
48
|
+
▼
|
|
49
|
+
┌─────────────────┐
|
|
50
|
+
│ SQLite + FTS5 │
|
|
51
|
+
│ ./logs/ │
|
|
52
|
+
│ session.db │
|
|
53
|
+
└─────────────────┘
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Singleton HTTP Server Management
|
|
57
|
+
|
|
58
|
+
`log-sink-mcp` implements automatic singleton coordination to prevent port conflicts when multiple MCP servers run concurrently.
|
|
59
|
+
|
|
60
|
+
### How It Works
|
|
61
|
+
|
|
62
|
+
1. **Service Discovery**: When an MCP server starts, it checks `.agiflow/registry/log-sink-mcp-http_{env}.json` for an existing HTTP server
|
|
63
|
+
2. **Health Check**: Pings `/health` endpoint to verify the registered server is alive
|
|
64
|
+
3. **Reuse or Start**: If healthy, reuses existing server; otherwise starts a new one
|
|
65
|
+
4. **PID Tracking**: Process IDs stored in `.pids/` for lifecycle management
|
|
66
|
+
5. **Auto-Cleanup**: Registry and PID files removed on graceful shutdown
|
|
67
|
+
|
|
68
|
+
### Service Registry Schema
|
|
69
|
+
|
|
70
|
+
```json
|
|
71
|
+
{
|
|
72
|
+
"name": "log-sink-mcp-http",
|
|
73
|
+
"port": 3100,
|
|
74
|
+
"host": "localhost",
|
|
75
|
+
"environment": "development",
|
|
76
|
+
"pid": 12345,
|
|
77
|
+
"status": "running",
|
|
78
|
+
"startedAt": "2026-01-15T10:00:00.000Z",
|
|
79
|
+
"metadata": {
|
|
80
|
+
"healthCheckUrl": "http://localhost:3100/health",
|
|
81
|
+
"dbPath": "./logs/session.db"
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Management Commands
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
# Check status of HTTP server
|
|
90
|
+
bun run src/cli.ts status
|
|
91
|
+
|
|
92
|
+
# Stop HTTP server
|
|
93
|
+
bun run src/cli.ts stop
|
|
94
|
+
|
|
95
|
+
# Start with auto-coordination
|
|
96
|
+
bun run src/cli.ts start
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Installation
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
# From monorepo root
|
|
103
|
+
pnpm install
|
|
104
|
+
|
|
105
|
+
# Or install globally
|
|
106
|
+
pnpm add -g log-sink-mcp
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Quick Start
|
|
110
|
+
|
|
111
|
+
### 1. Start the Servers
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
# Start both HTTP and MCP servers (recommended)
|
|
115
|
+
bun run src/cli.ts start
|
|
116
|
+
|
|
117
|
+
# Or start only HTTP server
|
|
118
|
+
bun run src/cli.ts start --http-only
|
|
119
|
+
|
|
120
|
+
# Or start only MCP server (stdio transport)
|
|
121
|
+
bun run src/cli.ts start --mcp-only
|
|
122
|
+
|
|
123
|
+
# With custom configuration
|
|
124
|
+
bun run src/cli.ts start --port 3100 --db-path ./logs/session.db
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
The `start` command uses singleton pattern - multiple MCP servers will share a single HTTP server automatically.
|
|
128
|
+
|
|
129
|
+
### 2. Configure MCP Server
|
|
130
|
+
|
|
131
|
+
Add to your `mcp-config.yaml`:
|
|
132
|
+
|
|
133
|
+
```yaml
|
|
134
|
+
mcpServers:
|
|
135
|
+
log-sink:
|
|
136
|
+
type: stdio
|
|
137
|
+
command: bun
|
|
138
|
+
args:
|
|
139
|
+
- ./packages/log-sink-mcp/src/cli.ts
|
|
140
|
+
- mcp-serve
|
|
141
|
+
- --db-path
|
|
142
|
+
- ./logs/session.db
|
|
143
|
+
disabled: false
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### 3. Send Logs
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
# Send a test log
|
|
150
|
+
curl -X POST http://localhost:3100/logs \
|
|
151
|
+
-H "Content-Type: application/json" \
|
|
152
|
+
-d '{
|
|
153
|
+
"logs": [{
|
|
154
|
+
"level": "info",
|
|
155
|
+
"message": "Application started",
|
|
156
|
+
"service": "my-app",
|
|
157
|
+
"metadata": {"version": "1.0.0"}
|
|
158
|
+
}]
|
|
159
|
+
}'
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### 4. Query with AI
|
|
163
|
+
|
|
164
|
+
Ask Claude:
|
|
165
|
+
|
|
166
|
+
> "Query all error logs from the database"
|
|
167
|
+
>
|
|
168
|
+
> "Show me the trace timeline for trace ID abc123"
|
|
169
|
+
>
|
|
170
|
+
> "Analyze error patterns in the logs"
|
|
171
|
+
|
|
172
|
+
## HTTP API Reference
|
|
173
|
+
|
|
174
|
+
### POST /logs
|
|
175
|
+
|
|
176
|
+
Ingest log entries in batch.
|
|
177
|
+
|
|
178
|
+
**Request Body:**
|
|
179
|
+
|
|
180
|
+
```typescript
|
|
181
|
+
{
|
|
182
|
+
logs: Array<{
|
|
183
|
+
// Required fields
|
|
184
|
+
level: 'debug' | 'info' | 'warn' | 'error';
|
|
185
|
+
message: string;
|
|
186
|
+
service: string;
|
|
187
|
+
|
|
188
|
+
// Optional fields
|
|
189
|
+
timestamp?: string; // ISO 8601, defaults to now
|
|
190
|
+
traceId?: string; // 32-char hex for distributed tracing
|
|
191
|
+
spanId?: string; // 16-char hex for span identification
|
|
192
|
+
parentSpanId?: string; // 16-char hex for parent span
|
|
193
|
+
hostname?: string;
|
|
194
|
+
pid?: number;
|
|
195
|
+
metadata?: Record<string, any>;
|
|
196
|
+
errorType?: string;
|
|
197
|
+
errorMessage?: string;
|
|
198
|
+
errorStack?: string;
|
|
199
|
+
}>
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
**Response (201 Created):**
|
|
204
|
+
|
|
205
|
+
```json
|
|
206
|
+
{
|
|
207
|
+
"success": true,
|
|
208
|
+
"count": 5,
|
|
209
|
+
"message": "Successfully inserted 5 logs"
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
**Response (400 Bad Request):**
|
|
214
|
+
|
|
215
|
+
```json
|
|
216
|
+
{
|
|
217
|
+
"success": false,
|
|
218
|
+
"error": "Validation failed",
|
|
219
|
+
"details": [...]
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### GET /health
|
|
224
|
+
|
|
225
|
+
Health check endpoint.
|
|
226
|
+
|
|
227
|
+
**Response (200 OK):**
|
|
228
|
+
|
|
229
|
+
```json
|
|
230
|
+
{
|
|
231
|
+
"status": "healthy",
|
|
232
|
+
"service": "log-sink-mcp",
|
|
233
|
+
"timestamp": "2026-01-15T10:00:00.000Z"
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
## MCP Tools Reference
|
|
238
|
+
|
|
239
|
+
### 1. `query_logs`
|
|
240
|
+
|
|
241
|
+
Filter logs by level, service, or trace ID.
|
|
242
|
+
|
|
243
|
+
**Parameters:**
|
|
244
|
+
- `level?`: string - Filter by log level (debug, info, warn, error)
|
|
245
|
+
- `service?`: string - Filter by service name
|
|
246
|
+
- `traceId?`: string - Filter by trace ID
|
|
247
|
+
- `limit?`: number - Maximum results (default: 100)
|
|
248
|
+
|
|
249
|
+
**Example:**
|
|
250
|
+
```
|
|
251
|
+
Query all error logs from user-service
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
**Returns:** JSON array of matching log entries with timestamps, messages, metadata.
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
258
|
+
### 2. `search_logs`
|
|
259
|
+
|
|
260
|
+
Full-text search across log messages and error messages.
|
|
261
|
+
|
|
262
|
+
**Parameters:**
|
|
263
|
+
- `searchQuery`: string (required) - Text to search for
|
|
264
|
+
- `limit?`: number - Maximum results (default: 50)
|
|
265
|
+
|
|
266
|
+
**Example:**
|
|
267
|
+
```
|
|
268
|
+
Search logs for "database connection timeout"
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
**Returns:** Matching logs with search relevance, count of results.
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
275
|
+
### 3. `get_trace_timeline`
|
|
276
|
+
|
|
277
|
+
Get chronological timeline for a distributed trace.
|
|
278
|
+
|
|
279
|
+
**Parameters:**
|
|
280
|
+
- `traceId`: string (required) - Trace ID to retrieve
|
|
281
|
+
|
|
282
|
+
**Example:**
|
|
283
|
+
```
|
|
284
|
+
Show me the trace timeline for trace ID a1b2c3d4e5f6789012345678901234ab
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
**Returns:** Ordered sequence of log entries for the trace, showing service call flow.
|
|
288
|
+
|
|
289
|
+
---
|
|
290
|
+
|
|
291
|
+
### 4. `analyze_errors`
|
|
292
|
+
|
|
293
|
+
Analyze error patterns and categorize by error type.
|
|
294
|
+
|
|
295
|
+
**Parameters:**
|
|
296
|
+
- `limit?`: number - Maximum errors to analyze (default: 100)
|
|
297
|
+
|
|
298
|
+
**Example:**
|
|
299
|
+
```
|
|
300
|
+
Analyze error patterns in the logs
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
**Returns:** Error categories, frequencies, example stack traces, common patterns.
|
|
304
|
+
|
|
305
|
+
---
|
|
306
|
+
|
|
307
|
+
### 5. `get_log_stats`
|
|
308
|
+
|
|
309
|
+
Get statistics grouped by log level.
|
|
310
|
+
|
|
311
|
+
**Parameters:** None
|
|
312
|
+
|
|
313
|
+
**Example:**
|
|
314
|
+
```
|
|
315
|
+
Show me log statistics
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
**Returns:** Count per log level (debug, info, warn, error), total count.
|
|
319
|
+
|
|
320
|
+
---
|
|
321
|
+
|
|
322
|
+
### 6. `get_services`
|
|
323
|
+
|
|
324
|
+
List all unique services that have logged.
|
|
325
|
+
|
|
326
|
+
**Parameters:** None
|
|
327
|
+
|
|
328
|
+
**Example:**
|
|
329
|
+
```
|
|
330
|
+
What services are logging to the database?
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
**Returns:** Array of service names with log counts.
|
|
334
|
+
|
|
335
|
+
---
|
|
336
|
+
|
|
337
|
+
### 7. `clear_logs`
|
|
338
|
+
|
|
339
|
+
Delete all logs from the database.
|
|
340
|
+
|
|
341
|
+
**Parameters:** None
|
|
342
|
+
|
|
343
|
+
**Example:**
|
|
344
|
+
```
|
|
345
|
+
Clear all logs from the database
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
**Returns:** Confirmation with count of deleted entries.
|
|
349
|
+
|
|
350
|
+
⚠️ **Warning:** This operation cannot be undone.
|
|
351
|
+
|
|
352
|
+
## Integration Examples
|
|
353
|
+
|
|
354
|
+
### Pino Logger
|
|
355
|
+
|
|
356
|
+
```typescript
|
|
357
|
+
import pino from 'pino';
|
|
358
|
+
|
|
359
|
+
const logger = pino({
|
|
360
|
+
transport: {
|
|
361
|
+
target: 'pino-http-send',
|
|
362
|
+
options: {
|
|
363
|
+
url: 'http://localhost:3100/logs',
|
|
364
|
+
method: 'POST',
|
|
365
|
+
},
|
|
366
|
+
},
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
logger.info({ traceId: 'abc123', userId: '456' }, 'User logged in');
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
### Winston Logger
|
|
373
|
+
|
|
374
|
+
```typescript
|
|
375
|
+
import winston from 'winston';
|
|
376
|
+
|
|
377
|
+
const logger = winston.createLogger({
|
|
378
|
+
transports: [
|
|
379
|
+
new winston.transports.Http({
|
|
380
|
+
host: 'localhost',
|
|
381
|
+
port: 3100,
|
|
382
|
+
path: '/logs',
|
|
383
|
+
}),
|
|
384
|
+
],
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
logger.error('Database connection failed', {
|
|
388
|
+
service: 'api',
|
|
389
|
+
errorType: 'ConnectionError'
|
|
390
|
+
});
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
### Custom Fetch
|
|
394
|
+
|
|
395
|
+
```typescript
|
|
396
|
+
async function sendLog(level: string, message: string, metadata?: any) {
|
|
397
|
+
await fetch('http://localhost:3100/logs', {
|
|
398
|
+
method: 'POST',
|
|
399
|
+
headers: { 'Content-Type': 'application/json' },
|
|
400
|
+
body: JSON.stringify({
|
|
401
|
+
logs: [{
|
|
402
|
+
level,
|
|
403
|
+
message,
|
|
404
|
+
service: 'my-service',
|
|
405
|
+
metadata,
|
|
406
|
+
timestamp: new Date().toISOString(),
|
|
407
|
+
}],
|
|
408
|
+
}),
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
await sendLog('info', 'Request processed', { duration: 245, status: 200 });
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
## Configuration
|
|
416
|
+
|
|
417
|
+
### CLI Options
|
|
418
|
+
|
|
419
|
+
#### `start` command (Recommended)
|
|
420
|
+
|
|
421
|
+
Start HTTP and/or MCP servers with automatic singleton coordination.
|
|
422
|
+
|
|
423
|
+
```bash
|
|
424
|
+
bun run src/cli.ts start [options]
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
Options:
|
|
428
|
+
- `--port <number>`: HTTP server port (default: 3100)
|
|
429
|
+
- `--db-path <path>`: SQLite database path (default: ./logs/session.db)
|
|
430
|
+
- `--in-memory`: Use in-memory database for testing (default: false)
|
|
431
|
+
- `--http-only`: Start only the HTTP server
|
|
432
|
+
- `--mcp-only`: Start only the MCP server (stdio transport)
|
|
433
|
+
|
|
434
|
+
Examples:
|
|
435
|
+
```bash
|
|
436
|
+
# Start both servers with defaults
|
|
437
|
+
bun run src/cli.ts start
|
|
438
|
+
|
|
439
|
+
# Production mode with persistent database
|
|
440
|
+
bun run src/cli.ts start --port 3100 --db-path ./logs/production.db
|
|
441
|
+
|
|
442
|
+
# Testing with in-memory database
|
|
443
|
+
bun run src/cli.ts start --in-memory
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
#### `status` command
|
|
447
|
+
|
|
448
|
+
Show diagnostic information about running services.
|
|
449
|
+
|
|
450
|
+
```bash
|
|
451
|
+
bun run src/cli.ts status
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
Displays:
|
|
455
|
+
- HTTP server status (running/stopped)
|
|
456
|
+
- Process ID and port
|
|
457
|
+
- Database file path and size
|
|
458
|
+
- Health check URL
|
|
459
|
+
|
|
460
|
+
#### `stop` command
|
|
461
|
+
|
|
462
|
+
Gracefully stop HTTP server and cleanup registry/PID files.
|
|
463
|
+
|
|
464
|
+
```bash
|
|
465
|
+
bun run src/cli.ts stop
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
Behavior:
|
|
469
|
+
- Sends SIGTERM to HTTP server process
|
|
470
|
+
- Removes `.agiflow/registry/` entries
|
|
471
|
+
- Cleans up `.pids/` files
|
|
472
|
+
|
|
473
|
+
#### `http-serve` command
|
|
474
|
+
|
|
475
|
+
Manually start HTTP log ingestion server (for advanced use).
|
|
476
|
+
|
|
477
|
+
```bash
|
|
478
|
+
bun run src/cli.ts http-serve [options]
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
Options:
|
|
482
|
+
- `--port <number>`: HTTP server port (default: 3000)
|
|
483
|
+
- `--db-path <path>`: SQLite database path (default: ./logs.db)
|
|
484
|
+
- `--in-memory`: Use in-memory database (default: false)
|
|
485
|
+
|
|
486
|
+
**Note:** Prefer using `start` command for automatic singleton coordination.
|
|
487
|
+
|
|
488
|
+
#### `mcp-serve` command
|
|
489
|
+
|
|
490
|
+
Manually start MCP server (for advanced use or custom transports).
|
|
491
|
+
|
|
492
|
+
```bash
|
|
493
|
+
bun run src/cli.ts mcp-serve [options]
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
Options:
|
|
497
|
+
- `--type <type>`: Transport type: stdio, http, or sse (default: stdio)
|
|
498
|
+
- `--port <number>`: Port for http/sse transport (default: 3000)
|
|
499
|
+
- `--host <host>`: Host for http/sse transport (default: localhost)
|
|
500
|
+
- `--db-path <path>`: SQLite database path (default: ./logs/session.db)
|
|
501
|
+
- `--in-memory`: Use in-memory database (default: false)
|
|
502
|
+
- `--cleanup`: Stop HTTP server on MCP shutdown (stdio only, default: false)
|
|
503
|
+
|
|
504
|
+
Examples:
|
|
505
|
+
```bash
|
|
506
|
+
# stdio transport (for Claude Desktop)
|
|
507
|
+
bun run src/cli.ts mcp-serve --type stdio
|
|
508
|
+
|
|
509
|
+
# HTTP transport
|
|
510
|
+
bun run src/cli.ts mcp-serve --type http --port 3001
|
|
511
|
+
|
|
512
|
+
# SSE transport
|
|
513
|
+
bun run src/cli.ts mcp-serve --type sse --port 3002
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
**Note:** For stdio transport, prefer using `start --mcp-only` for automatic HTTP coordination.
|
|
517
|
+
|
|
518
|
+
#### `logs` command
|
|
519
|
+
|
|
520
|
+
Run the same analysis capabilities exposed by the package MCP tools directly from the shell.
|
|
521
|
+
|
|
522
|
+
```bash
|
|
523
|
+
bun run src/cli.ts logs <subcommand> [options]
|
|
524
|
+
```
|
|
525
|
+
|
|
526
|
+
Subcommands:
|
|
527
|
+
- `query`: Equivalent to `query_logs`
|
|
528
|
+
- `search`: Equivalent to `search_logs`
|
|
529
|
+
- `trace`: Equivalent to `get_trace_timeline`
|
|
530
|
+
- `analyze-errors`: Equivalent to `analyze_errors`
|
|
531
|
+
- `stats`: Equivalent to `get_log_stats`
|
|
532
|
+
- `services`: Equivalent to `get_services`
|
|
533
|
+
- `clear`: Equivalent to `clear_logs`
|
|
534
|
+
|
|
535
|
+
All subcommands support:
|
|
536
|
+
- `--db-path <path>`: SQLite database path (default: `./logs/session.db`)
|
|
537
|
+
- `--in-memory`: Use an in-memory database
|
|
538
|
+
|
|
539
|
+
Examples:
|
|
540
|
+
|
|
541
|
+
```bash
|
|
542
|
+
# Query error logs
|
|
543
|
+
bun run src/cli.ts logs query --level error --db-path ./logs/session.db
|
|
544
|
+
|
|
545
|
+
# Search for timeout failures
|
|
546
|
+
bun run src/cli.ts logs search "timeout OR retry" --service api-gateway user-service
|
|
547
|
+
|
|
548
|
+
# Inspect one trace
|
|
549
|
+
bun run src/cli.ts logs trace a1b2c3d4e5f6789012345678901234ab
|
|
550
|
+
|
|
551
|
+
# Analyze grouped errors in a time window
|
|
552
|
+
bun run src/cli.ts logs analyze-errors \
|
|
553
|
+
--start-time 2026-01-15T10:00:00Z \
|
|
554
|
+
--end-time 2026-01-15T11:00:00Z
|
|
555
|
+
|
|
556
|
+
# View service names discovered in the log database
|
|
557
|
+
bun run src/cli.ts logs services
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
### Environment Variables
|
|
561
|
+
|
|
562
|
+
None required. All configuration via CLI flags.
|
|
563
|
+
|
|
564
|
+
## Development
|
|
565
|
+
|
|
566
|
+
### Setup
|
|
567
|
+
|
|
568
|
+
```bash
|
|
569
|
+
# Install dependencies
|
|
570
|
+
pnpm install
|
|
571
|
+
|
|
572
|
+
# Run development server
|
|
573
|
+
pnpm dev
|
|
574
|
+
|
|
575
|
+
# Run HTTP server in dev mode
|
|
576
|
+
bun run src/cli.ts http-serve --port 3100
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
### Project Structure
|
|
580
|
+
|
|
581
|
+
```
|
|
582
|
+
log-sink-mcp/
|
|
583
|
+
├── src/
|
|
584
|
+
│ ├── cli.ts # CLI entry point
|
|
585
|
+
│ ├── commands/ # CLI commands
|
|
586
|
+
│ │ ├── http-serve.ts # HTTP server command
|
|
587
|
+
│ │ └── mcp-serve.ts # MCP server command
|
|
588
|
+
│ ├── container/ # InversifyJS DI container
|
|
589
|
+
│ ├── models/ # Drizzle schemas
|
|
590
|
+
│ │ └── schema.ts # Log table schema
|
|
591
|
+
│ ├── server/
|
|
592
|
+
│ │ ├── http.ts # Hono HTTP server
|
|
593
|
+
│ │ └── index.ts # MCP server
|
|
594
|
+
│ ├── services/ # Business logic
|
|
595
|
+
│ │ ├── LogStorageService.ts
|
|
596
|
+
│ │ ├── LogQueryService.ts
|
|
597
|
+
│ │ ├── LogSearchService.ts
|
|
598
|
+
│ │ └── LogRetentionService.ts
|
|
599
|
+
│ ├── tools/ # MCP tools
|
|
600
|
+
│ │ ├── QueryLogsTool.ts
|
|
601
|
+
│ │ ├── SearchLogsTool.ts
|
|
602
|
+
│ │ ├── GetTraceTimelineTool.ts
|
|
603
|
+
│ │ ├── AnalyzeErrorsTool.ts
|
|
604
|
+
│ │ ├── GetLogStatsTool.ts
|
|
605
|
+
│ │ ├── GetServicesTool.ts
|
|
606
|
+
│ │ └── ClearLogsTool.ts
|
|
607
|
+
│ └── types/ # TypeScript types
|
|
608
|
+
├── migrations/ # Drizzle migrations
|
|
609
|
+
├── tests/
|
|
610
|
+
│ ├── integration/ # Integration tests
|
|
611
|
+
│ ├── services/ # Service unit tests
|
|
612
|
+
│ ├── tools/ # Tool unit tests
|
|
613
|
+
│ └── commands/ # Command tests
|
|
614
|
+
└── README.md
|
|
615
|
+
```
|
|
616
|
+
|
|
617
|
+
### Testing
|
|
618
|
+
|
|
619
|
+
```bash
|
|
620
|
+
# Run all tests
|
|
621
|
+
pnpm test
|
|
622
|
+
|
|
623
|
+
# Run integration tests only
|
|
624
|
+
pnpm test integration
|
|
625
|
+
|
|
626
|
+
# Run with coverage
|
|
627
|
+
pnpm test --coverage
|
|
628
|
+
```
|
|
629
|
+
|
|
630
|
+
**Test Coverage:**
|
|
631
|
+
- HTTP server integration tests (8 tests)
|
|
632
|
+
- MCP tools integration tests (17 tests)
|
|
633
|
+
- Command tests (5 tests)
|
|
634
|
+
|
|
635
|
+
### Adding New Tools
|
|
636
|
+
|
|
637
|
+
1. Create tool class in `src/tools/`
|
|
638
|
+
2. Implement `Tool` interface with `getDefinition()` and `execute()`
|
|
639
|
+
3. Register in `src/server/index.ts`
|
|
640
|
+
4. Add integration tests in `tests/integration/`
|
|
641
|
+
|
|
642
|
+
See existing tools for patterns.
|
|
643
|
+
|
|
644
|
+
## Troubleshooting
|
|
645
|
+
|
|
646
|
+
### Check Service Status
|
|
647
|
+
|
|
648
|
+
Use the `status` command to diagnose issues:
|
|
649
|
+
|
|
650
|
+
```bash
|
|
651
|
+
bun run src/cli.ts status
|
|
652
|
+
```
|
|
653
|
+
|
|
654
|
+
This shows:
|
|
655
|
+
- Whether HTTP server is running
|
|
656
|
+
- Process ID and port
|
|
657
|
+
- Database path and size
|
|
658
|
+
- Health check URL
|
|
659
|
+
|
|
660
|
+
### Logs not appearing
|
|
661
|
+
|
|
662
|
+
1. Check HTTP server is running:
|
|
663
|
+
```bash
|
|
664
|
+
# Using status command
|
|
665
|
+
bun run src/cli.ts status
|
|
666
|
+
|
|
667
|
+
# Or direct health check
|
|
668
|
+
curl http://localhost:3100/health
|
|
669
|
+
```
|
|
670
|
+
|
|
671
|
+
2. Verify log format matches API schema
|
|
672
|
+
3. Check database path is accessible
|
|
673
|
+
4. Review HTTP server logs for errors
|
|
674
|
+
|
|
675
|
+
### MCP tools not working
|
|
676
|
+
|
|
677
|
+
1. Verify database file exists and has logs:
|
|
678
|
+
```bash
|
|
679
|
+
bun run src/cli.ts status
|
|
680
|
+
```
|
|
681
|
+
|
|
682
|
+
2. Check `--db-path` matches between HTTP and MCP servers
|
|
683
|
+
3. Restart MCP server after configuration changes:
|
|
684
|
+
```bash
|
|
685
|
+
bun run src/cli.ts stop
|
|
686
|
+
bun run src/cli.ts start
|
|
687
|
+
```
|
|
688
|
+
|
|
689
|
+
### Database locked errors
|
|
690
|
+
|
|
691
|
+
SQLite uses WAL mode for better concurrency, but:
|
|
692
|
+
- Don't run multiple HTTP servers on same database
|
|
693
|
+
- Ensure file permissions allow writes
|
|
694
|
+
- Use separate databases for testing
|
|
695
|
+
|
|
696
|
+
### Finding and Killing HTTP Server
|
|
697
|
+
|
|
698
|
+
If you need to manually stop the HTTP server:
|
|
699
|
+
|
|
700
|
+
```bash
|
|
701
|
+
# Graceful stop (recommended)
|
|
702
|
+
bun run src/cli.ts stop
|
|
703
|
+
|
|
704
|
+
# Find process manually
|
|
705
|
+
cat .pids/log-sink-mcp-http-development.pid
|
|
706
|
+
|
|
707
|
+
# Kill process (if graceful stop fails)
|
|
708
|
+
kill $(cat .pids/log-sink-mcp-http-development.pid)
|
|
709
|
+
|
|
710
|
+
# Force kill (last resort)
|
|
711
|
+
kill -9 $(cat .pids/log-sink-mcp-http-development.pid)
|
|
712
|
+
```
|
|
713
|
+
|
|
714
|
+
### Stale Registry Entries
|
|
715
|
+
|
|
716
|
+
If the registry file exists but server isn't running:
|
|
717
|
+
|
|
718
|
+
```bash
|
|
719
|
+
# Clean up stale registry
|
|
720
|
+
rm .agiflow/registry/log-sink-mcp-http_development.json
|
|
721
|
+
rm .pids/log-sink-mcp-http-development.pid
|
|
722
|
+
|
|
723
|
+
# Restart
|
|
724
|
+
bun run src/cli.ts start
|
|
725
|
+
```
|
|
726
|
+
|
|
727
|
+
The health check will automatically detect stale registries and start a new server.
|
|
728
|
+
|
|
729
|
+
### Port Already in Use
|
|
730
|
+
|
|
731
|
+
If port 3100 is already taken:
|
|
732
|
+
|
|
733
|
+
```bash
|
|
734
|
+
# Use different port
|
|
735
|
+
bun run src/cli.ts start --port 3101
|
|
736
|
+
|
|
737
|
+
# Or find what's using the port
|
|
738
|
+
lsof -i :3100
|
|
739
|
+
|
|
740
|
+
# Kill the process using the port
|
|
741
|
+
kill $(lsof -t -i :3100)
|
|
742
|
+
```
|
|
743
|
+
|
|
744
|
+
## License
|
|
745
|
+
|
|
746
|
+
MIT
|
|
747
|
+
|
|
748
|
+
## Contributing
|
|
749
|
+
|
|
750
|
+
This package is part of the Agiflow monorepo. Contributions welcome!
|
|
751
|
+
|
|
752
|
+
1. Follow coding standards in `/docs/CODING_STANDARDS.md`
|
|
753
|
+
2. Use architect MCP before modifying code
|
|
754
|
+
3. Add tests for new features
|
|
755
|
+
4. Run `pnpm test` before committing
|