Imported from MattyMroz/AniShift (
anishift/utils/logger/AGENTS.md). Install upstream withnpx skills add MattyMroz/AniShift --skill logger. Copyright stays with the author.
logger
Przenośny (współdzielony z mm_avh): logger oparty na loguru z mostem stdlib, sinkami JSON/Rich, scrubbingiem sekretów i readerami logów.
Mapa katalogów
core.py—setup_mode, most stdlib→loguru (InterceptHandler), konfiguracja z envconfig.py— modele pydantic (Console/File/Logger/Preset) +get_level_prioritymodes.py— presety DEV/PRODUCTION/SILENT +get_mode_configscrubber.py— maskowanie sekretów w treści logówstats.py— thread-safe statystyki (globalny singleton_stats)log_reader.py— prosty reader JSON (nie-chainable) dla CLIlog_viewer.py— renderowanie logów przez Richcli.py— CLI do przeglądania plików logów JSONtiming.py— context managerlog_duration(mostutils.timer.Timer→ loguru)_time_helpers.py— helpery zakresu czasowego dla readerówhandlers/— sinki (console/rich/json);readers/— chainable readery + aggregatorformatters/— formatter JSON;examples/— dema + presety JSON;tests/
Pułapki
- Scrubbing działa we wszystkich trybach i obejmuje message, zagnieżdżone
extraoraz komunikat wyjątku.diagnose=Falsezapobiega serializacji lokalnych zmiennych z tracebacka; nie rozluźniaj żadnej z tych ochron.core.py,scrubber.py setup_modena starcie robilogger.remove()— kasuje WSZYSTKIE istniejące sinki loguru (także dodane z zewnątrz) przed dodaniem swoich.core.py:89- Sink
errors.log.jsonlNIE powstaje w SILENT, mimo że główny plik SILENT i tak na niego wskazuje.core.py:122,modes.py:79 InterceptHandlerwyłącza loggeruvicorn.access(disabled = True) — jego logi znikają bez śladu.core.py:157- W
apply_filtersfiltr czasu wołafilter_by_timena pełnym zbiorze i NADPISUJElogs, kasując wcześniejszy filtr--level.cli.py:147 - Reader leniwie woła
read_all()gdy_logspuste; dla realnie pustego pliku warunek jest zawsze prawdziwy — plik parsowany przy każdym wywołaniu.log_reader.py:77 resolve_time_windowprzyminutes/hours/dayszawsze wymuszaend = now; priorytet minutes > hours > days._time_helpers.py:32- Override
file_pathw env działa tylko dzięki specjalnej obsłudze wget_mode_config(pop dofile) —LoggerConfigmaextra="forbid"i odrzuciłby surowefile_path.core.py:190,modes.py:119
Konwencje
- Dwa różne
LogReader: prosty (log_reader.py) i chainable (readers/); docstring odsyła doreaders.LogReaderdla fluent API.log_reader.py:2 log_viewer.pyimportuje prywatne symbole (_LEVEL_BADGE,_LEVEL_COLOR,_LEVEL_ICON,_show_icons) zhandlers/console.py.log_viewer.py:22- Statystyki na globalnym singletonie
_stats;increment_stat(wołane przez sinki) mutuje ten sam obiekt.stats.py:77 - Style z configu (
time_style,logger_name_styleitd.) to nazwy stylów Rich zRICH_THEME.config.py:113,147 _VENDOR_LOGGERS(torch, httpx, transformers, PIL...) przypięte na WARNING — logi poniżej celowo tłumione.core.py:30timing.pyzależy odutils.timer.Timer;log_viewer.py/cli.pyużywają wspólnej..rich_console— komponenty spoza pakietu.timing.py:19
Komenda
- CLI:
python -m <pkg>.logger.cli <log_file> [--recent 10 | --level ERROR --table | --stats].
Uwaga
- Standalone examples use
logger; when nested, import<pkg>.loggerwith the utilities package prefix defined by the host. - URL route prefixes default to empty. The host process may register its routes with
set_url_route_prefixes; filesystem paths and secrets remain scrubbed.
