133 lines
4.9 KiB
Python
133 lines
4.9 KiB
Python
import logging
|
|
import os
|
|
import sys
|
|
from logging.handlers import TimedRotatingFileHandler
|
|
|
|
from indexer.config import LOG_LEVEL, LOG_DIR
|
|
|
|
# Loki label aplikace (stabilní, BEZ verze) — podle něj se filtruje v Grafaně:
|
|
# {app="dropbox_backup"}
|
|
CENTRAL_APP_NAME = "dropbox_backup"
|
|
|
|
# Sdílené knihovny (central_logging klient) — na produkci leží v
|
|
# C:\Reporting\knihovny, v dev prostředí ve zdroji CentralLogging.
|
|
_LIB_DIRS = [
|
|
r"C:\Reporting\knihovny",
|
|
r"U:\janssen\CentralLogging\client",
|
|
]
|
|
|
|
# Token/gateway pro central logging držíme centrálně v /scripts na unraidu
|
|
# (\\tower\Scripts). Skript si je odsud načte do os.environ, takže není nutné
|
|
# nastavovat env proměnné na každém stroji ani mít token v repu/.env.
|
|
_CENTRAL_ENV_FILES = [
|
|
r"\\tower\Scripts\central_log.env",
|
|
r"\\192.168.1.76\Scripts\central_log.env",
|
|
]
|
|
|
|
|
|
def _load_central_env() -> None:
|
|
"""Načte CENTRAL_LOG_* z token souboru na unraidu (KEY=VALUE řádky) do
|
|
os.environ. Nepřepisuje už nastavené hodnoty (setdefault). Tiše ignoruje,
|
|
když share není dostupný — fallback řeší volající."""
|
|
path = os.environ.get("CENTRAL_LOG_ENV_FILE")
|
|
candidates = [path] if path else _CENTRAL_ENV_FILES
|
|
for p in candidates:
|
|
if not p or not os.path.isfile(p):
|
|
continue
|
|
try:
|
|
with open(p, "r", encoding="utf-8") as f:
|
|
for line in f:
|
|
line = line.strip()
|
|
if not line or line.startswith("#") or "=" not in line:
|
|
continue
|
|
key, _, val = line.partition("=")
|
|
os.environ.setdefault(key.strip(), val.strip())
|
|
return
|
|
except OSError:
|
|
continue
|
|
|
|
|
|
def _attach_central_handler(root: logging.Logger, fmt: logging.Formatter, level: int) -> bool:
|
|
"""Připojí na root logger handler centrálního logování (Grafana Loki).
|
|
|
|
Posílá KAŽDÝ log řádek (tedy i celou konzoli) do centrální gateway na
|
|
pozadí, neblokujícím způsobem se spool fallbackem. Vrací True při úspěchu.
|
|
Když klient/gateway nejsou dostupné (např. dev stroj), tiše degraduje na
|
|
file+console — záloha běží dál.
|
|
"""
|
|
_load_central_env()
|
|
for d in _LIB_DIRS:
|
|
if os.path.isdir(d) and d not in sys.path:
|
|
sys.path.insert(0, d)
|
|
try:
|
|
# importlib shim re-exportuje CentralLogHandler i _GatewaySender přes
|
|
# implementační modul; sender vytvoříme přímo, ať nepřepíšeme naše
|
|
# vlastní file+console handlery (central setup_logging si je čistí sám).
|
|
import central_logging # noqa: F401 (shim načte impl modul)
|
|
impl = sys.modules.get("central_logging_impl") or central_logging.setup_logging.__globals__
|
|
if isinstance(impl, dict):
|
|
GatewaySender = impl["_GatewaySender"]
|
|
CentralLogHandler = impl["CentralLogHandler"]
|
|
else:
|
|
GatewaySender = impl._GatewaySender
|
|
CentralLogHandler = impl.CentralLogHandler
|
|
|
|
from pathlib import Path
|
|
gw = os.environ.get("CENTRAL_LOG_GATEWAY", "http://192.168.1.76:8770")
|
|
tok = os.environ.get("CENTRAL_LOG_TOKEN", "change-this-shared-secret")
|
|
ev = os.environ.get("CENTRAL_LOG_ENV", "prod")
|
|
|
|
sender = GatewaySender(
|
|
app_name=CENTRAL_APP_NAME,
|
|
gateway=gw,
|
|
token=tok,
|
|
env=ev,
|
|
spool_dir=Path(LOG_DIR) / "_log_spool",
|
|
)
|
|
ch = CentralLogHandler(sender)
|
|
ch.setLevel(level)
|
|
ch.setFormatter(fmt)
|
|
root.addHandler(ch)
|
|
|
|
import atexit
|
|
atexit.register(sender.flush_and_stop)
|
|
return True
|
|
except Exception as e: # noqa: BLE001 — logování nikdy nesmí shodit zálohu
|
|
print(f"[logger] central logging nedostupné, pokracuji file+console: {e}")
|
|
return False
|
|
|
|
|
|
def setup_logging() -> logging.Logger:
|
|
os.makedirs(LOG_DIR, exist_ok=True)
|
|
|
|
level = getattr(logging, LOG_LEVEL.upper(), logging.INFO)
|
|
fmt = logging.Formatter(
|
|
"%(asctime)s [%(levelname)-8s] %(message)s",
|
|
datefmt="%Y-%m-%d %H:%M:%S",
|
|
)
|
|
|
|
file_handler = TimedRotatingFileHandler(
|
|
os.path.join(LOG_DIR, "backup.log"),
|
|
when="midnight",
|
|
backupCount=90,
|
|
encoding="utf-8",
|
|
)
|
|
file_handler.setFormatter(fmt)
|
|
|
|
console_handler = logging.StreamHandler(sys.stdout)
|
|
console_handler.setFormatter(fmt)
|
|
|
|
logging.root.setLevel(level)
|
|
logging.root.handlers.clear()
|
|
logging.root.addHandler(file_handler)
|
|
logging.root.addHandler(console_handler)
|
|
|
|
# Central logging (Grafana Loki) — vedle file+console, posílá vše do gateway.
|
|
if _attach_central_handler(logging.root, fmt, level):
|
|
logging.getLogger("backup").info(
|
|
"central_logging napojeno (app=%s, gateway=%s)",
|
|
CENTRAL_APP_NAME, os.environ.get("CENTRAL_LOG_GATEWAY", "http://192.168.1.76:8770"),
|
|
)
|
|
|
|
return logging.getLogger("backup")
|