py.lib
11:9a4eb7660c11 Browse Files
+ Добавлены простые логгеры
log/__init__.py log/slog_console.py log/slog_syslogger.py log/syslogger.py syslogger.py
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/log/slog_console.py Mon Nov 11 21:18:14 2019 +0300 2.3 @@ -0,0 +1,123 @@ 2.4 +# coding: utf-8 2.5 +""" Логирование на консоль 2.6 + 2.7 +Метки в журнале о уровне сообщения: 2.8 + "`": Debug 2.9 + ".": Info 2.10 + "*": Warning 2.11 + "!": Error 2.12 + "#": Alert 2.13 +""" 2.14 + 2.15 +from time import time 2.16 +from datetime import timedelta 2.17 +from sys import exc_info, stderr, stdout 2.18 +from traceback import extract_tb, extract_stack 2.19 + 2.20 + 2.21 +class Timing(object): 2.22 + def __init__(self, name=None): 2.23 + if name is None: 2.24 + self.prefix = '' 2.25 + else: 2.26 + self.prefix = '%s :: ' % name 2.27 + self.tsAll = time() 2.28 + self.ts = self.tsAll 2.29 + 2.30 + def getTime(self): 2.31 + return time() - self.ts 2.32 + 2.33 + def reset(self): 2.34 + self.ts = time() 2.35 + self.tsAll = self.ts 2.36 + 2.37 + def __str__(self): 2.38 + ts = time() 2.39 + return self.prefix + '%s(%.4f)' % (timedelta(seconds=(ts - self.tsAll)), ts - self.ts) 2.40 + 2.41 + def __call__(self, msg): 2.42 + _buf = '%s | %s' % (self, msg) 2.43 + self.ts = time() 2.44 + return _buf 2.45 + 2.46 + 2.47 +class ConsoleLog(object): 2.48 + def __init__(self, appname='main'): 2.49 + self.appname = appname 2.50 + 2.51 + @staticmethod 2.52 + def _write(ItrCntnt): 2.53 + for l in ItrCntnt: 2.54 + print(l) 2.55 + 2.56 + def __call__(self, msg): 2.57 + self._write(map( 2.58 + lambda x: '%3s | %s :: %s' % ('.', self.appname, x), 2.59 + str(msg).splitlines() 2.60 + )) 2.61 + 2.62 + def err(self, msg): 2.63 + self._write(map( 2.64 + lambda x: '%3s | %s :: %s' % ('!', self.appname, x), 2.65 + str(msg).splitlines() 2.66 + )) 2.67 + 2.68 + def warn(self, msg): 2.69 + self._write(map( 2.70 + lambda x: '%3s | %s :: %s' % ('*', self.appname, x), 2.71 + str(msg).splitlines() 2.72 + )) 2.73 + 2.74 + def alert(self, msg): 2.75 + self._write(map( 2.76 + lambda x: '%3s | %s :: %s' % ('#', self.appname, x), 2.77 + str(msg).splitlines() 2.78 + )) 2.79 + 2.80 + def debug(self, msg): 2.81 + self._write(map( 2.82 + lambda x: '%3s | %s :: %s' % ('`', self.appname, x), 2.83 + str(msg).splitlines() 2.84 + )) 2.85 + 2.86 + @staticmethod 2.87 + def getTiming(name=None): 2.88 + return Timing(name) 2.89 + 2.90 + def sublog(self, name): 2.91 + return self.__class__('%s/%s' % (self.appname, name)) 2.92 + 2.93 + def excpt(self, msg, eClass=None, eObj=None, eTb=None, stack_skip=0): 2.94 + if eClass is None: 2.95 + eClass, eObj, eTb = exc_info() 2.96 + 2.97 + tbData_tb = list(extract_tb(eTb))[::-1] 2.98 + tbData_stack = list(extract_stack())[::-1][(2 + stack_skip):] 2.99 + self.err(msg) 2.100 + self.err('--- EXCEPTION ---') 2.101 + self.err(' %s (%s)' % (eClass.__name__, eObj)) 2.102 + self.err('--- TRACEBACK ---') 2.103 + for _tbFile, _tbLine, _tbFunc, _tbText in tbData_tb: 2.104 + self.err('File: %s, line %s in %s' % (_tbFile, _tbLine, _tbFunc)) 2.105 + self.err(' %s' % _tbText) 2.106 + self.err('>>> Exception Handler <<<') 2.107 + for _tbFile, _tbLine, _tbFunc, _tbText in tbData_stack: 2.108 + self.err('File: %s, line %s in %s' % (_tbFile, _tbLine, _tbFunc)) 2.109 + self.err(' %s' % _tbText) 2.110 + self.err('--- END EXCEPTION ---') 2.111 + 2.112 + 2.113 +class StderrLog(ConsoleLog): 2.114 + @staticmethod 2.115 + def _write(msgItr): 2.116 + for l in msgItr: 2.117 + stderr.write('%s\n' % l) 2.118 + stderr.flush() 2.119 + 2.120 + 2.121 +class StdoutLog(ConsoleLog): 2.122 + @staticmethod 2.123 + def _write(msgItr): 2.124 + for l in msgItr: 2.125 + stdout.write('%s\n' % l) 2.126 + stdout.flush()
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/log/slog_syslogger.py Mon Nov 11 21:18:14 2019 +0300 3.3 @@ -0,0 +1,99 @@ 3.4 +# coding: utf-8 3.5 +""" 3.6 +Тривиальная реализация сислоггера без блэк-джека и поэтесс 3.7 + 3.8 +Метки в журнале о уровне сообщения: 3.9 + "`": Debug 3.10 + ".": Info 3.11 + "*": Warning 3.12 + "!": Error 3.13 + "#": Alert 3.14 + 3.15 +""" 3.16 +from time import time 3.17 +from datetime import timedelta 3.18 + 3.19 +import syslog 3.20 +from traceback import extract_tb, extract_stack 3.21 +from sys import exc_info 3.22 + 3.23 + 3.24 +class Timing(object): 3.25 + def __init__(self, name=None): 3.26 + if name is None: 3.27 + self.prefix = '' 3.28 + else: 3.29 + self.prefix = '%s :: ' % name 3.30 + self.tsAll = time() 3.31 + self.ts = self.tsAll 3.32 + 3.33 + def getTime(self): 3.34 + return time() - self.ts 3.35 + 3.36 + def reset(self): 3.37 + self.ts = time() 3.38 + self.tsAll = self.ts 3.39 + 3.40 + def __str__(self): 3.41 + ts = time() 3.42 + return self.prefix + '%s(%.4f)' % (timedelta(seconds=(ts - self.tsAll)), ts - self.ts) 3.43 + 3.44 + def __call__(self, msg): 3.45 + _buf = '%s | %s' % (self, msg) 3.46 + self.ts = time() 3.47 + return _buf 3.48 + 3.49 + 3.50 +class SimpleSysLogger(object): 3.51 + @staticmethod 3.52 + def initSyslog(ident): 3.53 + syslog.openlog(ident, syslog.LOG_PID) 3.54 + 3.55 + @staticmethod 3.56 + def getTiming(name=None): 3.57 + return Timing(name) 3.58 + 3.59 + def __init__(self, prefix, facility=syslog.LOG_USER): 3.60 + self.prefix = str(prefix) 3.61 + self.facility = facility 3.62 + 3.63 + def _write(self, flag, mark, msg): 3.64 + for l in str(msg).splitlines(): 3.65 + syslog.syslog(self.facility | flag, '%s: %s %s' % (self.prefix, mark, l)) 3.66 + 3.67 + def __call__(self, msg): 3.68 + self._write(syslog.LOG_INFO, '.', msg) 3.69 + 3.70 + def err(self, msg): 3.71 + self._write(syslog.LOG_ERR, '!', msg) 3.72 + 3.73 + def warn(self, msg): 3.74 + self._write(syslog.LOG_WARNING, '*', msg) 3.75 + 3.76 + def debug(self, msg): 3.77 + self._write(syslog.LOG_DEBUG, '`', msg) 3.78 + 3.79 + def alert(self, msg): 3.80 + self._write(syslog.LOG_ALERT, '#', msg) 3.81 + 3.82 + def sublog(self, prefix): 3.83 + return self.__class__('%s/%s' % (self.prefix, prefix), self.facility) 3.84 + 3.85 + def excpt(self, msg, eClass=None, eObj=None, eTb=None, stack_skip=0): 3.86 + if eClass is None: 3.87 + eClass, eObj, eTb = exc_info() 3.88 + 3.89 + tbData_tb = list(extract_tb(eTb))[::-1] 3.90 + tbData_stack = list(extract_stack())[::-1][(2 + stack_skip):] 3.91 + self.err(msg) 3.92 + self.err('--- EXCEPTION ---') 3.93 + self.err(' %s (%s)' % (eClass.__name__, eObj)) 3.94 + self.err('--- TRACEBACK ---') 3.95 + for _tbFile, _tbLine, _tbFunc, _tbText in tbData_tb: 3.96 + self.err('File: %s, line %s in %s' % (_tbFile, _tbLine, _tbFunc)) 3.97 + self.err(' %s' % _tbText) 3.98 + self.err('>>> Exception Handler <<<') 3.99 + for _tbFile, _tbLine, _tbFunc, _tbText in tbData_stack: 3.100 + self.err('File: %s, line %s in %s' % (_tbFile, _tbLine, _tbFunc)) 3.101 + self.err(' %s' % _tbText) 3.102 + self.err('--- END EXCEPTION ---') 3.103 \ No newline at end of file
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/log/syslogger.py Mon Nov 11 21:18:14 2019 +0300 4.3 @@ -0,0 +1,278 @@ 4.4 +#!/usr/bin/env python 4.5 +# -*- coding: utf-8 -*- 4.6 +""" Логирование в системный журнал Unix 4.7 + 4.8 +Метки в журнале о уровне сообщения: 4.9 + "`": Debug 4.10 + ".": Info 4.11 + "*": Warning 4.12 + "!": Error 4.13 + "#": Alert 4.14 +""" 4.15 +import syslog 4.16 +from sys import argv, version_info, exc_info 4.17 +from time import time 4.18 +from traceback import extract_tb 4.19 + 4.20 +LOG_FACILITY = { 4.21 + 'auth': syslog.LOG_AUTH, 4.22 + 'authpriv': syslog.LOG_AUTH, 4.23 + 'cron': syslog.LOG_CRON, 4.24 + 'daemon': syslog.LOG_DAEMON, 4.25 + 'ftp': syslog.LOG_DAEMON, 4.26 + 'kern': syslog.LOG_KERN, 4.27 + 'lpr': syslog.LOG_LPR, 4.28 + 'mail': syslog.LOG_MAIL, 4.29 + 'news': syslog.LOG_NEWS, 4.30 + 'syslog': syslog.LOG_SYSLOG, 4.31 + 'user': syslog.LOG_USER, 4.32 + 'uucp': syslog.LOG_UUCP, 4.33 + 'local0': syslog.LOG_LOCAL0, 4.34 + 'local1': syslog.LOG_LOCAL1, 4.35 + 'local2': syslog.LOG_LOCAL2, 4.36 + 'local3': syslog.LOG_LOCAL3, 4.37 + 'local4': syslog.LOG_LOCAL4, 4.38 + 'local5': syslog.LOG_LOCAL5, 4.39 + 'local6': syslog.LOG_LOCAL6, 4.40 + 'local7': syslog.LOG_LOCAL7 4.41 +} 4.42 + 4.43 +# --- INTERFACE --- # 4.44 +FACILITY = LOG_FACILITY['user'] 4.45 +def logPrep(ident, facility='user'): 4.46 + global FACILITY 4.47 + if not facility.lower() in LOG_FACILITY: 4.48 + raise LoggerError('Unknown facility') 4.49 + syslog.openlog(ident, syslog.LOG_PID) 4.50 + 4.51 + FACILITY = LOG_FACILITY[facility] 4.52 + 4.53 + 4.54 +# --- ABSTRACT PART --- # 4.55 + 4.56 +LOG_DEBUG = "`" 4.57 +LOG_INFO = "." 4.58 +LOG_WARN = "*" 4.59 +LOG_ERR = "!" 4.60 +LOG_ALERT = "#" 4.61 + 4.62 +class LoggerError(Exception): pass 4.63 + 4.64 +if version_info.major == 3: 4.65 + def _strWrap(msg): 4.66 + return str(msg) 4.67 +elif version_info.major == 2: 4.68 + def _strWrap(msg): 4.69 + if isinstance(msg, unicode): 4.70 + return msg 4.71 + else: 4.72 + return str(msg).decode('utf-8') 4.73 +else: 4.74 + raise LoggerError('Unknown major version of Python') 4.75 + 4.76 + 4.77 +def _splitLines(obj): 4.78 + if isinstance(obj, (list, tuple)): 4.79 + for i in _parseList(obj): 4.80 + yield i 4.81 + elif isinstance(obj, dict): 4.82 + for i in _parseDict(obj): 4.83 + yield i 4.84 + else: 4.85 + buf = _strWrap(obj).splitlines() 4.86 + for i in buf: 4.87 + if len(i) < 401: 4.88 + yield i 4.89 + else: 4.90 + i = '<| ' + i + ' |>' 4.91 + lenI = len(i) 4.92 + c = 0 4.93 + while (c + 401) < lenI: 4.94 + yield i[c:c+401] 4.95 + c += 401 4.96 + yield i[c:] 4.97 + 4.98 +def _parseList(lst): 4.99 + for i in lst: 4.100 + i = _splitLines(i) 4.101 + try: 4.102 + yield '- %s' % next(i) 4.103 + for l in i: 4.104 + yield ' %s' % l 4.105 + except StopIteration: pass 4.106 + 4.107 +def _parseDict(dct): 4.108 + for key in sorted(dct): 4.109 + yield '%s:' % key 4.110 + for l in _splitLines(dct[key]): 4.111 + yield ' %s' % l 4.112 + 4.113 +def _parseArgs(a, kwa): 4.114 + if a: 4.115 + yield '| --- ARGS:' 4.116 + for i in _parseList(a): 4.117 + yield '| %s' % i 4.118 + 4.119 + if kwa: 4.120 + yield '| --- NAMED ARGS:' 4.121 + for i in _parseDict(kwa): 4.122 + yield '| %s' % i 4.123 + 4.124 + if a or kwa: 4.125 + yield '| ---' 4.126 + 4.127 +class TimingLog(): 4.128 + def __init__(self, logproc, opName): 4.129 + self.logproc = logproc 4.130 + self.opName = opName 4.131 + self.dt = time() 4.132 + 4.133 + def __str__(self): 4.134 + return '%s :: %.4f' % (self.opName, (time() - self.dt)) 4.135 + 4.136 + def __call__(self, msg, *a, **kwa): 4.137 + self.logproc('%s | %s' % (self, msg)) 4.138 + for i in _parseArgs(a, kwa): 4.139 + self.logproc('%s | %s' % (self, i)) 4.140 + 4.141 + def reset(self): 4.142 + self.dt = time() 4.143 + 4.144 + 4.145 +class OperationContext(object): 4.146 + def __init__(self, log, opName): 4.147 + self.opName = opName 4.148 + self.log = log 4.149 + self.msgBuf = [] 4.150 + 4.151 + def __call__(self, msg, *a, **kwa): 4.152 + self.msgBuf.append((msg, [ i for i in map(_strWrap, a)])) 4.153 + 4.154 + def __enter__(self): 4.155 + return self 4.156 + 4.157 + def __exit__(self, exc_type, exc_val, exc_tb): 4.158 + if exc_type is not None: 4.159 + self.log.err("Operation '%s' fail" % self.opName) 4.160 + self.log.excpt_handler(exc_type, exc_val, exc_tb) 4.161 + 4.162 + if self.msgBuf: 4.163 + self.log.err('--- MESSAGES ---') 4.164 + for msg, a, kwa in self.msgBuf: 4.165 + self.log.err(msg, a) 4.166 + self.log.err('--- END MESSAGES ---') 4.167 + 4.168 + 4.169 +class AbstractLogger(object): 4.170 + def err(self, msg, *a, **kwa): 4.171 + raise LoggerError('NotImplemented') 4.172 + 4.173 + def __call__(self, msg, *a, **kwa): 4.174 + raise LoggerError('NotImplemented') 4.175 + 4.176 + def excpt_handler(self, eType, eObj, eTb): 4.177 + eTb = extract_tb(eTb) 4.178 + eType = str(eType) 4.179 + try: 4.180 + eType = eType.split("'")[1] 4.181 + except IndexError: 4.182 + pass 4.183 + 4.184 + try: 4.185 + eArgs = eObj.args[1:] 4.186 + except: 4.187 + eArgs = [] 4.188 + 4.189 + try: 4.190 + eKwa = eObj.kwa 4.191 + except: 4.192 + eKwa = {} 4.193 + 4.194 + eObj = str(eObj) 4.195 + 4.196 + self.err('--- EXCEPTION ---') 4.197 + self.err(eType) 4.198 + 4.199 + for l in _splitLines(eObj): 4.200 + self.err(' ' + l) 4.201 + 4.202 + for l in _parseArgs(eArgs, eKwa): 4.203 + self.err(l) 4.204 + 4.205 + self.err('--- TRACEBACK ---') 4.206 + for _tbFile, _tbLine, _tbFunc, _tbText in eTb: 4.207 + self.err('File: %s, line %s in %s' % (_tbFile, _tbLine, _tbFunc)) 4.208 + self.err(' %s' % _tbText) 4.209 + self.err('--- END EXCEPTION ---') 4.210 + 4.211 + def excpt(self, msg, *a, **kwa): 4.212 + eType, eObj, eTb = exc_info() 4.213 + self.err(msg, *a, **kwa) 4.214 + self.excpt_handler(eType, eObj, eTb) 4.215 + 4.216 + def cntxt(self, opName): 4.217 + """ 4.218 + Если операцию нужно залогировать но при этом совершенно не хочется покрывать код 4.219 + толстым слоем try ... except можно завернуть операцию в контекст, и даже сохранить 4.220 + возвращаемом логером объекте отладочную информацию. При падении и только при нём 4.221 + это обязательно попадёт в лог. 4.222 + 4.223 + ОСТОРОЖНО ПАМЯТЬ!!!!! 4.224 + Объект копирует себе все переданные данные и опреобразует их сразу в строки 4.225 + Если объекту передать одни и те же параметры они всё равно будут храниться 4.226 + по копии на каждый вызов в виде строк, что может сьесть много памяти и вызвать 4.227 + болезненное её особождение. 4.228 + 4.229 + :param opName: членораздельное имя операции 4.230 + """ 4.231 + return OperationContext(self, opName) 4.232 + 4.233 + def getTiming(self, opName): 4.234 + return TimingLog(self, opName) 4.235 + 4.236 + def dumpDict(self, msg, dct): 4.237 + self('--- ' + _strWrap(msg)) 4.238 + for i in _parseDict(dct): 4.239 + self('| ' + i) 4.240 + self('---') 4.241 + 4.242 + @staticmethod 4.243 + def logPrep(*a, **kwa): 4.244 + logPrep(*a, **kwa) 4.245 + 4.246 +# --- END ABSTRACT PART --- # 4.247 + 4.248 +class Logger(AbstractLogger): 4.249 + facility = FACILITY 4.250 + def __init__(self, modName = 'main'): 4.251 + self.name = modName 4.252 + 4.253 + def _write(self, flags, prefix, msg): 4.254 + syslog.syslog(flags, u"%s %s: %s" % (prefix, self.name, msg)) 4.255 + 4.256 + def __call__(self, msg, *a, **kwa): 4.257 + _flags = self.facility | syslog.LOG_INFO 4.258 + _prefix = LOG_INFO + ' ' + self.name + ': ' 4.259 + syslog.syslog(_flags, _prefix + _strWrap(msg)) 4.260 + for i in _parseArgs(a, kwa): 4.261 + syslog.syslog(_flags, _prefix + i) 4.262 + 4.263 + def warn(self, msg, *a, **kwa): 4.264 + _flags = self.facility | syslog.LOG_WARNING 4.265 + _prefix = LOG_WARN + ' ' + self.name + ': ' 4.266 + syslog.syslog(_flags, _prefix + _strWrap(msg)) 4.267 + for i in _parseArgs(a, kwa): 4.268 + syslog.syslog(_flags, _prefix + i) 4.269 + 4.270 + def err(self, msg, *a, **kwa): 4.271 + _flags = self.facility | syslog.LOG_ERR 4.272 + _prefix = LOG_ERR + ' ' + self.name + ': ' 4.273 + syslog.syslog(_flags, _prefix + _strWrap(msg)) 4.274 + for i in _parseArgs(a, kwa): 4.275 + syslog.syslog(_flags, _prefix + i) 4.276 + 4.277 + 4.278 + 4.279 + 4.280 + 4.281 +
5.1 --- a/syslogger.py Tue Oct 01 23:14:52 2019 +0300 5.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 5.3 @@ -1,278 +0,0 @@ 5.4 -#!/usr/bin/env python 5.5 -# -*- coding: utf-8 -*- 5.6 -""" Логирование в системный журнал Unix 5.7 - 5.8 -Метки в журнале о уровне сообщения: 5.9 - "`": Debug 5.10 - ".": Info 5.11 - "*": Warning 5.12 - "!": Error 5.13 - "#": Alert 5.14 -""" 5.15 -import syslog 5.16 -from sys import argv, version_info, exc_info 5.17 -from time import time 5.18 -from traceback import extract_tb 5.19 - 5.20 -LOG_FACILITY = { 5.21 - 'auth': syslog.LOG_AUTH, 5.22 - 'authpriv': syslog.LOG_AUTH, 5.23 - 'cron': syslog.LOG_CRON, 5.24 - 'daemon': syslog.LOG_DAEMON, 5.25 - 'ftp': syslog.LOG_DAEMON, 5.26 - 'kern': syslog.LOG_KERN, 5.27 - 'lpr': syslog.LOG_LPR, 5.28 - 'mail': syslog.LOG_MAIL, 5.29 - 'news': syslog.LOG_NEWS, 5.30 - 'syslog': syslog.LOG_SYSLOG, 5.31 - 'user': syslog.LOG_USER, 5.32 - 'uucp': syslog.LOG_UUCP, 5.33 - 'local0': syslog.LOG_LOCAL0, 5.34 - 'local1': syslog.LOG_LOCAL1, 5.35 - 'local2': syslog.LOG_LOCAL2, 5.36 - 'local3': syslog.LOG_LOCAL3, 5.37 - 'local4': syslog.LOG_LOCAL4, 5.38 - 'local5': syslog.LOG_LOCAL5, 5.39 - 'local6': syslog.LOG_LOCAL6, 5.40 - 'local7': syslog.LOG_LOCAL7 5.41 -} 5.42 - 5.43 -# --- INTERFACE --- # 5.44 -FACILITY = LOG_FACILITY['user'] 5.45 -def logPrep(ident, facility='user'): 5.46 - global FACILITY 5.47 - if not facility.lower() in LOG_FACILITY: 5.48 - raise LoggerError('Unknown facility') 5.49 - syslog.openlog(ident, syslog.LOG_PID) 5.50 - 5.51 - FACILITY = LOG_FACILITY[facility] 5.52 - 5.53 - 5.54 -# --- ABSTRACT PART --- # 5.55 - 5.56 -LOG_DEBUG = "`" 5.57 -LOG_INFO = "." 5.58 -LOG_WARN = "*" 5.59 -LOG_ERR = "!" 5.60 -LOG_ALERT = "#" 5.61 - 5.62 -class LoggerError(Exception): pass 5.63 - 5.64 -if version_info.major == 3: 5.65 - def _strWrap(msg): 5.66 - return str(msg) 5.67 -elif version_info.major == 2: 5.68 - def _strWrap(msg): 5.69 - if isinstance(msg, unicode): 5.70 - return msg 5.71 - else: 5.72 - return str(msg).decode('utf-8') 5.73 -else: 5.74 - raise LoggerError('Unknown major version of Python') 5.75 - 5.76 - 5.77 -def _splitLines(obj): 5.78 - if isinstance(obj, (list, tuple)): 5.79 - for i in _parseList(obj): 5.80 - yield i 5.81 - elif isinstance(obj, dict): 5.82 - for i in _parseDict(obj): 5.83 - yield i 5.84 - else: 5.85 - buf = _strWrap(obj).splitlines() 5.86 - for i in buf: 5.87 - if len(i) < 401: 5.88 - yield i 5.89 - else: 5.90 - i = '<| ' + i + ' |>' 5.91 - lenI = len(i) 5.92 - c = 0 5.93 - while (c + 401) < lenI: 5.94 - yield i[c:c+401] 5.95 - c += 401 5.96 - yield i[c:] 5.97 - 5.98 -def _parseList(lst): 5.99 - for i in lst: 5.100 - i = _splitLines(i) 5.101 - try: 5.102 - yield '- %s' % next(i) 5.103 - for l in i: 5.104 - yield ' %s' % l 5.105 - except StopIteration: pass 5.106 - 5.107 -def _parseDict(dct): 5.108 - for key in sorted(dct): 5.109 - yield '%s:' % key 5.110 - for l in _splitLines(dct[key]): 5.111 - yield ' %s' % l 5.112 - 5.113 -def _parseArgs(a, kwa): 5.114 - if a: 5.115 - yield '| --- ARGS:' 5.116 - for i in _parseList(a): 5.117 - yield '| %s' % i 5.118 - 5.119 - if kwa: 5.120 - yield '| --- NAMED ARGS:' 5.121 - for i in _parseDict(kwa): 5.122 - yield '| %s' % i 5.123 - 5.124 - if a or kwa: 5.125 - yield '| ---' 5.126 - 5.127 -class TimingLog(): 5.128 - def __init__(self, logproc, opName): 5.129 - self.logproc = logproc 5.130 - self.opName = opName 5.131 - self.dt = time() 5.132 - 5.133 - def __str__(self): 5.134 - return '%s :: %.4f' % (self.opName, (time() - self.dt)) 5.135 - 5.136 - def __call__(self, msg, *a, **kwa): 5.137 - self.logproc('%s | %s' % (self, msg)) 5.138 - for i in _parseArgs(a, kwa): 5.139 - self.logproc('%s | %s' % (self, i)) 5.140 - 5.141 - def reset(self): 5.142 - self.dt = time() 5.143 - 5.144 - 5.145 -class OperationContext(object): 5.146 - def __init__(self, log, opName): 5.147 - self.opName = opName 5.148 - self.log = log 5.149 - self.msgBuf = [] 5.150 - 5.151 - def __call__(self, msg, *a, **kwa): 5.152 - self.msgBuf.append((msg, [ i for i in map(_strWrap, a)])) 5.153 - 5.154 - def __enter__(self): 5.155 - return self 5.156 - 5.157 - def __exit__(self, exc_type, exc_val, exc_tb): 5.158 - if exc_type is not None: 5.159 - self.log.err("Operation '%s' fail" % self.opName) 5.160 - self.log.excpt_handler(exc_type, exc_val, exc_tb) 5.161 - 5.162 - if self.msgBuf: 5.163 - self.log.err('--- MESSAGES ---') 5.164 - for msg, a, kwa in self.msgBuf: 5.165 - self.log.err(msg, a) 5.166 - self.log.err('--- END MESSAGES ---') 5.167 - 5.168 - 5.169 -class AbstractLogger(object): 5.170 - def err(self, msg, *a, **kwa): 5.171 - raise LoggerError('NotImplemented') 5.172 - 5.173 - def __call__(self, msg, *a, **kwa): 5.174 - raise LoggerError('NotImplemented') 5.175 - 5.176 - def excpt_handler(self, eType, eObj, eTb): 5.177 - eTb = extract_tb(eTb) 5.178 - eType = str(eType) 5.179 - try: 5.180 - eType = eType.split("'")[1] 5.181 - except IndexError: 5.182 - pass 5.183 - 5.184 - try: 5.185 - eArgs = eObj.args[1:] 5.186 - except: 5.187 - eArgs = [] 5.188 - 5.189 - try: 5.190 - eKwa = eObj.kwa 5.191 - except: 5.192 - eKwa = {} 5.193 - 5.194 - eObj = str(eObj) 5.195 - 5.196 - self.err('--- EXCEPTION ---') 5.197 - self.err(eType) 5.198 - 5.199 - for l in _splitLines(eObj): 5.200 - self.err(' ' + l) 5.201 - 5.202 - for l in _parseArgs(eArgs, eKwa): 5.203 - self.err(l) 5.204 - 5.205 - self.err('--- TRACEBACK ---') 5.206 - for _tbFile, _tbLine, _tbFunc, _tbText in eTb: 5.207 - self.err('File: %s, line %s in %s' % (_tbFile, _tbLine, _tbFunc)) 5.208 - self.err(' %s' % _tbText) 5.209 - self.err('--- END EXCEPTION ---') 5.210 - 5.211 - def excpt(self, msg, *a, **kwa): 5.212 - eType, eObj, eTb = exc_info() 5.213 - self.err(msg, *a, **kwa) 5.214 - self.excpt_handler(eType, eObj, eTb) 5.215 - 5.216 - def cntxt(self, opName): 5.217 - """ 5.218 - Если операцию нужно залогировать но при этом совершенно не хочется покрывать код 5.219 - толстым слоем try ... except можно завернуть операцию в контекст, и даже сохранить 5.220 - возвращаемом логером объекте отладочную информацию. При падении и только при нём 5.221 - это обязательно попадёт в лог. 5.222 - 5.223 - ОСТОРОЖНО ПАМЯТЬ!!!!! 5.224 - Объект копирует себе все переданные данные и опреобразует их сразу в строки 5.225 - Если объекту передать одни и те же параметры они всё равно будут храниться 5.226 - по копии на каждый вызов в виде строк, что может сьесть много памяти и вызвать 5.227 - болезненное её особождение. 5.228 - 5.229 - :param opName: членораздельное имя операции 5.230 - """ 5.231 - return OperationContext(self, opName) 5.232 - 5.233 - def getTiming(self, opName): 5.234 - return TimingLog(self, opName) 5.235 - 5.236 - def dumpDict(self, msg, dct): 5.237 - self('--- ' + _strWrap(msg)) 5.238 - for i in _parseDict(dct): 5.239 - self('| ' + i) 5.240 - self('---') 5.241 - 5.242 - @staticmethod 5.243 - def logPrep(*a, **kwa): 5.244 - logPrep(*a, **kwa) 5.245 - 5.246 -# --- END ABSTRACT PART --- # 5.247 - 5.248 -class Logger(AbstractLogger): 5.249 - facility = FACILITY 5.250 - def __init__(self, modName = 'main'): 5.251 - self.name = modName 5.252 - 5.253 - def _write(self, flags, prefix, msg): 5.254 - syslog.syslog(flags, u"%s %s: %s" % (prefix, self.name, msg)) 5.255 - 5.256 - def __call__(self, msg, *a, **kwa): 5.257 - _flags = self.facility | syslog.LOG_INFO 5.258 - _prefix = LOG_INFO + ' ' + self.name + ': ' 5.259 - syslog.syslog(_flags, _prefix + _strWrap(msg)) 5.260 - for i in _parseArgs(a, kwa): 5.261 - syslog.syslog(_flags, _prefix + i) 5.262 - 5.263 - def warn(self, msg, *a, **kwa): 5.264 - _flags = self.facility | syslog.LOG_WARNING 5.265 - _prefix = LOG_WARN + ' ' + self.name + ': ' 5.266 - syslog.syslog(_flags, _prefix + _strWrap(msg)) 5.267 - for i in _parseArgs(a, kwa): 5.268 - syslog.syslog(_flags, _prefix + i) 5.269 - 5.270 - def err(self, msg, *a, **kwa): 5.271 - _flags = self.facility | syslog.LOG_ERR 5.272 - _prefix = LOG_ERR + ' ' + self.name + ': ' 5.273 - syslog.syslog(_flags, _prefix + _strWrap(msg)) 5.274 - for i in _parseArgs(a, kwa): 5.275 - syslog.syslog(_flags, _prefix + i) 5.276 - 5.277 - 5.278 - 5.279 - 5.280 - 5.281 -