from __future__ import annotations import datetime import sys import syslog from typing import TYPE_CHECKING if TYPE_CHECKING: from typing import Final # fmt: disable # don't conflate # yapf: disable # don't conflate EMERG = int(syslog.LOG_EMERG) ALERT = int(syslog.LOG_ALERT) CRIT = int(syslog.LOG_CRIT) ERR = int(syslog.LOG_ERR) WARNING = int(syslog.LOG_WARNING) NOTICE = int(syslog.LOG_NOTICE) INFO = int(syslog.LOG_INFO) DEBUG = int(syslog.LOG_DEBUG) DEVEL = int(syslog.LOG_DEBUG + 1) OFF = DEVEL + 1 _log_level = NOTICE _last_tstamp = datetime.datetime.now() _first_tstamp = _last_tstamp _LOG_LEVEL_NAME_BY_VALUE: Final[dict[int, str]] = { EMERG: 'EMERG', ALERT: 'ALERT', CRIT: 'CRIT', ERR: 'ERR', WARNING: 'WARNING', NOTICE: 'NOTICE', INFO: 'INFO', DEBUG: 'DEBUG', DEVEL: 'DEVEL', OFF: 'OFF', } # yapf: enable # fmt: enable _LOG_LEVEL_VALUE_BY_NAME: Final[dict[str, int]] = { alias: value for value, name in _LOG_LEVEL_NAME_BY_VALUE.items() for alias in (name, name.lower()) } def get_log_level_name(level: int) -> str: return _LOG_LEVEL_NAME_BY_VALUE[level] def parse_log_level(level: str | int) -> int: def __int_level(level: int) -> int: if level >= 0 and level <= DEVEL: return level raise Exception(f'Invalid log level number {level}') if isinstance(level, int): return __int_level(level) if level in _LOG_LEVEL_VALUE_BY_NAME: return _LOG_LEVEL_VALUE_BY_NAME[level] return __int_level(int(level)) def set_log_level(level: str | int | None = None) -> int: global _log_level ret = _log_level if level is not None: _log_level = parse_log_level(level) return ret def set_log_flags(*args, **kwargs): pass def log(prio: int, *args, **kwargs): global _log_level if prio > _log_level: return print(*args, file = sys.stderr) def log_time_diff(prio: int, *args, **kwargs): global _last_tstamp now = datetime.datetime.now() log(prio, now - _last_tstamp, now - _first_tstamp, *args) _last_tstamp = now