Make lib.App logging more customizable #55

Merged
Jan Lindemann merged 6 commits from jan/feature/20260810-make-lib-app-logging-more-customizable into master 2026-08-10 20:34:59 +02:00 AGit
Showing only changes of commit 34ca0a7a95 - Show all commits

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>
Jan Lindemann 2026-08-09 04:20:56 +02:00
Signed by: Jan Lindemann
GPG key ID: 3750640C9E25DD61

View file

@ -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