9.0 KiB
Jakach Logging
A self-hosted log analysis and alerting system. Ingests logs from files, TCP/UDP syslog, and HTTP, evaluates them against configurable rules, notifies via Telegram, and provides a Bootstrap web UI for management.
Architecture
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Log Files │ │ TCP/UDP │ │ HTTP POST │
│ (tail -f) │ │ syslog │ │ /ingest │
└──────┬───────┘ └──────┬───────┘ └──────┬───────┘
│ │ │
└─────────────────┼──────────────────┘
│
┌──────────▼──────────┐
│ Worker (PHP-CLI) │
│ FileWatcher │
│ SocketListener │
└──────────┬──────────┘
│
┌──────────▼──────────┐
│ Rule Engine │
│ preg_match rules │
│ Rate Limiter │
└──────────┬──────────┘
│
┌──────────▼──────────┐
│ TelegramNotifier │
└──────────┬──────────┘
│
┌──────────▼──────────┐
│ SQLite Database │
│ (FTS5 full-text) │
└──────────┬──────────┘
│
┌──────────▼──────────┐
│ API (PHP-FPM) │
│ REST + Auth │
└──────────┬──────────┘
│
┌──────────▼──────────┐
│ Web UI (Bootstrap)│
│ nginx :8080 │
└─────────────────────┘
Quick Start
# Clone and start
git clone <repo> jakach-logging
cd jakach-logging
docker compose build --no-cache && docker compose up -d
# Seed default rules and syslog sources
docker compose exec api php bin/seed
# Open the UI
open http://localhost:8080
Set ALLOW_FIRST_USER_BOOTSTRAP=true only during initial setup if you want the first Jakach Auth user to be automatically added as admin.
Authentication
Uses Jakach Login for authentication. Users authenticate via auth.jakach.ch. Authorized users must have their user_token added in Settings > Security. First-user auto-authorization is disabled unless ALLOW_FIRST_USER_BOOTSTRAP=true is set for initial setup.
Log Sources (Ingestion)
File sources
curl -X POST http://localhost:8080/sources \
-H 'Content-Type: application/json' \
-d '{"name":"nginx-access","type":"file","address":"/var/log/nginx/access.log"}'
Supports glob patterns: "/collect/*.log"
TCP/UDP syslog
The worker already listens on :9514 (TCP and UDP). Add the source via UI or:
curl -X POST http://localhost:8080/sources \
-H 'Content-Type: application/json' \
-d '{"name":"syslog","type":"tcp","address":"tcp://0.0.0.0:9514"}'
Other containers can send logs via Docker syslog driver:
services:
my-app:
logging:
driver: syslog
options:
syslog-address: "tcp://<host>:9514"
tag: "my-app"
HTTP POST
/ingest requires an authenticated session and CSRF token. For unauthenticated service-to-service ingestion, put it behind a trusted reverse proxy or add a dedicated ingest-token flow before exposing it publicly.
Shared volume
services:
my-app:
volumes:
- jakach-logging_log_collect:/collect
Files written to /collect/*.log are automatically picked up by the worker.
Alert Rules
Default rules (created by bin/seed):
| Rule | Pattern | Severity |
|---|---|---|
| PHP Fatal Error | /PHP Fatal/i |
critical_high |
| PHP Exception | /Uncaught (Exception|Error)/ |
critical |
| PHP Warning | /PHP (Warning|Notice)/i |
warning |
| HTTP 5xx | /" (50[0-9]) / |
critical |
| HTTP 4xx | /" (4[0-9]{2}) / |
warning_low |
| Failed Login | /Failed (login|password|authentication)/i |
critical_low |
| Out of Memory | /out of memory|OutOfMemory/i |
emergency |
| Connection Refused | /Connection (refused|reset|timed? out)/i |
warning_high |
| Disk Space | /disk (full|space|usage|low)/i |
critical_low |
| Service Started | /service started|daemon started|ready to serve/i |
notice |
| Slow Query | /slow (query|request|response)/i |
warning_high |
Rules use PHP regex. Add custom rules via UI or API:
curl -X POST http://localhost:8080/rules \
-H 'Content-Type: application/json' \
-d '{"name":"SSH Login","pattern":"/sshd.*Accepted/i","severity":"notice"}'
Each rule can have a rate_limit_seconds to prevent alert storms.
Severity Levels
debug → info → notice → warning_low → warning → warning_high → error → critical_low → critical → critical_high → emergency
Telegram Notifications
Configure in Settings > Telegram Notifications:
- Create a bot via @BotFather on Telegram
- Get your chat ID (send a message to your bot, visit
https://api.telegram.org/bot<token>/getUpdates) - Enter bot token and chat ID in settings, click Save, then Test
Alerts Workflow
- Open — newly triggered, shown on dashboard
- Acknowledged — someone has seen it
- Resolved — closed, hidden from dashboard counts
Quick actions in the table: ✓ (acknowledge), ✓✓ (resolve). Click any row for full detail.
API Endpoints
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /health |
No | Health check |
| POST | /ingest |
Yes | Ingest a log line |
| GET | /auth/me |
No | Current session user |
| POST | /auth/logout |
No | Destroy session |
| GET | /sources |
Yes | List sources |
| POST | /sources |
Yes | Create source |
| PUT | /sources/{id} |
Yes | Update source |
| DELETE | /sources/{id} |
Yes | Delete source |
| GET | /rules |
Yes | List rules |
| POST | /rules |
Yes | Create rule |
| PUT | /rules/{id} |
Yes | Update rule |
| DELETE | /rules/{id} |
Yes | Delete rule |
| GET | /alerts |
Yes | List alerts (query: severity, status, limit) |
| GET | /alerts/search?q= |
Yes | Full-text search alerts |
| GET | /alerts/counts |
Yes | Alert counts by status/severity |
| POST | /alerts/{id}/status |
Yes | Update alert status |
| GET | /logs/search?q= |
Yes | Search raw log entries |
| GET | /config/allowed_tokens |
Yes | Get allowed user tokens |
| PUT | /config/allowed_tokens |
Yes | Set allowed user tokens |
| GET | /config/telegram |
Yes | Get Telegram config |
| PUT | /config/telegram |
Yes | Set Telegram config |
Log Search
In the Logs tab, search through all ingested log lines. Use * as wildcard:
error— matches any line containing "error"error 500— matches lines containing both "error" AND "500"*— shows all logs
Development
# Install PHP deps locally
composer install
# Run PHP built-in server (no Docker)
composer serve
Project Structure
├── bin/
│ ├── consume # Worker entrypoint
│ └── seed # Seed default data
├── config/
│ └── default.php # Default rules config
├── docker/
│ ├── Dockerfile.api # PHP-FPM image
│ ├── Dockerfile.php # PHP-CLI image
│ ├── entrypoint-api.sh
│ └── nginx.conf
├── docker-compose.yml
├── public/
│ ├── index.html # SPA frontend
│ ├── index.php # API entrypoint
│ └── oauth.php # Auth callback
└── src/
├── Api/
│ ├── AuthMiddleware.php
│ └── Router.php
├── Model/
│ ├── Alert.php
│ ├── AlertSeverity.php
│ ├── AlertStatus.php
│ ├── LogSource.php
│ ├── LogSourceType.php
│ └── Rule.php
├── Notifier/
│ └── TelegramNotifier.php
├── RuleEngine/
│ └── Engine.php
├── Storage/
│ ├── Database.php
│ └── Repository.php
└── Worker/
├── FileWatcher.php
├── Orchestrator.php
└── SocketListener.php