Add CentralLogging stack, Covance/EDC sources, email import + IWRS scripts

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-08 16:06:21 +02:00
parent af787d9f02
commit 5545f05eee
173 changed files with 21334 additions and 1 deletions
@@ -0,0 +1,171 @@
{
"annotations": { "list": [] },
"editable": true,
"graphTooltip": 1,
"schemaVersion": 39,
"tags": ["central-logging"],
"title": "Central Logs — přehled",
"uid": "central-logs",
"time": { "from": "now-24h", "to": "now" },
"refresh": "30s",
"templating": {
"list": [
{
"name": "env",
"label": "Prostředí",
"type": "query",
"datasource": { "type": "loki", "uid": "loki" },
"query": "label_values(env)",
"refresh": 2,
"includeAll": true,
"allValue": ".+",
"multi": true,
"current": { "text": "All", "value": "$__all" }
},
{
"name": "app",
"label": "Skript (app)",
"type": "query",
"datasource": { "type": "loki", "uid": "loki" },
"query": "label_values({env=~\"$env\"}, app)",
"refresh": 2,
"includeAll": true,
"allValue": ".+",
"multi": true,
"current": { "text": "All", "value": "$__all" }
},
{
"name": "level",
"label": "Úroveň",
"type": "custom",
"query": "DEBUG,INFO,WARNING,ERROR,CRITICAL",
"includeAll": true,
"allValue": ".+",
"multi": true,
"current": { "text": "All", "value": "$__all" }
},
{
"name": "search",
"label": "Hledat v textu",
"type": "textbox",
"current": { "text": "", "value": "" }
}
]
},
"panels": [
{
"id": 1,
"type": "stat",
"title": "Logů celkem (rozsah)",
"datasource": { "type": "loki", "uid": "loki" },
"gridPos": { "h": 4, "w": 8, "x": 0, "y": 0 },
"options": { "colorMode": "value", "graphMode": "area", "reduceOptions": { "calcs": ["lastNotNull"] } },
"targets": [
{
"refId": "A",
"datasource": { "type": "loki", "uid": "loki" },
"expr": "sum(count_over_time({app=~\"$app\", env=~\"$env\", level=~\"$level\"} |~ \"(?i)$search\" [$__range]))",
"queryType": "instant"
}
]
},
{
"id": 2,
"type": "stat",
"title": "Chyby (ERROR+CRITICAL, rozsah)",
"datasource": { "type": "loki", "uid": "loki" },
"gridPos": { "h": 4, "w": 8, "x": 8, "y": 0 },
"fieldConfig": {
"defaults": {
"color": { "mode": "thresholds" },
"thresholds": { "mode": "absolute", "steps": [
{ "color": "green", "value": null },
{ "color": "red", "value": 1 }
] }
}
},
"options": { "colorMode": "background", "graphMode": "area", "reduceOptions": { "calcs": ["lastNotNull"] } },
"targets": [
{
"refId": "A",
"datasource": { "type": "loki", "uid": "loki" },
"expr": "sum(count_over_time({app=~\"$app\", env=~\"$env\", level=~\"ERROR|CRITICAL\"} |~ \"(?i)$search\" [$__range]))",
"queryType": "instant"
}
]
},
{
"id": 3,
"type": "stat",
"title": "Aktivních skriptů",
"datasource": { "type": "loki", "uid": "loki" },
"gridPos": { "h": 4, "w": 8, "x": 16, "y": 0 },
"options": { "colorMode": "value", "graphMode": "none", "reduceOptions": { "calcs": ["lastNotNull"] } },
"targets": [
{
"refId": "A",
"datasource": { "type": "loki", "uid": "loki" },
"expr": "count(sum by (app) (count_over_time({env=~\"$env\"} [$__range])))",
"queryType": "instant"
}
]
},
{
"id": 4,
"type": "timeseries",
"title": "Tok logů podle úrovně",
"datasource": { "type": "loki", "uid": "loki" },
"gridPos": { "h": 8, "w": 12, "x": 0, "y": 4 },
"fieldConfig": { "defaults": { "custom": { "drawStyle": "bars", "fillOpacity": 60, "stacking": { "mode": "normal" } } } },
"targets": [
{
"refId": "A",
"datasource": { "type": "loki", "uid": "loki" },
"expr": "sum by (level) (count_over_time({app=~\"$app\", env=~\"$env\", level=~\"$level\"} |~ \"(?i)$search\" [$__interval]))",
"legendFormat": "{{level}}"
}
]
},
{
"id": 5,
"type": "timeseries",
"title": "Chyby podle skriptu",
"datasource": { "type": "loki", "uid": "loki" },
"gridPos": { "h": 8, "w": 12, "x": 12, "y": 4 },
"fieldConfig": { "defaults": { "custom": { "drawStyle": "bars", "fillOpacity": 70, "stacking": { "mode": "normal" } } } },
"targets": [
{
"refId": "A",
"datasource": { "type": "loki", "uid": "loki" },
"expr": "sum by (app) (count_over_time({app=~\"$app\", env=~\"$env\", level=~\"ERROR|CRITICAL\"} |~ \"(?i)$search\" [$__interval]))",
"legendFormat": "{{app}}"
}
]
},
{
"id": 6,
"type": "logs",
"title": "Poslední logy",
"datasource": { "type": "loki", "uid": "loki" },
"gridPos": { "h": 14, "w": 24, "x": 0, "y": 12 },
"options": {
"showTime": true,
"showLabels": false,
"showCommonLabels": false,
"wrapLogMessage": true,
"prettifyLogMessage": true,
"enableLogDetails": true,
"dedupStrategy": "none",
"sortOrder": "Descending"
},
"targets": [
{
"refId": "A",
"datasource": { "type": "loki", "uid": "loki" },
"expr": "{app=~\"$app\", env=~\"$env\", level=~\"$level\"} |~ \"(?i)$search\" | json",
"maxLines": 1000
}
]
}
]
}
+73
View File
@@ -0,0 +1,73 @@
# ============================================================================
# CentralLogging — docker-compose (Loki + Grafana + Log Gateway)
# Verze: 1.0
# Datum: 2026-06-08
# Popis: Stack pro centrální logování na Unraidu.
# - loki : úložiště logů (HTTP push API), retence 90 dní
# - grafana : prohlížení a dashboardy nad Loki
# - gateway : FastAPI brána, kam posílají logy klientské skripty
#
# Spuštění na Unraidu:
# docker compose -f docker-compose.yml up -d
#
# Porty (uprav dle potřeby):
# 3100 Loki HTTP (interní, klienti na něj nesahají přímo)
# 3000 Grafana web UI
# 8770 Log Gateway (sem posílají skripty)
# ============================================================================
services:
loki:
image: grafana/loki:3.1.1
container_name: central-loki
restart: unless-stopped
command: -config.file=/etc/loki/loki-config.yml
ports:
- "3100:3100"
volumes:
- ./loki-config.yml:/etc/loki/loki-config.yml:ro
# Persistentní data na Unraid share (desítky TB) — uprav cestu:
- /mnt/user/appdata/central-logging/loki:/loki
networks:
- logging
grafana:
image: grafana/grafana:11.2.0
container_name: central-grafana
restart: unless-stopped
ports:
- "3001:3000" # 3000 na Unraidu drží Gitea -> Grafana na 3001
environment:
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD:-changeme}
- GF_USERS_ALLOW_SIGN_UP=false
volumes:
- /mnt/user/appdata/central-logging/grafana:/var/lib/grafana
- ./grafana-datasource.yml:/etc/grafana/provisioning/datasources/loki.yml:ro
- ./grafana-dashboards.yml:/etc/grafana/provisioning/dashboards/central.yml:ro
- ./dashboards:/etc/grafana/provisioning/dashboards/json:ro
depends_on:
- loki
networks:
- logging
gateway:
build:
context: ../gateway
image: central-log-gateway:1.0
container_name: central-log-gateway
restart: unless-stopped
ports:
- "8770:8770"
environment:
- LOKI_URL=http://loki:3100
- LOG_TOKEN=${LOG_TOKEN:-change-this-shared-secret}
- GATEWAY_ENV=prod
depends_on:
- loki
networks:
- logging
networks:
logging:
driver: bridge
@@ -0,0 +1,20 @@
# ============================================================================
# CentralLogging — Grafana dashboard provisioning
# Verze: 1.0
# Datum: 2026-06-08
# Popis: Automaticky načte dashboardy z /etc/grafana/provisioning/dashboards/json
# (mountováno z ./dashboards). Soubor .json = jeden dashboard.
# ============================================================================
apiVersion: 1
providers:
- name: CentralLogging
orgId: 1
folder: CentralLogging
type: file
disableDeletion: false
updateIntervalSeconds: 30
allowUiUpdates: true
options:
path: /etc/grafana/provisioning/dashboards/json
foldersFromFilesStructure: false
@@ -0,0 +1,17 @@
# ============================================================================
# CentralLogging — Grafana datasource provisioning
# Verze: 1.0
# Datum: 2026-06-08
# Popis: Automaticky přidá Loki jako datasource při startu Grafany.
# ============================================================================
apiVersion: 1
datasources:
- name: Loki
type: loki
uid: loki # pevné uid, na které odkazuje dashboard
access: proxy
url: http://loki:3100
isDefault: true
jsonData:
maxLines: 5000
+62
View File
@@ -0,0 +1,62 @@
# ============================================================================
# CentralLogging — Loki konfigurace
# Verze: 1.0
# Datum: 2026-06-08
# Popis: Single-binary Loki, filesystem storage, retence 90 dní.
# Retenci vynucuje compactor (delete_request + retention_period).
# ============================================================================
auth_enabled: false
server:
http_listen_port: 3100
grpc_listen_port: 9096
log_level: info
common:
instance_addr: 127.0.0.1
path_prefix: /loki
storage:
filesystem:
chunks_directory: /loki/chunks
rules_directory: /loki/rules
replication_factor: 1
ring:
kvstore:
store: inmemory
schema_config:
configs:
- from: 2024-01-01
store: tsdb
object_store: filesystem
schema: v13
index:
prefix: index_
period: 24h
storage_config:
tsdb_shipper:
active_index_directory: /loki/tsdb-index
cache_location: /loki/tsdb-cache
filesystem:
directory: /loki/chunks
limits_config:
retention_period: 2160h # 90 dní
reject_old_samples: true
reject_old_samples_max_age: 168h # 7 dní (logy starší se odmítnou)
max_label_names_per_series: 15
ingestion_rate_mb: 16
ingestion_burst_size_mb: 32
allow_structured_metadata: true
compactor:
working_directory: /loki/compactor
compaction_interval: 10m
retention_enabled: true # zapne mazání dle retention_period
retention_delete_delay: 2h
delete_request_store: filesystem
# Analytika do Grafana Labs vypnuta
analytics:
reporting_enabled: false