py.lib.aw_log

Yohn Y. 2024-02-11 Child:894923fbd0d0

0:41b53fd5637e Go to Latest

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

..init

History
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/aw_log/__init__.py	Sun Feb 11 13:53:23 2024 +0300
     1.3 @@ -0,0 +1,101 @@
     1.4 +# coding: utf-8
     1.5 +# devel.a0fs.ru -- aw_log -- v0.r202402.1
     1.6 +""" Реализация классов логирования
     1.7 +
     1.8 +Метки в журнале о уровне сообщения:
     1.9 +  "`": Debug
    1.10 +  ".": Info
    1.11 +  "*": Warning
    1.12 +  "!": Error
    1.13 +  "#": Alert
    1.14 +
    1.15 +"""
    1.16 +
    1.17 +from time import monotonic
    1.18 +from datetime import timedelta
    1.19 +from traceback import extract_tb, extract_stack
    1.20 +from typing import Optional, Any, Iterable
    1.21 +from sys import exc_info
    1.22 +
    1.23 +
    1.24 +class Timing(object):
    1.25 +    def __init__(self, name: Optional[str] = None):
    1.26 +        if name is None:
    1.27 +            self.prefix = ''
    1.28 +
    1.29 +        else:
    1.30 +            self.prefix = f'{name} :: '
    1.31 +
    1.32 +        self.tsAll = monotonic()
    1.33 +        self.ts = self.tsAll
    1.34 +
    1.35 +    def get_time(self):
    1.36 +        return monotonic() - self.ts
    1.37 +
    1.38 +    def reset(self):
    1.39 +        self.ts = monotonic()
    1.40 +        self.tsAll = self.ts
    1.41 +
    1.42 +    def __str__(self):
    1.43 +        ts = monotonic()
    1.44 +        return self.prefix + '%s(%.4f)' % (timedelta(seconds=(ts - self.tsAll)), ts - self.ts)
    1.45 +
    1.46 +    def __call__(self, msg):
    1.47 +        _buf = f'{self} | {msg}'
    1.48 +        self.ts = monotonic()
    1.49 +        return _buf
    1.50 +
    1.51 +
    1.52 +class AbstractLogBase(object):
    1.53 +    def __init__(self, prefix: str = 'main'):
    1.54 +        self.prefix = prefix
    1.55 +
    1.56 +    def _write_helper(self, mark: str, msg: Any) -> Iterable[str]:
    1.57 +        for l in str(msg).splitlines():
    1.58 +            yield f'{mark} {self.prefix} | {l}'
    1.59 +
    1.60 +    def _write(self, mark: str, msg: Any):
    1.61 +        raise NotImplemented(f'Метод write не определён для класса "{type(self).__name__}"')
    1.62 +
    1.63 +    def __call__(self, msg):
    1.64 +        self._write('.', msg)
    1.65 +
    1.66 +    def err(self, msg):
    1.67 +        self._write('!', msg)
    1.68 +
    1.69 +    def warn(self, msg):
    1.70 +        self._write('*', msg)
    1.71 +
    1.72 +    def alert(self, msg):
    1.73 +        self._write('#', msg)
    1.74 +
    1.75 +    def debug(self, msg):
    1.76 +        self._write('`', msg)
    1.77 +
    1.78 +    @staticmethod
    1.79 +    def get_timing(name: Optional[str] = None):
    1.80 +        return Timing(name)
    1.81 +
    1.82 +    def sub_log(self, name: str):
    1.83 +        return self.__class__(f'{self.prefix}/{name}')
    1.84 +
    1.85 +    def excpt(self, msg, e_class=None, e_obj=None, e_tb=None, stack_skip=0):
    1.86 +        if e_class is None:
    1.87 +            e_class, e_obj, e_tb = exc_info()
    1.88 +
    1.89 +        tb_data_tb = list(extract_tb(e_tb))[::-1]
    1.90 +        tb_data_stack = list(extract_stack())[::-1][(2 + stack_skip):]
    1.91 +        self.err(msg)
    1.92 +        self.err('--- EXCEPTION ---')
    1.93 +        self.err(f' {e_class.__name__} ({e_obj})')
    1.94 +        self.err('--- TRACEBACK ---')
    1.95 +        for _tb_file, _tb_line, _tb_func, _tb_text in tb_data_tb:
    1.96 +            self.err(f'File: {_tb_file}, line {_tb_line} in {_tb_func}')
    1.97 +            self.err(f'   {_tb_text}')
    1.98 +
    1.99 +        self.err('>>> Exception Handler <<<')
   1.100 +        for _tb_file, _tb_line, _tb_func, _tb_text in tb_data_stack:
   1.101 +            self.err(f'File: {_tb_file}, line {_tb_line} in {_tb_func}')
   1.102 +            self.err(f'   {_tb_text}')
   1.103 +
   1.104 +        self.err('--- END EXCEPTION ---')