-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlog.py
82 lines (63 loc) · 2.06 KB
/
log.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import typing as T
import logging
import sys
import io
from pathlib import Path
from functools import wraps
def cfg(name=None, level=logging.DEBUG):
logging.basicConfig(**_getcfg(level=level))
return logging.getLogger(name)
def _getcfg(level=logging.DEBUG):
return dict(
format='[%(levelname)s|%(module)s:%(lineno)s|%(asctime)s] %(message)s',
datefmt='%y-%m-%d %X',
level=level)
def get_strlog(name, stream=None, fmt=None, datefmt=None):
'''Log to stream. Creates StringIO if none provided.'''
stream = stream or io.StringIO()
logger = logging.getLogger(name)
logger.propagate = False
logger.addHandler(_streamhandler(stream, logging.Formatter(fmt, datefmt)))
return logger, stream
class LogPrinter:
def __init__(self, log=None):
self.log = log or logging.getLogger(__name__)
self.log.setLevel(logging.DEBUG)
def write(self, text):
if text.strip():
self.log.debug(text)
def printlog(func):
'''Treat print as log within some function. Assumes single-thread execution.
'''
@wraps(func)
def pwrapper(*arg, **kwargs):
stdold = sys.stdout
try:
sys.stdout = LogPrinter()
return func(*arg, **kwargs)
finally: sys.stdout = stdold
return pwrapper
def to(stream_or_fname: T.Union[io.IOBase, str, Path]):
'''Temp redirect log. Assumes single-thread execution.
If stream_or_fname is path, will open/close file as appropriate.
'''
logger = logging.getLogger()
is_fname = isinstance(stream_or_fname, (str, Path))
def _inner(func):
@wraps(func)
def _innerinner(*a, **kw):
hs_old = logger.handlers
stream = open(stream_or_fname, 'a') if is_fname else stream_or_fname
try:
formatter = hs_old[-1].formatter if hs_old else logging.Formatter()
logger.handlers = [_streamhandler(stream, formatter)]
return func(*a, **kw)
finally:
logger.handlers = hs_old
if is_fname: stream.close()
return _innerinner
return _inner
def _streamhandler(stream, formatter):
sh = logging.StreamHandler(stream)
sh.formatter = formatter
return sh