Diff of /aggmap/utils/logtools.py [000000] .. [9e8054]

Switch to unified view

a b/aggmap/utils/logtools.py
1
#!/usr/bin/env python3
2
# -*- coding: utf-8 -*-
3
"""
4
Created on Sat Aug 17 16:54:12 2019
5
6
@author: wanxiang.shen@u.nus.edu
7
8
@logtools
9
"""
10
11
12
import os, sys, logging, time, traceback, inspect
13
from colorlog import ColoredFormatter
14
from colored import fg, bg, attr
15
16
formatter = ColoredFormatter(
17
    "%(asctime)s - %(log_color)s%(levelname).4s%(reset)s - %(message_log_color)s[%(name)s]%(reset)s - %(message_log_color)s%(message)s",
18
    datefmt=None,
19
    reset=True,
20
    log_colors={
21
        'DEBUG': 'cyan',
22
        'INFO': 'green',
23
        'WARNING': 'yellow',
24
        'ERROR': 'red',
25
        'CRITICAL': 'red,bg_white',
26
    },
27
    secondary_log_colors={
28
        'message':{
29
            'ERROR': 'red',
30
            'CRITICAL': 'red,bg_white',
31
        },
32
    },
33
    style='%',
34
    )
35
36
37
logger = logging.getLogger('bidd-aggmap')
38
logger.propagate = False
39
40
41
all_loggers = [ logger]
42
43
def set_level(level):
44
    for _logger in all_loggers:
45
        _logger.setLevel(getattr(logging, level.upper()))
46
47
set_level('INFO')
48
49
file_handler = None
50
def log_to_file(path):
51
    global file_handler
52
    if file_handler is not None:
53
        for _logger in all_loggers:
54
            _logger.removeHandler(file_handler)
55
            
56
    logpath = os.path.join(os.getcwd(), path + '.' + get_datetime() + '.log')
57
    print_info('log to file:', logpath)
58
    file_handler = logging.FileHandler(logpath)
59
    file_handler.setFormatter(formatter)
60
    for _logger in all_loggers:
61
        _logger.addHandler(file_handler)
62
63
def reset_handler(handler):
64
    for _logger in all_loggers:
65
        del _logger.handlers[:]
66
        _logger.addHandler(handler)
67
        if file_handler is not None:
68
            _logger.addHandler(file_handler)
69
70
handler = logging.StreamHandler(sys.stdout)
71
handler.setFormatter(formatter)
72
reset_handler(handler)
73
74
DEFAULT_TEXT_LENGTH = 5000
75
DEFAULT_TEXT_LENGTH_PREFIX = 4000
76
DEFAULT_TEXT_LENGTH_SUFFIX = DEFAULT_TEXT_LENGTH - DEFAULT_TEXT_LENGTH_PREFIX
77
def set_text_length(prefix, suffix):
78
    global DEFAULT_TEXT_LENGTH, DEFAULT_TEXT_LENGTH_PREFIX, DEFAULT_TEXT_LENGTH_SUFFIX
79
    DEFAULT_TEXT_LENGTH = prefix + suffix
80
    DEFAULT_TEXT_LENGTH_PREFIX = prefix
81
    DEFAULT_TEXT_LENGTH_SUFFIX = suffix
82
83
def clip_text(text):
84
    if len(text) > DEFAULT_TEXT_LENGTH:
85
        text = '%s %s%s... [%d chars truncated] ...%s %s' % (text[:DEFAULT_TEXT_LENGTH_PREFIX], fg('red'), attr('bold'), len(text) - DEFAULT_TEXT_LENGTH, attr('reset'), text[-DEFAULT_TEXT_LENGTH_SUFFIX:])
86
    return text
87
88
def create_print_method(level):
89
    print_method = getattr(logger, level)
90
    def func(*args, sep=' ', verbose=True):
91
        if verbose: print_method(clip_text(sep.join(map(str, args))))
92
    return func
93
94
print_error = create_print_method('error')
95
print_warn = create_print_method('warn')
96
print_info = create_print_method('info')
97
print_debug = create_print_method('debug')
98
99
def format_exc(error):
100
    return traceback.format_exception(error.__class__, error, error.__traceback__)
101
102
def print_exc(error, verbose=True):
103
    lines = format_exc(error)
104
    logger.error(lines[-1].rstrip())
105
    if verbose:
106
        logger.info(''.join(lines[:-1]))
107
108
def print_exc_s(error):
109
    logger.error('%s: %s', type(error).__name__, error)
110
111
def print_traceback():
112
    logger.info('Traceback (most recent call last):')
113
    for frame in reversed(inspect.getouterframes(inspect.currentframe())[1:]):
114
        logger.info('  File "%s", line %s, in %s', frame.filename, frame.lineno, frame.function)
115
        logger.info('    %s', frame.code_context[0].strip())
116
117
last_time = time.time()
118
def print_timedelta(*args, sep=' '):
119
    global last_time
120
    this_time = time.time()
121
    logger.info('[%7.2f] %s', (this_time - last_time) * 1000, sep.join(map(str, args)))
122
    last_time = this_time
123
124
def get_date():
125
    return time.strftime('%Y%m%d')
126
127
def get_datetime():
128
    return time.strftime('%Y%m%d%H%M%S')
129
130
from tqdm import tqdm
131
132
class PBarHandler(logging.Handler):
133
134
    def __init__(self, pbar):
135
        logging.Handler.__init__(self)
136
        self.pbar = pbar
137
138
    def emit(self, record):
139
        self.pbar.write(self.format(record))
140
141
def pbar(*args, **kwargs):
142
    kwargs['ascii'] = kwargs.get('ascii', True)
143
    kwargs['smoothing'] = kwargs.get('smoothing', 0.7)
144
145
    pb = tqdm(*args, **kwargs)
146
    handler = PBarHandler(pb)
147
    handler.setFormatter(formatter)
148
149
    pb.handler = handler
150
    reset_handler(handler)
151
152
    return pb
153
154
if __name__ == '__main__':
155
    pb = pbar(range(100))
156
    for i in pb:
157
        time.sleep(0.05)
158
        print_info(str(i))