Log-Observer & Monitor
A high-performance, real-time log aggregation CLI tool with a live web dashboard.
Features Β· Install Β· Quick Start Β· Dashboard Β· Config Β· Architecture
- π Multi-source Tailing β Watch multiple log files or entire directories simultaneously
- π Structured Parsing β Auto-detect JSON, Common Log Format, or use custom Regex patterns
- β‘ High Throughput β 500Kβ970K lines/sec parsing, <50MB RAM via Go's concurrency pipeline
- π Live Dashboard β Real-time WebSocket-powered UI for log trends, error rates, and EPS metrics
- π Resilient Rotation β Automatic reconnection on log file rotation with state checkpointing
- π¦ Single Binary β Frontend assets embedded via
go:embedβ no external dependencies at runtime - π¬ Built-in Profiling β
pprofendpoints for CPU/memory analysis in production
git clone https://github.com/atikulmunna/loom.git
cd loom
go build -o loom ./cmd/loomgo install github.com/atikulmunna/loom/cmd/loom@latestloom watch /var/log/app.logloom watch "/var/log/**/*.log"loom watch /var/log/app.log --level error,warn# Apache/Nginx Common Log Format
loom watch /var/log/nginx/access.log --format clf
# Custom regex with named capture groups
loom watch app.log --format regex --pattern '^(?P<timestamp>\S+) (?P<level>\w+) (?P<message>.+)$'loom watch /var/log/app.log --output json | jq '.level == "ERROR"'loom watch /var/log/app.log --serve --port 8080Then open http://localhost:8080 in your browser.
| Metric | Description |
|---|---|
| Events/sec | Live throughput gauge |
| Error/Warning Count | Running totals of ERROR and WARN entries |
| Log Stream | Filterable, color-coded live log feed with severity toggles |
| Uptime & File Count | How long Loom has been running and how many files are watched |
| Route | Description |
|---|---|
GET / |
Dashboard UI |
GET /healthz |
JSON health check |
GET /api/stats |
Aggregator metrics snapshot |
GET /ws |
WebSocket log stream |
GET /debug/pprof/* |
pprof profiling endpoints |
Loom uses a YAML config file. Default location: ~/.loom.yaml
# ~/.loom.yaml
watch:
paths:
- /var/log/app/*.log
- /var/log/nginx/access.log
recursive: true
parser:
format: auto # auto | json | clf | regex
custom_regex: '^(?P<timestamp>\S+) (?P<level>\w+) (?P<message>.+)$'
server:
enabled: true
port: 8080| Flag | Short | Description | Default |
|---|---|---|---|
--level |
-l |
Filter by log severity | all |
--output |
-o |
Output format (text, json) |
text |
--format |
-f |
Parser format (auto, json, clf, regex) |
auto |
--pattern |
-p |
Custom regex pattern (with --format regex) |
β |
--serve |
-s |
Enable web dashboard | false |
--port |
Dashboard port | 8080 |
|
--config |
-c |
Config file path | ~/.loom.yaml |
Loom uses a Fan-in concurrency pipeline built on Go channels:
ββββββββββββββββ
β Log File A ββββ
ββββββββββββββββ β ββββββββββββ βββββββββββ ββββββββββββββββββ
βββββΆβ Tailer βββββΆβ Hub βββββΆβ CLI Output β
ββββββββββββββββ β β(Raw Lines)β β(Parse + β ββββββββββββββββββ€
β Log File B ββββ€ ββββββββββββ βBroadcast)β β WebSocket UI β
ββββββββββββββββ β ββββββ¬βββββ ββββββββββββββββββ€
β β β Aggregator β
ββββββββββββββββ β βΌ ββββββββββββββββββ
β Log File N ββββ ββββββββββββ
ββββββββββββββββ β Parser β
Watcher β(JSON/CLF/β
(fsnotify) βRegex/Auto)β
ββββββββββββ
| Component | Responsibility |
|---|---|
| Watcher | OS-level file notifications via fsnotify, glob pattern support |
| Tailer | Offset-based tailing with checkpointing, rotation reconnect |
| Parser | JSON, CLF, Regex, or Auto-detect structured log parsing |
| Hub | Central channel-based broadcaster with backpressure drop policy |
| Aggregator | Time-windowed metrics: EPS, level counts, uptime |
| Server | Gin web server with go:embed, WebSocket, and pprof |
| Category | Technology |
|---|---|
| Language | Go 1.22+ |
| CLI Framework | Cobra |
| Config | Viper |
| File Watching | fsnotify |
| Web Server | Gin |
| WebSocket | Gorilla WebSocket |
| TUI Styling | Lip Gloss |
| Profiling | pprof |
# Run all tests (18 tests across 5 packages)
go test ./...
# Run with coverage
go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.out
# Run benchmarks
go test -bench=. -benchmem ./internal/parser/
go test -bench=. -benchmem ./internal/hub/Benchmarked on AMD Ryzen 9 8945HX (Windows, amd64):
| Parser | ops/sec | ns/op | allocs/op |
|---|---|---|---|
| Regex | 969K | 1,033 | 4 |
| CLF | 729K | 1,372 | 4 |
| Auto-detect | 714K | 1,401 | 8 |
| JSON | 474K | 2,108 | 35 |
| Mixed (throughput) | 583K | 1,715 | 7 |
| Subscribers | ops/sec | ns/op | allocs/op |
|---|---|---|---|
| 1 | 7.9M | 126 | 2 |
| 5 | 13.3M | 101 | 2 |
| 10 | 9.2M | 143 | 2 |
- Phase 1 β Core engine (Watcher, Tail, Checkpointing)
- Phase 2 β Processing pipeline (Parser, Hub, Filtering)
- Phase 3 β Web dashboard (Gin, WebSocket, go:embed)
- Phase 4 β Hardening (Tests, Profiling, Benchmarks)
- Phase 5 β Alerting (Threshold triggers, webhook/Slack notifications)
Contributions are welcome! Please follow these steps:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'feat: add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Please use Conventional Commits for commit messages.
This project is licensed under the MIT License β see the LICENSE file for details.
Built with β and Go
