Initial Commit
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
"""Logging that goes to a file as well as to stdout.
|
||||
|
||||
WHY BOTH
|
||||
|
||||
stdout is what `docker compose logs` reads and what Docker's own log
|
||||
driver captures, so it has to stay. The file is so that every component
|
||||
in this stack has ONE findable place - ./logs, bind-mounted at /logs -
|
||||
rather than leaving somebody to work out which compose invocation shows
|
||||
the thing they are looking for.
|
||||
|
||||
Falling back to stdout alone is deliberate. A container run without the
|
||||
mount, or with the directory not writable, should keep working and say
|
||||
why once; refusing to start because a log file could not be opened would
|
||||
be the tail wagging the dog.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
|
||||
FORMAT = "%(asctime)s %(levelname)-7s %(name)s | %(message)s"
|
||||
|
||||
|
||||
def configure(component: str, level: str = "INFO") -> logging.Logger:
|
||||
"""stdout always; ./logs/<component>.log when the directory is there."""
|
||||
handlers: list[logging.Handler] = [logging.StreamHandler(sys.stdout)]
|
||||
problem = ""
|
||||
log_dir = os.environ.get("OWUITOOLS_LOG_DIR", "/logs")
|
||||
if log_dir:
|
||||
try:
|
||||
os.makedirs(log_dir, exist_ok=True)
|
||||
handlers.append(logging.FileHandler(
|
||||
os.path.join(log_dir, f"{component}.log"), encoding="utf-8"))
|
||||
except OSError as exc:
|
||||
problem = f"{log_dir} is not writable ({exc}); logging to stdout only"
|
||||
|
||||
logging.basicConfig(level=getattr(logging, level.upper(), logging.INFO),
|
||||
format=FORMAT, handlers=handlers, force=True)
|
||||
logger = logging.getLogger(component)
|
||||
if problem:
|
||||
logger.warning(problem)
|
||||
return logger
|
||||
Reference in New Issue
Block a user