py.lib.aw_log

Yohn Y. 2026-06-23 Parent:1e93862d5063 Child:e673daec06dc

8:7caffeee7dca Go to Latest

py.lib.aw_log/src/aw_log/__init__.py

.. 1.202606.2 . Проблема в разборе расширенного сообщения при некоторых параметрах

History
1 # coding: utf-8
2 """ Реализация классов логирования
4 Метки в журнале о уровне сообщения:
5 "`": Debug
6 ".": Info
7 "*": Warning
8 "!": Error
9 "#": Alert
11 """
13 from time import monotonic
14 from datetime import timedelta
15 from traceback import extract_tb, extract_stack
16 from typing import Optional, Any, Iterable
17 from sys import exc_info
20 class Timing:
21 """\
22 Организация работы с таймерами
23 """
24 def __init__(self, name: Optional[str] = None):
25 if name is None:
26 self.prefix = ''
28 else:
29 self.prefix = f'{name} :: '
31 self.ts_all = monotonic()
32 self.ts = self.ts_all
34 def get_time(self):
35 return monotonic() - self.ts
37 def reset(self):
38 self.ts = monotonic()
39 self.ts_all = self.ts
41 def __str__(self):
42 ts = monotonic()
43 return self.prefix + '%s(%.4f)' % (timedelta(seconds=(ts - self.ts_all)), ts - self.ts)
45 def __call__(self, msg):
46 _buf = f'{self} | {msg}'
47 self.ts = monotonic()
48 return _buf
51 class AbstractLogBase:
52 def __init__(self, prefix: str = 'main'):
53 self.prefix = prefix
55 def _write_helper(self, mark: str, msg: Any) -> Iterable[str]:
56 for l in str(msg).splitlines():
57 yield f'{mark} {self.prefix} | {l}\n'
59 def _write(self, mark: str, msg: Any):
60 raise NotImplemented(f'Метод write не определён для класса "{type(self).__name__}"')
62 def __call__(self, msg):
63 self._write('.', msg)
65 def err(self, msg):
66 self._write('!', msg)
68 def warn(self, msg):
69 self._write('*', msg)
71 def alert(self, msg):
72 self._write('#', msg)
74 def debug(self, msg):
75 self._write('`', msg)
77 @staticmethod
78 def get_timing(name: Optional[str] = None):
79 return Timing(name)
81 @staticmethod
82 def format_msg(msg: str, **kwa) -> str:
83 """\
84 Создаём сообщение, более дружелюбное к средствам разбора логов.
85 Ориентир на ``victoria_logs`` и её ``unpack_logfmt``
87 :param msg: Основное сообщение
88 :param kwa: Набор ключ-значение, для добавления в сообщения в качестве
89 разбираемых системой элементов, пригодных для фильтрации
90 :returns: Строку, которую необходимо отправить в лог методом с нужным уровнем важности.
91 """
92 data = ''
93 for k, v in kwa.items():
94 _v = str(v)
95 if v.find(' ') != -1:
96 v = f'"{v}"'
98 data += f' {k}={v}'
100 if not data:
101 return msg
103 else:
104 return f'{msg} |{data}'
106 def sub_log(self, name: str):
107 return self.__class__(f'{self.prefix}/{name}')
109 def excpt(self, msg, e_class=None, e_obj=None, e_tb=None, stack_skip=0):
110 if e_class is None:
111 e_class, e_obj, e_tb = exc_info()
113 tb_data_tb = list(extract_tb(e_tb))[::-1]
114 tb_data_stack = list(extract_stack())[::-1][(2 + stack_skip):]
115 self.alert(msg)
116 self.alert('--- EXCEPTION ---')
117 self.alert(f' {e_class.__name__} ({e_obj})')
118 self.alert('--- TRACEBACK ---')
119 for _tb_file, _tb_line, _tb_func, _tb_text in tb_data_tb:
120 self.alert(f'File: {_tb_file}, line {_tb_line} in {_tb_func}')
121 self.alert(f' {_tb_text}')
123 self.err('>>> Exception Handler <<<')
124 for _tb_file, _tb_line, _tb_func, _tb_text in tb_data_stack:
125 self.alert(f'File: {_tb_file}, line {_tb_line} in {_tb_func}')
126 self.alert(f' {_tb_text}')
128 self.alert('--- END EXCEPTION ---')
131 class NullLog(AbstractLogBase):
132 def _write(self, mark: str, msg: Any):
133 pass
135 def __init__(self, *a, **kwa):
136 super().__init__('n')
138 def sub_log(self, name: str):
139 return self
141 @classmethod
142 def make(cls, *a, **kwa):
143 return cls()
145 def flush(self, *a, **kwa):
146 pass
148 @staticmethod
149 def init_syslog(ident):
150 pass