py.lib
10:af2bf518950a
Go to Latest
py.lib/syslogger.py
+ Модуль - сосуд всяких идей по рабоче с SSH. Вообще нужно разобрать его
2 # -*- coding: utf-8 -*-
3 """ Логирование в системный журнал Unix
5 Метки в журнале о уровне сообщения:
13 from sys import argv, version_info, exc_info
15 from traceback import extract_tb
18 'auth': syslog.LOG_AUTH,
19 'authpriv': syslog.LOG_AUTH,
20 'cron': syslog.LOG_CRON,
21 'daemon': syslog.LOG_DAEMON,
22 'ftp': syslog.LOG_DAEMON,
23 'kern': syslog.LOG_KERN,
24 'lpr': syslog.LOG_LPR,
25 'mail': syslog.LOG_MAIL,
26 'news': syslog.LOG_NEWS,
27 'syslog': syslog.LOG_SYSLOG,
28 'user': syslog.LOG_USER,
29 'uucp': syslog.LOG_UUCP,
30 'local0': syslog.LOG_LOCAL0,
31 'local1': syslog.LOG_LOCAL1,
32 'local2': syslog.LOG_LOCAL2,
33 'local3': syslog.LOG_LOCAL3,
34 'local4': syslog.LOG_LOCAL4,
35 'local5': syslog.LOG_LOCAL5,
36 'local6': syslog.LOG_LOCAL6,
37 'local7': syslog.LOG_LOCAL7
41 FACILITY = LOG_FACILITY['user']
42 def logPrep(ident, facility='user'):
44 if not facility.lower() in LOG_FACILITY:
45 raise LoggerError('Unknown facility')
46 syslog.openlog(ident, syslog.LOG_PID)
48 FACILITY = LOG_FACILITY[facility]
51 # --- ABSTRACT PART --- #
59 class LoggerError(Exception): pass
61 if version_info.major == 3:
64 elif version_info.major == 2:
66 if isinstance(msg, unicode):
69 return str(msg).decode('utf-8')
71 raise LoggerError('Unknown major version of Python')
75 if isinstance(obj, (list, tuple)):
76 for i in _parseList(obj):
78 elif isinstance(obj, dict):
79 for i in _parseDict(obj):
82 buf = _strWrap(obj).splitlines()
90 while (c + 401) < lenI:
99 yield '- %s' % next(i)
102 except StopIteration: pass
105 for key in sorted(dct):
107 for l in _splitLines(dct[key]):
110 def _parseArgs(a, kwa):
113 for i in _parseList(a):
117 yield '| --- NAMED ARGS:'
118 for i in _parseDict(kwa):
125 def __init__(self, logproc, opName):
126 self.logproc = logproc
131 return '%s :: %.4f' % (self.opName, (time() - self.dt))
133 def __call__(self, msg, *a, **kwa):
134 self.logproc('%s | %s' % (self, msg))
135 for i in _parseArgs(a, kwa):
136 self.logproc('%s | %s' % (self, i))
142 class OperationContext(object):
143 def __init__(self, log, opName):
148 def __call__(self, msg, *a, **kwa):
149 self.msgBuf.append((msg, [ i for i in map(_strWrap, a)]))
154 def __exit__(self, exc_type, exc_val, exc_tb):
155 if exc_type is not None:
156 self.log.err("Operation '%s' fail" % self.opName)
157 self.log.excpt_handler(exc_type, exc_val, exc_tb)
160 self.log.err('--- MESSAGES ---')
161 for msg, a, kwa in self.msgBuf:
163 self.log.err('--- END MESSAGES ---')
166 class AbstractLogger(object):
167 def err(self, msg, *a, **kwa):
168 raise LoggerError('NotImplemented')
170 def __call__(self, msg, *a, **kwa):
171 raise LoggerError('NotImplemented')
173 def excpt_handler(self, eType, eObj, eTb):
174 eTb = extract_tb(eTb)
177 eType = eType.split("'")[1]
182 eArgs = eObj.args[1:]
193 self.err('--- EXCEPTION ---')
196 for l in _splitLines(eObj):
199 for l in _parseArgs(eArgs, eKwa):
202 self.err('--- TRACEBACK ---')
203 for _tbFile, _tbLine, _tbFunc, _tbText in eTb:
204 self.err('File: %s, line %s in %s' % (_tbFile, _tbLine, _tbFunc))
205 self.err(' %s' % _tbText)
206 self.err('--- END EXCEPTION ---')
208 def excpt(self, msg, *a, **kwa):
209 eType, eObj, eTb = exc_info()
210 self.err(msg, *a, **kwa)
211 self.excpt_handler(eType, eObj, eTb)
213 def cntxt(self, opName):
215 Если операцию нужно залогировать но при этом совершенно не хочется покрывать код
216 толстым слоем try ... except можно завернуть операцию в контекст, и даже сохранить
217 возвращаемом логером объекте отладочную информацию. При падении и только при нём
218 это обязательно попадёт в лог.
220 ОСТОРОЖНО ПАМЯТЬ!!!!!
221 Объект копирует себе все переданные данные и опреобразует их сразу в строки
222 Если объекту передать одни и те же параметры они всё равно будут храниться
223 по копии на каждый вызов в виде строк, что может сьесть много памяти и вызвать
224 болезненное её особождение.
226 :param opName: членораздельное имя операции
228 return OperationContext(self, opName)
230 def getTiming(self, opName):
231 return TimingLog(self, opName)
233 def dumpDict(self, msg, dct):
234 self('--- ' + _strWrap(msg))
235 for i in _parseDict(dct):
240 def logPrep(*a, **kwa):
243 # --- END ABSTRACT PART --- #
245 class Logger(AbstractLogger):
247 def __init__(self, modName = 'main'):
250 def _write(self, flags, prefix, msg):
251 syslog.syslog(flags, u"%s %s: %s" % (prefix, self.name, msg))
253 def __call__(self, msg, *a, **kwa):
254 _flags = self.facility | syslog.LOG_INFO
255 _prefix = LOG_INFO + ' ' + self.name + ': '
256 syslog.syslog(_flags, _prefix + _strWrap(msg))
257 for i in _parseArgs(a, kwa):
258 syslog.syslog(_flags, _prefix + i)
260 def warn(self, msg, *a, **kwa):
261 _flags = self.facility | syslog.LOG_WARNING
262 _prefix = LOG_WARN + ' ' + self.name + ': '
263 syslog.syslog(_flags, _prefix + _strWrap(msg))
264 for i in _parseArgs(a, kwa):
265 syslog.syslog(_flags, _prefix + i)
267 def err(self, msg, *a, **kwa):
268 _flags = self.facility | syslog.LOG_ERR
269 _prefix = LOG_ERR + ' ' + self.name + ': '
270 syslog.syslog(_flags, _prefix + _strWrap(msg))
271 for i in _parseArgs(a, kwa):
272 syslog.syslog(_flags, _prefix + i)