mirror of
https://github.com/lilydjwg/nvchecker.git
synced 2025-03-10 06:14:02 +00:00
127 lines
3.2 KiB
Python
127 lines
3.2 KiB
Python
# vim: se sw=2:
|
|
# MIT licensed
|
|
# Copyright (c) 2018 lilydjwg <lilydjwg@gmail.com>, et al.
|
|
|
|
import logging
|
|
import os
|
|
import io
|
|
import traceback
|
|
import sys
|
|
|
|
import structlog
|
|
|
|
from .httpclient import TemporaryError
|
|
|
|
def _console_msg(event):
|
|
evt = event['event']
|
|
if evt == 'up-to-date':
|
|
msg = 'up-to-date, version %s' % event['version']
|
|
del event['version']
|
|
elif evt == 'updated':
|
|
if event.get('old_version'):
|
|
msg = 'updated from %(old_version)s to %(version)s' % event
|
|
else:
|
|
msg = 'updated to %(version)s' % event
|
|
del event['version'], event['old_version']
|
|
else:
|
|
msg = evt
|
|
|
|
if 'name' in event:
|
|
msg = f"{event['name']}: {msg}"
|
|
del event['name']
|
|
|
|
event['msg'] = msg
|
|
|
|
return event
|
|
|
|
def exc_info(logger, level, event):
|
|
if level == 'exception':
|
|
event['exc_info'] = True
|
|
return event
|
|
|
|
def filter_exc(logger, level, event):
|
|
exc_info = event.get('exc_info')
|
|
if not exc_info:
|
|
return event
|
|
|
|
if exc_info is True:
|
|
exc = sys.exc_info()[1]
|
|
else:
|
|
exc = exc_info
|
|
|
|
if isinstance(exc, TemporaryError):
|
|
if exc.code == 599: # network issues
|
|
del event['exc_info']
|
|
event['error'] = exc
|
|
return event
|
|
|
|
def stdlib_renderer(logger, level, event):
|
|
# return event unchanged for further processing
|
|
std_event = _console_msg(event.copy())
|
|
try:
|
|
logger = logging.getLogger(std_event.pop('logger_name'))
|
|
except KeyError:
|
|
logger = logging.getLogger()
|
|
msg = std_event.pop('msg', std_event.pop('event'))
|
|
exc_info = std_event.pop('exc_info', None)
|
|
if 'error' in std_event:
|
|
std_event['error'] = repr(std_event['error'])
|
|
getattr(logger, level)(
|
|
msg, exc_info = exc_info, extra=std_event,
|
|
)
|
|
return event
|
|
|
|
_renderer = structlog.processors.JSONRenderer(ensure_ascii=False)
|
|
def json_renderer(logger, level, event):
|
|
event['level'] = level
|
|
return _renderer(logger, level, event)
|
|
|
|
def null_renderer(logger, level, event):
|
|
return ''
|
|
|
|
class _Logger(logging.Logger):
|
|
_my_srcfile = os.path.normcase(
|
|
stdlib_renderer.__code__.co_filename)
|
|
|
|
_structlog_dir = os.path.dirname(structlog.__file__)
|
|
|
|
def findCaller(self, stack_info=False, stacklevel=1):
|
|
"""
|
|
Find the stack frame of the caller so that we can note the source
|
|
file name, line number and function name.
|
|
"""
|
|
f = logging.currentframe()
|
|
#On some versions of IronPython, currentframe() returns None if
|
|
#IronPython isn't run with -X:Frames.
|
|
if f is not None:
|
|
f = f.f_back
|
|
orig_f = f
|
|
while f and stacklevel > 1:
|
|
f = f.f_back
|
|
stacklevel -= 1
|
|
if not f:
|
|
f = orig_f
|
|
rv = "(unknown file)", 0, "(unknown function)", None
|
|
while hasattr(f, "f_code"):
|
|
co = f.f_code
|
|
filename = os.path.normcase(co.co_filename)
|
|
if filename in [logging._srcfile, self._my_srcfile] \
|
|
or filename.startswith(self._structlog_dir):
|
|
f = f.f_back
|
|
continue
|
|
sinfo = None
|
|
if stack_info:
|
|
sio = io.StringIO()
|
|
sio.write('Stack (most recent call last):\n')
|
|
traceback.print_stack(f, file=sio)
|
|
sinfo = sio.getvalue()
|
|
if sinfo[-1] == '\n':
|
|
sinfo = sinfo[:-1]
|
|
sio.close()
|
|
rv = (co.co_filename, f.f_lineno, co.co_name, sinfo)
|
|
break
|
|
return rv
|
|
|
|
def fix_logging():
|
|
logging.setLoggerClass(_Logger)
|
|
|