Create a logger instance for a specific app. The purpose of this function is to have different loggers for different subapps (if needed). Args: tag: String added to the each logging line idenfiting this logger config: ServerConfig instance, will create the default one i
(
tag: str | None = None, config: ServerConfig | None = None
)
| 28 | |
| 29 | |
| 30 | def create_logger( |
| 31 | tag: str | None = None, config: ServerConfig | None = None |
| 32 | ) -> logging.Logger: |
| 33 | """ |
| 34 | Create a logger instance for a specific app. The purpose of this function |
| 35 | is to have different loggers for different subapps (if needed). |
| 36 | |
| 37 | Args: |
| 38 | tag: String added to the each logging line idenfiting this logger |
| 39 | config: ServerConfig instance, will create the default one if not provided |
| 40 | |
| 41 | Returns: |
| 42 | Configured logger instance |
| 43 | """ |
| 44 | config = config or ServerConfig() |
| 45 | |
| 46 | logger_name = "optimade" + (f".{tag}" if tag else "") |
| 47 | logger = logging.getLogger(logger_name) |
| 48 | logger.setLevel(logging.DEBUG) |
| 49 | |
| 50 | if logger.handlers: |
| 51 | return logger |
| 52 | |
| 53 | # Console handler only on parent (.tag will propagate to parent anyway) |
| 54 | if tag is None: |
| 55 | ch = logging.StreamHandler(sys.stdout) |
| 56 | ch.setLevel(logging.DEBUG if config.debug else config.log_level.value.upper()) |
| 57 | try: |
| 58 | from uvicorn.logging import DefaultFormatter |
| 59 | |
| 60 | ch.setFormatter(DefaultFormatter("%(levelprefix)s [%(name)s] %(message)s")) |
| 61 | except ImportError: |
| 62 | pass |
| 63 | logger.addHandler(ch) |
| 64 | |
| 65 | logs_dir = config.log_dir |
| 66 | if logs_dir is None: |
| 67 | logs_dir = Path(os.getenv("OPTIMADE_LOG_DIR", "/var/log/optimade/")).resolve() |
| 68 | try: |
| 69 | logs_dir.mkdir(exist_ok=True, parents=True) |
| 70 | log_filename = f"optimade_{tag}.log" if tag else "optimade.log" |
| 71 | fh = logging.handlers.RotatingFileHandler( |
| 72 | logs_dir / log_filename, maxBytes=1_000_000, backupCount=5 |
| 73 | ) |
| 74 | fh.setLevel(logging.DEBUG) |
| 75 | fh.setFormatter( |
| 76 | logging.Formatter( |
| 77 | "[%(levelname)-8s %(asctime)s %(filename)s:%(lineno)d][%(name)s] %(message)s", |
| 78 | "%d-%m-%Y %H:%M:%S", |
| 79 | ) |
| 80 | ) |
| 81 | logger.addHandler(fh) |
| 82 | except OSError: |
| 83 | logger.warning( |
| 84 | "Log files are not saved (%s). Set OPTIMADE_LOG_DIR or fix permissions for %s.", |
| 85 | tag, |
| 86 | logs_dir, |
| 87 | ) |
no test coverage detected