1
0

logging: basics

This commit is contained in:
SomberNight
2019-04-26 18:52:26 +02:00
parent 4d64e132d7
commit 3385a94753
68 changed files with 681 additions and 563 deletions

View File

@@ -47,6 +47,7 @@ from aiorpcx import TaskGroup
import certifi
from .i18n import _
from .logging import get_logger, Logger
if TYPE_CHECKING:
from .network import Network
@@ -54,6 +55,9 @@ if TYPE_CHECKING:
from .simple_config import SimpleConfig
_logger = get_logger(__name__)
def inv_dict(d):
return {v: k for k, v in d.items()}
@@ -237,11 +241,15 @@ class PrintError(object):
def print_msg(self, *msg):
print_msg(self.log_name(), *msg)
class ThreadJob(PrintError):
class ThreadJob(Logger):
"""A job that is run periodically from a thread's main loop. run() is
called from that thread's context.
"""
def __init__(self):
Logger.__init__(self)
def run(self):
"""Called periodically from the thread"""
pass
@@ -249,13 +257,14 @@ class ThreadJob(PrintError):
class DebugMem(ThreadJob):
'''A handy class for debugging GC memory leaks'''
def __init__(self, classes, interval=30):
ThreadJob.__init__(self)
self.next_time = 0
self.classes = classes
self.interval = interval
def mem_stats(self):
import gc
self.print_error("Start memscan")
self.logger.info("Start memscan")
gc.collect()
objmap = defaultdict(list)
for obj in gc.get_objects():
@@ -263,20 +272,21 @@ class DebugMem(ThreadJob):
if isinstance(obj, class_):
objmap[class_].append(obj)
for class_, objs in objmap.items():
self.print_error("%s: %d" % (class_.__name__, len(objs)))
self.print_error("Finish memscan")
self.logger.info(f"{class_.__name__}: {len(objs)}")
self.logger.info("Finish memscan")
def run(self):
if time.time() > self.next_time:
self.mem_stats()
self.next_time = time.time() + self.interval
class DaemonThread(threading.Thread, PrintError):
class DaemonThread(threading.Thread, Logger):
""" daemon thread that terminates cleanly """
verbosity_filter = 'd'
def __init__(self):
threading.Thread.__init__(self)
Logger.__init__(self)
self.parent_thread = threading.currentThread()
self.running = False
self.running_lock = threading.Lock()
@@ -296,7 +306,7 @@ class DaemonThread(threading.Thread, PrintError):
try:
job.run()
except Exception as e:
traceback.print_exc(file=sys.stderr)
self.logger.exception('')
def remove_jobs(self, jobs):
with self.job_lock:
@@ -320,8 +330,8 @@ class DaemonThread(threading.Thread, PrintError):
if 'ANDROID_DATA' in os.environ:
import jnius
jnius.detach()
self.print_error("jnius detach")
self.print_error("stopped")
self.logger.info("jnius detach")
self.logger.info("stopped")
verbosity = ''
@@ -375,7 +385,7 @@ def profiler(func):
t0 = time.time()
o = func(*args, **kw_args)
t = time.time() - t0
print_error("[profiler]", name, "%.4f"%t)
_logger.debug(f"[profiler] {name} {t:,.4f}")
return o
return lambda *args, **kw_args: do_profile(args, kw_args)
@@ -393,7 +403,7 @@ def ensure_sparse_file(filename):
try:
os.system('fsutil sparse setflag "{}" 1'.format(filename))
except Exception as e:
print_error('error marking file {} as sparse: {}'.format(filename, e))
_logger.info(f'error marking file {filename} as sparse: {e}')
def get_headers_dir(config):
@@ -893,10 +903,10 @@ def import_meta(path, validater, load_meta):
load_meta(d)
#backwards compatibility for JSONDecodeError
except ValueError:
traceback.print_exc(file=sys.stderr)
_logger.exception('')
raise FileImportFailed(_("Invalid JSON code."))
except BaseException as e:
traceback.print_exc(file=sys.stdout)
_logger.exception('')
raise FileImportFailed(e)
@@ -905,7 +915,7 @@ def export_meta(meta, fileName):
with open(fileName, 'w+', encoding='utf-8') as f:
json.dump(meta, f, indent=4, sort_keys=True)
except (IOError, os.error) as e:
traceback.print_exc(file=sys.stderr)
_logger.exception('')
raise FileExportFailed(e)
@@ -928,12 +938,11 @@ def log_exceptions(func):
except asyncio.CancelledError as e:
raise
except BaseException as e:
print_ = self.print_error if hasattr(self, 'print_error') else print_error
print_("Exception in", func.__name__, ":", repr(e))
mylogger = self.logger if hasattr(self, 'logger') else _logger
try:
traceback.print_exc(file=sys.stderr)
mylogger.exception(f"Exception in {func.__name__}: {repr(e)}")
except BaseException as e2:
print_error("traceback.print_exc raised: {}...".format(e2))
print(f"logging exception raised: {repr(e2)}... orig exc: {repr(e)} in {func.__name__}")
raise
return wrapper
@@ -991,12 +1000,13 @@ class SilentTaskGroup(TaskGroup):
return super().spawn(*args, **kwargs)
class NetworkJobOnDefaultServer(PrintError):
class NetworkJobOnDefaultServer(Logger):
"""An abstract base class for a job that runs on the main network
interface. Every time the main interface changes, the job is
restarted, and some of its internals are reset.
"""
def __init__(self, network: 'Network'):
Logger.__init__(self)
asyncio.set_event_loop(network.asyncio_loop)
self.network = network
self.interface = None # type: Interface