tools.win_pg_dump_controller

Yohn Y. 2022-06-13 Parent:7c93b0305522

6:26558a3ee4f3 Go to Latest

tools.win_pg_dump_controller/win_pg_dump_controller/log_controller.py

Добавлен GIT репозиторий для тестов

History
awgur@0 1 # coding: utf-8
awgur@0 2 """\
awgur@0 3 Модуль логирования
awgur@0 4
awgur@0 5 Метки в журнале о уровне сообщения:
awgur@0 6 "`": Debug
awgur@0 7 ".": Info
awgur@0 8 "*": Warning
awgur@0 9 "!": Error
awgur@0 10 "#": Alert
awgur@0 11 """
awgur@0 12
awgur@0 13 from time import time, ctime
awgur@0 14 from datetime import timedelta, datetime
awgur@0 15 from sys import exc_info
awgur@0 16 from os.path import join as p_join
awgur@0 17 from os import listdir, remove as file_remove, stat
awgur@0 18 from traceback import extract_tb, extract_stack
awgur@0 19 from typing import Optional
awgur@0 20
awgur@0 21 from .config import Config
awgur@0 22
awgur@0 23
awgur@0 24 class Timing(object):
awgur@0 25 def __init__(self, name: Optional[str] = None):
awgur@0 26 if name is None:
awgur@0 27 self.prefix = ''
awgur@0 28 else:
awgur@0 29 self.prefix = f'{name} :: '
awgur@0 30 self.tsAll = time()
awgur@0 31 self.ts = self.tsAll
awgur@0 32
awgur@0 33 def get_time(self):
awgur@0 34 return time() - self.ts
awgur@0 35
awgur@0 36 def reset(self):
awgur@0 37 self.ts = time()
awgur@0 38 self.tsAll = self.ts
awgur@0 39
awgur@0 40 def __str__(self):
awgur@0 41 ts = time()
awgur@0 42 return self.prefix + '%s(%.4f)' % (timedelta(seconds=(ts - self.tsAll)), ts - self.ts)
awgur@0 43
awgur@0 44 def __call__(self, msg):
awgur@0 45 _buf = f'{self} | {msg}'
awgur@0 46 self.ts = time()
awgur@0 47 return _buf
awgur@0 48
awgur@0 49
awgur@0 50 class BaseLogger(object):
awgur@0 51 def __init__(self, appname='main'):
awgur@0 52 self.appname = appname
awgur@0 53
awgur@0 54 @staticmethod
awgur@0 55 def _write(itr_content):
awgur@0 56 raise NotImplemented()
awgur@0 57
awgur@0 58 def __call__(self, msg):
awgur@0 59 self._write(map(
awgur@0 60 lambda x: '%3s | %s :: %s' % ('.', self.appname, x),
awgur@0 61 str(msg).splitlines()
awgur@0 62 ))
awgur@0 63
awgur@0 64 def err(self, msg):
awgur@0 65 self._write(map(
awgur@0 66 lambda x: '%3s | %s :: %s' % ('!', self.appname, x),
awgur@0 67 str(msg).splitlines()
awgur@0 68 ))
awgur@0 69
awgur@0 70 def warn(self, msg):
awgur@0 71 self._write(map(
awgur@0 72 lambda x: '%3s | %s :: %s' % ('*', self.appname, x),
awgur@0 73 str(msg).splitlines()
awgur@0 74 ))
awgur@0 75
awgur@0 76 def alert(self, msg):
awgur@0 77 self._write(map(
awgur@0 78 lambda x: '%3s | %s :: %s' % ('#', self.appname, x),
awgur@0 79 str(msg).splitlines()
awgur@0 80 ))
awgur@0 81
awgur@0 82 def debug(self, msg):
awgur@0 83 self._write(map(
awgur@0 84 lambda x: '%3s | %s :: %s' % ('`', self.appname, x),
awgur@0 85 str(msg).splitlines()
awgur@0 86 ))
awgur@0 87
awgur@0 88 @staticmethod
awgur@0 89 def get_timing(name: Optional[str] = None):
awgur@0 90 return Timing(name)
awgur@0 91
awgur@0 92 def sublog(self, name):
awgur@0 93 return self.__class__(f'{self.appname}/{name}')
awgur@0 94
awgur@0 95 def excpt(self, msg, e_class=None, e_obj=None, e_tb=None, stack_skip=0):
awgur@0 96 if e_class is None:
awgur@0 97 e_class, e_obj, e_tb = exc_info()
awgur@0 98
awgur@0 99 tb_data_tb = list(extract_tb(e_tb))[::-1]
awgur@0 100 tb_data_stack = list(extract_stack())[::-1][(2 + stack_skip):]
awgur@0 101 self.err(msg)
awgur@0 102 self.err('--- EXCEPTION ---')
awgur@0 103 self.err(' %s (%s)' % (e_class.__name__, e_obj))
awgur@0 104 self.err('--- TRACEBACK ---')
awgur@0 105 for _tbFile, _tbLine, _tbFunc, _tbText in tb_data_tb:
awgur@0 106 self.err('File: %s, line %s in %s' % (_tbFile, _tbLine, _tbFunc))
awgur@0 107 self.err(' %s' % _tbText)
awgur@0 108 self.err('>>> Exception Handler <<<')
awgur@0 109 for _tbFile, _tbLine, _tbFunc, _tbText in tb_data_stack:
awgur@0 110 self.err('File: %s, line %s in %s' % (_tbFile, _tbLine, _tbFunc))
awgur@0 111 self.err(' %s' % _tbText)
awgur@0 112 self.err('--- END EXCEPTION ---')
awgur@0 113
awgur@0 114
awgur@0 115 class NullLogger(BaseLogger):
awgur@0 116 @staticmethod
awgur@0 117 def _write(itr_content):
awgur@0 118 pass
awgur@0 119
awgur@0 120
awgur@0 121 class FileLogger(BaseLogger):
awgur@0 122 def __init__(self, filename: str, appname: str = 'main'):
awgur@0 123 super().__init__(appname)
awgur@0 124 self.fd = open(filename, 'a')
awgur@0 125
awgur@0 126 def _write(self, itr_content):
awgur@0 127 cur_time = ctime()
awgur@0 128 for i in itr_content:
awgur@0 129 self.fd.write(f'{cur_time}{i}\n')
awgur@0 130
awgur@0 131 self.fd.flush()
awgur@0 132
awgur@0 133 def __del__(self):
awgur@0 134 try:
awgur@0 135 self.fd.close()
awgur@0 136 except:
awgur@0 137 pass
awgur@0 138
awgur@0 139
awgur@0 140 class LogController(object):
awgur@0 141 def __init__(self, config: Config):
awgur@0 142 self.log_dir = config.log_dir
awgur@0 143 self.keep_logs_days = config.keep_logs_days
awgur@2 144 self.log_files = []
awgur@2 145 self.main_log = None
awgur@0 146
awgur@0 147 @staticmethod
awgur@0 148 def _get_timeprefix() -> str:
awgur@0 149 return datetime.now().strftime('%Y-%m-%d_%H-%M-%S')
awgur@0 150
awgur@0 151 def get_logger(self, name: str) -> BaseLogger:
awgur@0 152 if self.log_dir is not None:
awgur@2 153 _log_name = p_join(self.log_dir, f'{self._get_timeprefix()} - {name}.log')
awgur@2 154 if name.lower() != 'main':
awgur@2 155 self.log_files.append(_log_name)
awgur@2 156
awgur@2 157 else:
awgur@2 158 self.main_log = _log_name
awgur@2 159
awgur@2 160 return FileLogger(_log_name, appname=name)
awgur@2 161
awgur@0 162 else:
awgur@0 163 return NullLogger(appname=name)
awgur@0 164
awgur@0 165 def get_filename(self, name: str) -> Optional[str]:
awgur@0 166 if self.log_dir is not None:
awgur@0 167 return str(p_join(self.log_dir, f'{self._get_timeprefix()} - {name}.log'))
awgur@0 168
awgur@0 169 def clean(self):
awgur@0 170 if self.log_dir is not None:
awgur@0 171 now = time()
awgur@0 172 for f in listdir(self.log_dir):
awgur@0 173 f_path = p_join(self.log_dir, f)
awgur@0 174 f_stat = stat(f_path)
awgur@0 175
awgur@0 176 if divmod(now - f_stat.st_ctime, 86400)[0] > self.keep_logs_days:
awgur@0 177 file_remove(f_path)