--- a +++ b/aggmap/utils/logtools.py @@ -0,0 +1,158 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on Sat Aug 17 16:54:12 2019 + +@author: wanxiang.shen@u.nus.edu + +@logtools +""" + + +import os, sys, logging, time, traceback, inspect +from colorlog import ColoredFormatter +from colored import fg, bg, attr + +formatter = ColoredFormatter( + "%(asctime)s - %(log_color)s%(levelname).4s%(reset)s - %(message_log_color)s[%(name)s]%(reset)s - %(message_log_color)s%(message)s", + datefmt=None, + reset=True, + log_colors={ + 'DEBUG': 'cyan', + 'INFO': 'green', + 'WARNING': 'yellow', + 'ERROR': 'red', + 'CRITICAL': 'red,bg_white', + }, + secondary_log_colors={ + 'message':{ + 'ERROR': 'red', + 'CRITICAL': 'red,bg_white', + }, + }, + style='%', + ) + + +logger = logging.getLogger('bidd-aggmap') +logger.propagate = False + + +all_loggers = [ logger] + +def set_level(level): + for _logger in all_loggers: + _logger.setLevel(getattr(logging, level.upper())) + +set_level('INFO') + +file_handler = None +def log_to_file(path): + global file_handler + if file_handler is not None: + for _logger in all_loggers: + _logger.removeHandler(file_handler) + + logpath = os.path.join(os.getcwd(), path + '.' + get_datetime() + '.log') + print_info('log to file:', logpath) + file_handler = logging.FileHandler(logpath) + file_handler.setFormatter(formatter) + for _logger in all_loggers: + _logger.addHandler(file_handler) + +def reset_handler(handler): + for _logger in all_loggers: + del _logger.handlers[:] + _logger.addHandler(handler) + if file_handler is not None: + _logger.addHandler(file_handler) + +handler = logging.StreamHandler(sys.stdout) +handler.setFormatter(formatter) +reset_handler(handler) + +DEFAULT_TEXT_LENGTH = 5000 +DEFAULT_TEXT_LENGTH_PREFIX = 4000 +DEFAULT_TEXT_LENGTH_SUFFIX = DEFAULT_TEXT_LENGTH - DEFAULT_TEXT_LENGTH_PREFIX +def set_text_length(prefix, suffix): + global DEFAULT_TEXT_LENGTH, DEFAULT_TEXT_LENGTH_PREFIX, DEFAULT_TEXT_LENGTH_SUFFIX + DEFAULT_TEXT_LENGTH = prefix + suffix + DEFAULT_TEXT_LENGTH_PREFIX = prefix + DEFAULT_TEXT_LENGTH_SUFFIX = suffix + +def clip_text(text): + if len(text) > DEFAULT_TEXT_LENGTH: + 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:]) + return text + +def create_print_method(level): + print_method = getattr(logger, level) + def func(*args, sep=' ', verbose=True): + if verbose: print_method(clip_text(sep.join(map(str, args)))) + return func + +print_error = create_print_method('error') +print_warn = create_print_method('warn') +print_info = create_print_method('info') +print_debug = create_print_method('debug') + +def format_exc(error): + return traceback.format_exception(error.__class__, error, error.__traceback__) + +def print_exc(error, verbose=True): + lines = format_exc(error) + logger.error(lines[-1].rstrip()) + if verbose: + logger.info(''.join(lines[:-1])) + +def print_exc_s(error): + logger.error('%s: %s', type(error).__name__, error) + +def print_traceback(): + logger.info('Traceback (most recent call last):') + for frame in reversed(inspect.getouterframes(inspect.currentframe())[1:]): + logger.info(' File "%s", line %s, in %s', frame.filename, frame.lineno, frame.function) + logger.info(' %s', frame.code_context[0].strip()) + +last_time = time.time() +def print_timedelta(*args, sep=' '): + global last_time + this_time = time.time() + logger.info('[%7.2f] %s', (this_time - last_time) * 1000, sep.join(map(str, args))) + last_time = this_time + +def get_date(): + return time.strftime('%Y%m%d') + +def get_datetime(): + return time.strftime('%Y%m%d%H%M%S') + +from tqdm import tqdm + +class PBarHandler(logging.Handler): + + def __init__(self, pbar): + logging.Handler.__init__(self) + self.pbar = pbar + + def emit(self, record): + self.pbar.write(self.format(record)) + +def pbar(*args, **kwargs): + kwargs['ascii'] = kwargs.get('ascii', True) + kwargs['smoothing'] = kwargs.get('smoothing', 0.7) + + pb = tqdm(*args, **kwargs) + handler = PBarHandler(pb) + handler.setFormatter(formatter) + + pb.handler = handler + reset_handler(handler) + + return pb + +if __name__ == '__main__': + pb = pbar(range(100)) + for i in pb: + time.sleep(0.05) + print_info(str(i))