feat: log-level redaction filter

This commit is contained in:
aclist committed 2026-07-04 08:47:34 +09:00
1 parent 6c86bff869
commit 5bb4271d36
3 files changed
+35 -21

No files matched your search

+9 -1
View File
@@ -4,7 +4,7 @@ import shutil
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from dzgui.const.constants import APP_NAME, APP_NAME_LOWER from dzgui.const.constants import APP_NAME
from dzgui.const.enum import Preferences from dzgui.const.enum import Preferences
from dzgui.config.query import lookup from dzgui.config.query import lookup
from dzgui.config.userprefs import UserPrefs from dzgui.config.userprefs import UserPrefs
@@ -21,6 +21,7 @@ from dzgui.strings import boot
# from dzgui.util.map_count import get_map_count # from dzgui.util.map_count import get_map_count
from dzgui.util.deck import is_steam_deck, is_game_mode from dzgui.util.deck import is_steam_deck, is_game_mode
from dzgui.util.localize import set_locale from dzgui.util.localize import set_locale
from dzgui.util.redact import RedactionFilter, REDACTION_PATTERNS
from dzgui.util.strings import init from dzgui.util.strings import init
from dzgui.views.base import App from dzgui.views.base import App
@@ -40,13 +41,19 @@ def make_parents(path: "Path") -> None:
def setup_logger(log_path: "Path") -> None: def setup_logger(log_path: "Path") -> None:
# TODO: put in consts?
_format = ( _format = (
"%(asctime)s␞%(levelname)s␞%(filename)s::%(funcName)s::%(lineno)s␞%(message)s" "%(asctime)s␞%(levelname)s␞%(filename)s::%(funcName)s::%(lineno)s␞%(message)s"
) )
fh = logging.FileHandler(log_path) fh = logging.FileHandler(log_path)
formatter = logging.Formatter(_format) formatter = logging.Formatter(_format)
fh.setFormatter(formatter) fh.setFormatter(formatter)
fh.setLevel(logging.DEBUG) fh.setLevel(logging.DEBUG)
_filter = RedactionFilter(patterns=REDACTION_PATTERNS)
fh.addFilter(_filter)
logger.setLevel(logging.DEBUG) logger.setLevel(logging.DEBUG)
logger.addHandler(fh) logger.addHandler(fh)
@@ -66,6 +73,7 @@ def copy_bare_configs(config: "Path", resolution: "Path") -> tuple[bool, bool]:
] ]
config_changed = False config_changed = False
state_changed = False state_changed = False
if config.parent.exists() is False: if config.parent.exists() is False:
new_file = config new_file = config
old_file = config.parent.parent / conf old_file = config.parent.parent / conf
+1 -4
View File
@@ -2,7 +2,6 @@ from dataclasses import dataclass
from typing import Any, Sequence, TYPE_CHECKING from typing import Any, Sequence, TYPE_CHECKING
from dzgui.const.enum import HELP_MENU_ROWS from dzgui.const.enum import HELP_MENU_ROWS
from dzgui.util.redact import redact_log
from dzgui.util.strings import delimiter from dzgui.util.strings import delimiter
import gi import gi
@@ -134,9 +133,7 @@ class ModelFactory:
with open(path, "r") as f: with open(path, "r") as f:
lines = [line.split(delimiter) for line in f.read().splitlines()] lines = [line.split(delimiter) for line in f.read().splitlines()]
for record in lines: for record in lines:
# NOTE: strips PII and API keys store.append(record)
clean = redact_log(record)
store.append(clean)
return store return store
def new_model_from_class(self, cls: type) -> FastInsertListStore: def new_model_from_class(self, cls: type) -> FastInsertListStore:
+25 -16
View File
@@ -1,20 +1,29 @@
import logging
import re import re
from typing import Literal
def redact(text: str) -> str: api_filter = r"(.*&key=)([^&]*)(.*)"
r = r"(/home/)([^/])*" home_filter = r"(/home/)([^/]*)(.*)"
cleaned = re.sub(r, r"/home/REDACTED", text) REDACTED = r"\1REDACTED\3"
REDACTION_PATTERNS = [api_filter, home_filter]
def redact_home(text: str) -> str:
pat = re.compile(home_filter)
cleaned = pat.sub(REDACTED, text)
return cleaned return cleaned
def redact_log(record: list) -> list[str]:
""" class RedactionFilter(logging.Filter):
requests library includes Steam API key in URL params def __init__(self, patterns: list[str] | None = None) -> None:
""" super().__init__()
clean = [] self._patterns = [re.compile(pat) for pat in (patterns or [])]
for item in record:
if "&key=" in item: def filter(self, record: logging.LogRecord) -> Literal[True]:
pat = r"(.*&key=)(\S+)(.*)" for pattern in self._patterns:
scrubbed = re.sub(pat, r"\1REDACTED\3", item) try:
clean.append(scrubbed) record.msg = pattern.sub(REDACTED, record.msg)
else: except TypeError:
clean.append(item) exception_text = f"{type(record.msg).__name__}: {record.msg}"
return clean record.msg = pattern.sub(REDACTED, exception_text)
return True