janis a41971a11e
Deploy / deploy (push) Successful in 10s
fix
2026-05-31 20:49:57 +02:00
2026-05-06 12:14:43 +02:00
.
2026-05-31 20:45:51 +02:00
2026-05-16 12:56:51 +02:00
fix
2026-05-31 20:49:57 +02:00
2026-05-06 11:28:41 +02:00
2026-05-06 11:28:41 +02:00
2026-05-06 11:28:41 +02:00
.
2026-05-31 20:47:14 +02:00
2026-05-16 12:56:51 +02:00

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

debuginfonoticewarning_lowwarningwarning_higherrorcritical_lowcriticalcritical_highemergency

Telegram Notifications

Configure in Settings > Telegram Notifications:

  1. Create a bot via @BotFather on Telegram
  2. Get your chat ID (send a message to your bot, visit https://api.telegram.org/bot<token>/getUpdates)
  3. 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

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
S
Description
logging analyzer and alert generator
Readme 639 KiB
Languages
PHP 54.4%
HTML 45.5%