Make lib.App logging more customizable #55
1 changed files with 64 additions and 37 deletions
lib.log.log(): Convert string-based flags to Flag
Replace the set of flag strings with a Flag enum for better type safety and bitwise operations. Add parse_flags() to convert comma-separated strings into a LogFlag value. Update set_flags() and set_log_flags() to accept str | LogFlag | None. set_flags() and set_log_flags() don't return str anylonger which is a breaking change, but shouldn't be a problem because it's not used anywhere. Signed-off-by: Jan Lindemann <jan@janware.com>
commit
34ca0a7a95
|
|
@ -5,9 +5,11 @@ import re
|
|||
import sys
|
||||
import syslog
|
||||
|
||||
from enum import Flag, auto
|
||||
|
||||
from datetime import datetime
|
||||
from os.path import basename
|
||||
from typing import TYPE_CHECKING, cast
|
||||
from typing import TYPE_CHECKING, cast, override
|
||||
|
||||
if TYPE_CHECKING:
|
||||
import io
|
||||
|
|
@ -81,16 +83,44 @@ CONSOLE_FONT_WHITE = '\033[37m'
|
|||
CONSOLE_FONT_BLINK = '\033[5m'
|
||||
CONSOLE_FONT_OFF = '\033[m'
|
||||
|
||||
f_position = 'position'
|
||||
f_module = 'module'
|
||||
f_date = 'date'
|
||||
f_stderr = 'stderr'
|
||||
f_stdout = 'stdout'
|
||||
f_prio = 'prio'
|
||||
f_color = 'color'
|
||||
f_default = [ f_position, f_stderr, f_prio, f_color ]
|
||||
# -- ytools compatible log flags
|
||||
#syslog
|
||||
#console
|
||||
#color
|
||||
#prio
|
||||
#position
|
||||
#ide
|
||||
#trace_rename_thread_to_shorter
|
||||
#trace_rename_thread_to_longer
|
||||
#trace_inout
|
||||
#skip_openlog
|
||||
#id
|
||||
#date
|
||||
#pid
|
||||
#highlight_first_error
|
||||
|
||||
class LogFlag(Flag):
|
||||
POSITION = auto()
|
||||
MODULE = auto()
|
||||
DATE = auto()
|
||||
STDERR = auto()
|
||||
STDOUT = auto()
|
||||
PRIO = auto()
|
||||
COLOR = auto()
|
||||
|
||||
@override
|
||||
def __str__(self) -> str:
|
||||
def _get_name(f: LogFlag) -> str:
|
||||
return f.name or ''
|
||||
|
||||
return ','.join(
|
||||
f.name.lower()
|
||||
for f in sorted(self, key = _get_name)
|
||||
if f.name
|
||||
)
|
||||
|
||||
_flags = LogFlag.POSITION | LogFlag.STDERR | LogFlag.PRIO | LogFlag.COLOR
|
||||
|
||||
_flags = set(f_default)
|
||||
_log_prefix = ''
|
||||
_clean_log_prefix = ''
|
||||
_file_name_len = 20
|
||||
|
|
@ -206,25 +236,25 @@ def log( # export
|
|||
color_on = ''
|
||||
color_off = ''
|
||||
|
||||
if f_date in _flags:
|
||||
if LogFlag.DATE & _flags:
|
||||
msg += datetime.now().strftime("%b %d %H:%M:%S.%f") + ' '
|
||||
|
||||
if f_prio in _flags:
|
||||
if LogFlag.PRIO & _flags:
|
||||
msg += _short_prio_str[prio] + ' '
|
||||
|
||||
if f_position in _flags:
|
||||
if LogFlag.POSITION & _flags:
|
||||
|
||||
if 'caller' in kwargs:
|
||||
mod, name, line = kwargs['caller']
|
||||
else:
|
||||
mod, name, line = get_caller_pos(1)
|
||||
|
||||
if f_module in _flags:
|
||||
if LogFlag.MODULE & _flags:
|
||||
msg += pad(mod, _module_name_len)
|
||||
|
||||
msg += pad(name, _file_name_len) + '[' + pad(str(line), 4, True) + ']'
|
||||
|
||||
if f_color in _flags:
|
||||
if LogFlag.COLOR & _flags:
|
||||
color_on, color_off = console_color_chars(prio)
|
||||
|
||||
margs = ''
|
||||
|
|
@ -255,10 +285,10 @@ def log( # export
|
|||
elif _streams:
|
||||
files = [s.stream for s in _streams.values()]
|
||||
else:
|
||||
if f_stdout in _flags:
|
||||
if LogFlag.STDOUT & _flags:
|
||||
files.append(sys.stdout)
|
||||
|
||||
if f_stderr in _flags:
|
||||
if LogFlag.STDERR & _flags:
|
||||
files.append(sys.stderr)
|
||||
|
||||
if not len(files):
|
||||
|
|
@ -310,30 +340,27 @@ def set_log_level(level: str | int | None = None) -> int:
|
|||
def set_level(level: str | int | None = None) -> int: # export
|
||||
return set_log_level(level)
|
||||
|
||||
def set_flags(flags: str | None) -> str: # export
|
||||
global _flags
|
||||
ret = ','.join(_flags)
|
||||
if flags is not None:
|
||||
_flags = set(flags.split(','))
|
||||
def parse_flags(flags: str) -> LogFlag:
|
||||
ret: LogFlag = LogFlag(0)
|
||||
s = set(flags.split(','))
|
||||
for f in LogFlag:
|
||||
assert f.name is not None
|
||||
if f.name.lower() in s:
|
||||
ret |= f
|
||||
return ret
|
||||
|
||||
def set_log_flags(flags: str) -> str:
|
||||
return set_flags(flags)
|
||||
parse_log_flags = parse_flags
|
||||
|
||||
#syslog
|
||||
#console
|
||||
#color
|
||||
#prio
|
||||
#position
|
||||
#ide
|
||||
#trace_rename_thread_to_shorter
|
||||
#trace_rename_thread_to_longer
|
||||
#trace_inout
|
||||
#skip_openlog
|
||||
#id
|
||||
#date
|
||||
#pid
|
||||
#highlight_first_error
|
||||
def set_flags(flags: str | LogFlag | None) -> LogFlag: # export
|
||||
global _flags
|
||||
if isinstance(flags, str):
|
||||
flags = parse_flags(flags)
|
||||
ret = _flags
|
||||
if flags is not None:
|
||||
_flags = flags
|
||||
return ret
|
||||
|
||||
set_log_flags = set_flags
|
||||
|
||||
def append_to_prefix(prefix: str) -> str: # export
|
||||
global _log_prefix
|
||||
|
|
|
|||
Loading…
Reference in a new issue