py.lib
py.lib/log/slog_syslogger.py
. Устанавливаем значение по умолчанию для нового лога
| awgur@13 | 1 # coding: utf-8 |
| awgur@13 | 2 |
| awgur@13 | 3 """\ |
| awgur@13 | 4 Логирование в системный журнал Unix |
| awgur@9 | 5 |
| awgur@9 | 6 Метки в журнале о уровне сообщения: |
| awgur@9 | 7 "`": Debug |
| awgur@9 | 8 ".": Info |
| awgur@9 | 9 "*": Warning |
| awgur@9 | 10 "!": Error |
| awgur@9 | 11 "#": Alert |
| awgur@9 | 12 """ |
| awgur@13 | 13 |
| awgur@9 | 14 import syslog |
| awgur@13 | 15 from sys import exc_info |
| awgur@9 | 16 from time import time |
| awgur@13 | 17 from traceback import extract_tb, extract_stack |
| awgur@13 | 18 from datetime import timedelta |
| awgur@22 | 19 from typing import Any |
| awgur@9 | 20 |
| awgur@9 | 21 LOG_FACILITY = { |
| awgur@9 | 22 'auth': syslog.LOG_AUTH, |
| awgur@9 | 23 'authpriv': syslog.LOG_AUTH, |
| awgur@9 | 24 'cron': syslog.LOG_CRON, |
| awgur@9 | 25 'daemon': syslog.LOG_DAEMON, |
| awgur@9 | 26 'ftp': syslog.LOG_DAEMON, |
| awgur@9 | 27 'kern': syslog.LOG_KERN, |
| awgur@9 | 28 'lpr': syslog.LOG_LPR, |
| awgur@9 | 29 'mail': syslog.LOG_MAIL, |
| awgur@9 | 30 'news': syslog.LOG_NEWS, |
| awgur@9 | 31 'syslog': syslog.LOG_SYSLOG, |
| awgur@9 | 32 'user': syslog.LOG_USER, |
| awgur@9 | 33 'uucp': syslog.LOG_UUCP, |
| awgur@9 | 34 'local0': syslog.LOG_LOCAL0, |
| awgur@9 | 35 'local1': syslog.LOG_LOCAL1, |
| awgur@9 | 36 'local2': syslog.LOG_LOCAL2, |
| awgur@9 | 37 'local3': syslog.LOG_LOCAL3, |
| awgur@9 | 38 'local4': syslog.LOG_LOCAL4, |
| awgur@9 | 39 'local5': syslog.LOG_LOCAL5, |
| awgur@9 | 40 'local6': syslog.LOG_LOCAL6, |
| awgur@9 | 41 'local7': syslog.LOG_LOCAL7 |
| awgur@9 | 42 } |
| awgur@9 | 43 |
| awgur@22 | 44 |
| awgur@13 | 45 class LoggerError(Exception): pass |
| awgur@13 | 46 |
| awgur@13 | 47 |
| awgur@9 | 48 # --- INTERFACE --- # |
| awgur@9 | 49 FACILITY = LOG_FACILITY['user'] |
| awgur@13 | 50 |
| awgur@13 | 51 |
| awgur@22 | 52 def check_facility(facility: str = 'user'): |
| awgur@22 | 53 if not facility.lower() in LOG_FACILITY: |
| awgur@22 | 54 raise LoggerError(f'Unknown facility: {facility}') |
| awgur@22 | 55 |
| awgur@22 | 56 |
| awgur@22 | 57 def log_prep(ident: str, facility: str = 'user'): |
| awgur@9 | 58 global FACILITY |
| awgur@22 | 59 check_facility(facility) |
| awgur@13 | 60 |
| awgur@9 | 61 syslog.openlog(ident, syslog.LOG_PID) |
| awgur@9 | 62 |
| awgur@9 | 63 FACILITY = LOG_FACILITY[facility] |
| awgur@9 | 64 |
| awgur@9 | 65 |
| awgur@13 | 66 class Timing(object): |
| awgur@22 | 67 def __init__(self, name: str = None): |
| awgur@13 | 68 if name is None: |
| awgur@13 | 69 self.prefix = '' |
| awgur@9 | 70 else: |
| awgur@22 | 71 self.prefix = f'{name} :: ' |
| awgur@13 | 72 self.tsAll = time() |
| awgur@13 | 73 self.ts = self.tsAll |
| awgur@9 | 74 |
| awgur@22 | 75 def get_time(self): |
| awgur@13 | 76 return time() - self.ts |
| awgur@9 | 77 |
| awgur@13 | 78 def reset(self): |
| awgur@13 | 79 self.ts = time() |
| awgur@13 | 80 self.tsAll = self.ts |
| awgur@9 | 81 |
| awgur@9 | 82 def __str__(self): |
| awgur@13 | 83 ts = time() |
| awgur@13 | 84 return self.prefix + '%s(%.4f)' % (timedelta(seconds=(ts - self.tsAll)), ts - self.ts) |
| awgur@9 | 85 |
| awgur@22 | 86 def __call__(self, msg: Any) -> str: |
| awgur@22 | 87 _buf = f'{self} | {msg}' |
| awgur@13 | 88 self.ts = time() |
| awgur@13 | 89 return _buf |
| awgur@9 | 90 |
| awgur@9 | 91 |
| awgur@13 | 92 class SysLogger(object): |
| awgur@13 | 93 init_log = log_prep |
| awgur@9 | 94 |
| awgur@13 | 95 @staticmethod |
| awgur@22 | 96 def get_timing(name: str = None): |
| awgur@13 | 97 return Timing(name) |
| awgur@9 | 98 |
| awgur@22 | 99 def __init__(self, prefix: str = 'main', facility: int = FACILITY): |
| awgur@13 | 100 self.prefix = str(prefix) |
| awgur@13 | 101 self.facility = facility |
| awgur@9 | 102 |
| awgur@22 | 103 def _write(self, flag: int, mark: str, msg: Any): |
| awgur@13 | 104 for l in str(msg).splitlines(): |
| awgur@22 | 105 syslog.syslog(self.facility | flag, f'{mark} {self.prefix}: {l}') |
| awgur@9 | 106 |
| awgur@22 | 107 def __call__(self, msg: Any): |
| awgur@13 | 108 self._write(syslog.LOG_INFO, '.', msg) |
| awgur@9 | 109 |
| awgur@22 | 110 def err(self, msg: Any): |
| awgur@13 | 111 self._write(syslog.LOG_ERR, '!', msg) |
| awgur@9 | 112 |
| awgur@22 | 113 def warn(self, msg: Any): |
| awgur@13 | 114 self._write(syslog.LOG_WARNING, '*', msg) |
| awgur@9 | 115 |
| awgur@22 | 116 def debug(self, msg: Any): |
| awgur@13 | 117 self._write(syslog.LOG_DEBUG, '`', msg) |
| awgur@9 | 118 |
| awgur@22 | 119 def alert(self, msg: Any): |
| awgur@13 | 120 self._write(syslog.LOG_ALERT, '#', msg) |
| awgur@9 | 121 |
| awgur@22 | 122 def sublog(self, prefix: str): |
| awgur@22 | 123 return self.__class__(f'{self.prefix}/{prefix}', self.facility) |
| awgur@9 | 124 |
| awgur@22 | 125 def excpt(self, msg: Any, e_class: type = None, e_obj: Exception = None, e_tb=None, stack_skip=0): |
| awgur@22 | 126 if e_class is None: |
| awgur@22 | 127 e_class, e_obj, e_tb = exc_info() |
| awgur@9 | 128 |
| awgur@22 | 129 if e_class is None: |
| awgur@13 | 130 # Если вдруг вызываем без произошедшего исключения |
| awgur@13 | 131 self.err(msg) |
| awgur@13 | 132 else: |
| awgur@22 | 133 tb_data_tb = list(extract_tb(e_tb))[::-1] |
| awgur@22 | 134 tb_data_stack = list(extract_stack())[::-1][(2 + stack_skip):] |
| awgur@9 | 135 |
| awgur@13 | 136 self.err(msg) |
| awgur@9 | 137 |
| awgur@13 | 138 self.err('--- EXCEPTION ---') |
| awgur@22 | 139 self.err(' %s (%s)' % (e_class.__name__, e_obj)) |
| awgur@9 | 140 |
| awgur@13 | 141 self.err('--- TRACEBACK ---') |
| awgur@22 | 142 for _tb_file, _tb_line, _tb_func, _tb_text in tb_data_tb: |
| awgur@22 | 143 self.err('File: %s, line %s in %s' % (_tb_file, _tb_line, _tb_func)) |
| awgur@22 | 144 self.err(' %s' % _tb_text) |
| awgur@9 | 145 |
| awgur@13 | 146 self.err('>>> Exception Handler <<<') |
| awgur@22 | 147 for _tb_file, _tb_line, _tb_func, _tb_text in tb_data_stack: |
| awgur@22 | 148 self.err('File: %s, line %s in %s' % (_tb_file, _tb_line, _tb_func)) |
| awgur@22 | 149 self.err(' %s' % _tb_text) |
| awgur@9 | 150 |
| awgur@13 | 151 self.err('--- END EXCEPTION ---') |