Files
janssen/CentralLogging/README.md
T

159 lines
7.0 KiB
Markdown

# CentralLogging — centrální logování (Loki + Grafana + FastAPI gateway)
**Verze:** 1.0 · **Datum:** 2026-06-08 · **Autor:** Vladimír Buzalka
Řešení pro sjednocení logů z rozházených skriptů projektu Janssen do jednoho
centrálního místa na Unraidu, **bez zrušení stávajícího souborového logování**.
Soubory a centrál běží paralelně; po ~měsíci ověřování se souborové logování
vypne jedním přepínačem.
---
## 1. Architektura
```
┌────────────────┐ HTTP POST /log/batch ┌──────────────┐ push ┌────────┐
│ Python skript │ ── Bearer token, JSON ──────▶ │ Log Gateway │ ───────▶ │ Loki │
│ (central_ │ (na pozadí, v dávkách) │ (FastAPI) │ /push │ (90 d) │
│ logging.py) │ └──────────────┘ └────┬───┘
│ │ │
│ + soubor .log │ (stávající RotatingFileHandler — zatím zůstává) │
└────────────────┘ ┌─────▼────┐
│ Grafana │
Při výpadku gateway → lokální spool .ndjson, přehraje se po obnovení. │ (dashbrd)│
└──────────┘
```
**Proč takhle:**
- **Loki** — průmyslový standard pro centrální logy, levné úložiště (chunky na
Unraid share), retence vynucená automaticky, vizualizace v Grafaně.
- **FastAPI gateway** (jako tvůj `msgreceiver`) — skripty neznají interní detaily
Loki ani DB hesla, jen jednoduchý JSON + sdílený token. Backend lze kdykoli
vyměnit beze změny skriptů.
- **Klient jen stdlib** (`urllib`) — žádné `pip install` do desítek skriptů.
- **Neblokující + odolné** — emit jen vloží do fronty, odesílá vlákno na pozadí
v dávkách; při výpadku spool soubor → žádný log se neztratí.
---
## 2. Adresářová struktura
```
CentralLogging/
├── README.md ← tento soubor
├── docker/
│ ├── docker-compose.yml Loki + Grafana + Gateway
│ ├── loki-config.yml Loki, retence 90 dní
│ └── grafana-datasource.yml auto-přidání Loki do Grafany
├── gateway/
│ ├── log_gateway_v1.0.py FastAPI brána
│ ├── log_gateway_v1.0.md dokumentace brány
│ ├── requirements.txt
│ └── Dockerfile
└── client/
├── central_logging.py stabilní import shim
├── central_logging_v1.0.py implementace (verze ve jméně)
├── central_logging_v1.0.md dokumentace knihovny
└── example_usage_v1.0.py ukázka integrace
```
---
## 3. Nasazení na Unraid
1. Zkopíruj adresář `CentralLogging/` na Unraid (např. do
`/mnt/user/appdata/central-logging/src`).
2. Uprav cesty volumes v `docker-compose.yml` (výchozí
`/mnt/user/appdata/central-logging/{loki,grafana}`).
3. Nastav tajemství (soubor `.env` vedle compose, NE do gitu):
```env
LOG_TOKEN=nejaky-dlouhy-nahodny-retezec
GRAFANA_PASSWORD=silne-heslo
```
4. Spusť:
```bash
cd docker
docker compose up -d
docker compose ps
```
5. Kontrola:
- Gateway health: `curl http://192.168.1.76:8770/health`
→ očekávané `{"status":"ok","loki":"ready",...}`
- Grafana: `http://192.168.1.76:3001` (admin / GRAFANA_PASSWORD)
→ Explore → datasource Loki → dotaz `{app="..."}`
> Porty: Loki 3100 (interní), Grafana 3001 (3000 drží Gitea), Gateway 8770. Uprav, pokud kolidují
> (msgreceiver běží na 8765).
---
## 4. Integrace do stávajících skriptů
Typický skript dnes obsahuje:
```python
import logging
logging.basicConfig(filename=str(LOG_FILE), level=logging.ERROR,
format="%(asctime)s | %(message)s",
datefmt="%Y-%m-%d %H:%M:%S", encoding="utf-8")
```
Nahradíš celý blok `basicConfig(...)` jedním voláním — **zbytek skriptu
(`logging.error(...)`, `log.info(...)`) zůstává beze změny:**
```python
import sys
sys.path.insert(0, r"U:\PythonProject\Janssen\CentralLogging\client")
from central_logging import setup_logging
log = setup_logging("nazev_skriptu") # label aplikace v Loki
```
Konfigurace přes ENV (nebo argumenty `setup_logging`):
| ENV | Default | Význam |
|-------------------------|-----------------------------|---------------------------------------|
| `CENTRAL_LOG_GATEWAY` | `http://192.168.1.76:8770` | URL brány |
| `CENTRAL_LOG_TOKEN` | `change-this-shared-secret` | sdílené tajemství (musí sedět s bránou)|
| `CENTRAL_LOG_ENV` | `prod` | label prostředí |
| `CENTRAL_LOG_KEEP_FILE` | `1` | psát i do souboru (po měsíci → `0`) |
| `CENTRAL_LOG_LEVEL` | `INFO` | min. úroveň |
---
## 5. Plán migrace (souběh → vypnutí souborů)
1. **Fáze A — souběh (cca 1 měsíc):** `keep_file=True` (default). Logy jdou do
souboru i do Loki. Ověřuješ úplnost, ladíš dashboardy, labely, úrovně.
2. **Fáze B — ověření:** porovnáš soubor vs. Loki na vybraných skriptech, že
nic nechybí (spool funguje i při výpadcích).
3. **Fáze C — vypnutí souborů:** nastav globálně `CENTRAL_LOG_KEEP_FILE=0`
(nebo `setup_logging(..., keep_file=False)`). Skripty pak píší jen do
centrálu. Staré `.log` soubory přesuň do `TRASH/` (nemazat — konvence).
---
## 6. Dotazy v Grafaně (LogQL)
```logql
{app="parse_emails_graph"} # vše z jednoho skriptu
{app="parse_emails_graph", level="ERROR"} # jen chyby
{env="prod"} |= "bulk_write" # fulltext napříč skripty
{app="edc_import"} | json | line > 100 # parsování JSON pole z těla
sum by (app) (count_over_time({level="ERROR"}[1h])) # počet chyb / skript / h
```
Labely (nízká kardinalita): `app`, `host`, `level`, `env`.
Vše ostatní (`logger`, `func`, `line`, `exc`, `extra`) je v těle řádku jako
JSON → v Grafaně dostupné přes `| json`.
---
## 7. Bezpečnost a poznámky
- Token je sdílené tajemství; drž ho v `.env` / ENV, ne v gitu.
- Gateway běží v interní docker síti; ven publikuje jen port 8770. Pokud má být
dostupná i mimo LAN, dej před ni reverzní proxy s TLS.
- Loki má `auth_enabled: false` (single-tenant, interní). Pro veřejné vystavení
přidej autentizaci na proxy.
- Spool soubory (`_log_spool/*.ndjson`) vznikají jen při výpadku brány a samy
se po obnovení spojení vyprázdní.