py.lib
2023-01-28
Parent:log/tiny_slog.py@fe4a96d06243
py.lib/log/log_syslog.py
. Наведение порядка в коде логирования
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/log/log_syslog.py Sat Jan 28 16:39:53 2023 +0300 1.3 @@ -0,0 +1,105 @@ 1.4 +# coding: utf-8 1.5 +""" 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 +from time import monotonic 1.17 +from datetime import timedelta 1.18 + 1.19 +import syslog 1.20 +from traceback import extract_tb, extract_stack 1.21 +from sys import exc_info 1.22 + 1.23 + 1.24 +class Timing(object): 1.25 + def __init__(self, name=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 SysLogger(object): 1.53 + @staticmethod 1.54 + def init_syslog(ident): 1.55 + syslog.openlog(ident, syslog.LOG_PID) 1.56 + 1.57 + @staticmethod 1.58 + def get_timing(name=None): 1.59 + return Timing(name) 1.60 + 1.61 + def __init__(self, prefix='main', facility=syslog.LOG_USER): 1.62 + self.prefix = str(prefix) 1.63 + self.facility = facility 1.64 + 1.65 + def _write(self, flag, mark, msg): 1.66 + for l in str(msg).splitlines(): 1.67 + syslog.syslog(self.facility | flag, f'{mark} {self.prefix} | {l}') 1.68 + 1.69 + def __call__(self, msg): 1.70 + self._write(syslog.LOG_INFO, '.', msg) 1.71 + 1.72 + def err(self, msg): 1.73 + self._write(syslog.LOG_ERR, '!', msg) 1.74 + 1.75 + def warn(self, msg): 1.76 + self._write(syslog.LOG_WARNING, '*', msg) 1.77 + 1.78 + def debug(self, msg): 1.79 + self._write(syslog.LOG_DEBUG, '`', msg) 1.80 + 1.81 + def alert(self, msg): 1.82 + self._write(syslog.LOG_ALERT, '#', msg) 1.83 + 1.84 + def sub_log(self, prefix): 1.85 + return self.__class__(f'{self.prefix}/{prefix}', self.facility) 1.86 + 1.87 + def excpt(self, msg, e_class=None, e_obj=None, e_tback=None, stack_skip=0): 1.88 + if e_class is None: 1.89 + e_class, e_obj, e_tback = exc_info() 1.90 + 1.91 + tb_data_tb = list(extract_tb(e_tback))[::-1] 1.92 + tb_data_stack = list(extract_stack())[::-1][(2 + stack_skip):] 1.93 + 1.94 + self.err(msg) 1.95 + self.err('--- EXCEPTION ---') 1.96 + self.err(f' {e_class.__name__} ({e_obj})') 1.97 + 1.98 + self.err('--- TRACEBACK ---') 1.99 + for _tb_file, _tb_line, _tb_func, _tb_text in tb_data_tb: 1.100 + self.err(f'File: {_tb_file}, line {_tb_line} in {_tb_func}') 1.101 + self.err(f' {_tb_text}') 1.102 + 1.103 + self.err('>>> Exception Handler <<<') 1.104 + for _tb_file, _tb_line, _tb_func, _tb_text in tb_data_stack: 1.105 + self.err(f'File: {_tb_file}, line {_tb_line} in {_tb_func}') 1.106 + self.err(f' {_tb_text}') 1.107 + 1.108 + self.err('--- END EXCEPTION ---')