py.lib

Yohn Y. 2023-01-30 Parent:6f8bea109183

44:bfc3a109c06c Go to Latest

py.lib/log/log_syslog.py

. Убираем лишние форматированные строки * Проблема с созданием вложенных журналов в сложных ситуациях с локами и ротируемым журналом.

History
awgur@28 1 # coding: utf-8
awgur@28 2 """
awgur@28 3 Тривиальная реализация сислоггера без блэк-джека и поэтесс
awgur@28 4
awgur@28 5 Метки в журнале о уровне сообщения:
awgur@28 6 "`": Debug
awgur@28 7 ".": Info
awgur@28 8 "*": Warning
awgur@28 9 "!": Error
awgur@28 10 "#": Alert
awgur@28 11
awgur@28 12 """
awgur@30 13 from time import monotonic
awgur@28 14 from datetime import timedelta
awgur@28 15
awgur@28 16 import syslog
awgur@28 17 from traceback import extract_tb, extract_stack
awgur@28 18 from sys import exc_info
awgur@28 19
awgur@28 20
awgur@28 21 class Timing(object):
awgur@28 22 def __init__(self, name=None):
awgur@28 23 if name is None:
awgur@28 24 self.prefix = ''
awgur@43 25
awgur@28 26 else:
awgur@43 27 self.prefix = f'{name} :: '
awgur@43 28
awgur@30 29 self.tsAll = monotonic()
awgur@28 30 self.ts = self.tsAll
awgur@28 31
awgur@43 32 def get_time(self):
awgur@30 33 return monotonic() - self.ts
awgur@28 34
awgur@28 35 def reset(self):
awgur@30 36 self.ts = monotonic()
awgur@28 37 self.tsAll = self.ts
awgur@28 38
awgur@28 39 def __str__(self):
awgur@30 40 ts = monotonic()
awgur@28 41 return self.prefix + '%s(%.4f)' % (timedelta(seconds=(ts - self.tsAll)), ts - self.ts)
awgur@28 42
awgur@28 43 def __call__(self, msg):
awgur@43 44 _buf = f'{self} | {msg}'
awgur@30 45 self.ts = monotonic()
awgur@28 46 return _buf
awgur@28 47
awgur@28 48
awgur@43 49 class SysLogger(object):
awgur@28 50 @staticmethod
awgur@28 51 def init_syslog(ident):
awgur@28 52 syslog.openlog(ident, syslog.LOG_PID)
awgur@28 53
awgur@28 54 @staticmethod
awgur@28 55 def get_timing(name=None):
awgur@28 56 return Timing(name)
awgur@28 57
awgur@29 58 def __init__(self, prefix='main', facility=syslog.LOG_USER):
awgur@28 59 self.prefix = str(prefix)
awgur@28 60 self.facility = facility
awgur@28 61
awgur@28 62 def _write(self, flag, mark, msg):
awgur@28 63 for l in str(msg).splitlines():
awgur@43 64 syslog.syslog(self.facility | flag, f'{mark} {self.prefix} | {l}')
awgur@28 65
awgur@28 66 def __call__(self, msg):
awgur@28 67 self._write(syslog.LOG_INFO, '.', msg)
awgur@28 68
awgur@28 69 def err(self, msg):
awgur@28 70 self._write(syslog.LOG_ERR, '!', msg)
awgur@28 71
awgur@28 72 def warn(self, msg):
awgur@28 73 self._write(syslog.LOG_WARNING, '*', msg)
awgur@28 74
awgur@28 75 def debug(self, msg):
awgur@28 76 self._write(syslog.LOG_DEBUG, '`', msg)
awgur@28 77
awgur@28 78 def alert(self, msg):
awgur@28 79 self._write(syslog.LOG_ALERT, '#', msg)
awgur@28 80
awgur@28 81 def sub_log(self, prefix):
awgur@43 82 return self.__class__(f'{self.prefix}/{prefix}', self.facility)
awgur@28 83
awgur@28 84 def excpt(self, msg, e_class=None, e_obj=None, e_tback=None, stack_skip=0):
awgur@28 85 if e_class is None:
awgur@28 86 e_class, e_obj, e_tback = exc_info()
awgur@28 87
awgur@28 88 tb_data_tb = list(extract_tb(e_tback))[::-1]
awgur@28 89 tb_data_stack = list(extract_stack())[::-1][(2 + stack_skip):]
awgur@28 90
awgur@28 91 self.err(msg)
awgur@28 92 self.err('--- EXCEPTION ---')
awgur@43 93 self.err(f' {e_class.__name__} ({e_obj})')
awgur@28 94
awgur@28 95 self.err('--- TRACEBACK ---')
awgur@28 96 for _tb_file, _tb_line, _tb_func, _tb_text in tb_data_tb:
awgur@43 97 self.err(f'File: {_tb_file}, line {_tb_line} in {_tb_func}')
awgur@43 98 self.err(f' {_tb_text}')
awgur@28 99
awgur@28 100 self.err('>>> Exception Handler <<<')
awgur@28 101 for _tb_file, _tb_line, _tb_func, _tb_text in tb_data_stack:
awgur@43 102 self.err(f'File: {_tb_file}, line {_tb_line} in {_tb_func}')
awgur@43 103 self.err(f' {_tb_text}')
awgur@28 104
awgur@28 105 self.err('--- END EXCEPTION ---')