History & Trends
Persistent storage and historical trend analysis (v0.5.0+)
SQLite Persistence
All analysis results are automatically persisted to a local SQLite database via better-sqlite3. The database is lazily initialized on first use and uses WAL mode for optimal read performance.
Database location: Controlled by SQLITE_PATH (default: ./storage/kafka-analyzer.db)
If the storage directory is not writable or better-sqlite3 fails to load, the system degrades gracefully — analysis continues without persistence.
Stored Data
| Table | Description |
|---|---|
analysis_records | Every analysis run with summary statistics |
anomaly_details | Per-anomaly details linked to analysis records |
lag_snapshots | Every get_lag result for trend analysis |
baselines | Auto (7-day rolling avg) and manual baselines |
Event-Driven Architecture
Persistence and baseline updates are decoupled from the analysis pipeline via an internal EventEmitter:
analyze_log completes → emit('analysis:completed')
├─→ persistence listener → write to SQLite → emit('analysis:persisted')
└─→ baseline listener → update auto baselines (7-day avg)
get_lag completes → emit('lag:completed')
└─→ persistence listener → write to lag_snapshotsListener errors are isolated — a failing listener logs the error but never interrupts the main analysis flow.
Anomaly Multiplier Detection
When analysis detects anomalies, the system automatically compares current values against stored baselines. If a value is ≥ 2× the baseline, the anomaly receives multiplier metadata:
⚠️ lag_spike [P0] consumer
3 partitions with lag > 10000 detected
🔺 比基线多 3.5 倍(基线: 2857, 当前: 10000, 来源: auto-7d)This happens synchronously before results are returned — no extra tool call needed.
MCP Tools
query_history
Query past analysis records with optional filters.
Parameters:
| Parameter | Type | Description |
|---|---|---|
from | string | Start time ISO 8601 (default: 7 days ago) |
to | string | End time ISO 8601 (default: now) |
source | string | Filter by source: paste / file / exporter / loki |
cluster | string | Filter by cluster name |
limit | number | Max results (default: 50, max: 200) |
compare_trend
Compare a metric across two time ranges.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
metric | string | Yes | error_rate / lag / anomaly_count / event_count |
current_range | string | Yes | 1h / 6h / 1d / 7d |
compare_range | string | No | previous / last_week / last_month (default: previous) |
cluster | string | No | Cluster name |
Output example:
{
"metric": "lag",
"current": { "range": "2026-07-04 ~ 2026-07-05", "avg": 8500, "max": 15000 },
"compare": { "range": "2026-07-03 ~ 2026-07-04", "avg": 3200, "max": 8000 },
"change": { "avgMultiplier": 2.66, "maxMultiplier": 1.88, "trend": "up" },
"summary": "平均Lag比对比时段2.66倍,峰值1.88倍,趋势上升"
}set_baseline
Manually set a metric baseline value, overriding any auto baseline.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
metric_key | string | Yes | e.g. lag:cluster:group:topic |
value | number | Yes | Baseline value |
metric_type | string | Yes | lag / error_rate / anomaly_count |
list_baselines
List all baselines, optionally filtered by metric type.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
metric_type | string | No | lag / error_rate / anomaly_count |
cleanup_storage
Clean up expired persisted data.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
retention_days | number | No | Retention in days (default: 30) |
dry_run | boolean | No | Preview only, no deletion (default: false) |
Baselines
Baselines define the "normal" value for a metric, used by multiplier detection.
- Auto baselines: Computed from 7-day rolling averages of historical data. Updated automatically after each analysis is persisted.
- Manual baselines: Set via
set_baselinetool. Override auto baselines for the same metric key.
When no baseline exists for a metric, multiplier detection is silently skipped.
Data Retention
By default, data older than 30 days is automatically cleaned up. This is configurable:
| Config | Env Var | Default | Description |
|---|---|---|---|
storageRetentionDays | STORAGE_RETENTION_DAYS | 30 | Days to retain |
storageAutoCleanup | STORAGE_AUTO_CLEANUP | true | Enable daily auto-cleanup |
Manual baselines are never auto-deleted. Auto baselines not updated within the retention window are removed.