blob: 9ebc42532ec1706f0efabdd759c8e711fe9fe383 [file] [log] [blame]
koder aka kdanilov962ee5f2016-12-19 02:40:08 +02001import yaml
koder aka kdanilov3b4da8b2016-10-17 00:17:53 +03002import logging
koder aka kdanilov962ee5f2016-12-19 02:40:08 +02003import logging.config
koder aka kdanilov73084622016-11-16 21:51:08 +02004from typing import Callable, IO, Optional
koder aka kdanilov3b4da8b2016-10-17 00:17:53 +03005
6
koder aka kdanilov22d134e2016-11-08 11:33:19 +02007def color_me(color: int) -> Callable[[str], str]:
koder aka kdanilov3b4da8b2016-10-17 00:17:53 +03008 RESET_SEQ = "\033[0m"
9 COLOR_SEQ = "\033[1;%dm"
10
11 color_seq = COLOR_SEQ % (30 + color)
12
13 def closure(msg):
14 return color_seq + msg + RESET_SEQ
15 return closure
16
17
18class ColoredFormatter(logging.Formatter):
19 BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8)
20
21 colors = {
22 'WARNING': color_me(YELLOW),
23 'DEBUG': color_me(BLUE),
24 'CRITICAL': color_me(YELLOW),
25 'ERROR': color_me(RED)
26 }
27
koder aka kdanilov22d134e2016-11-08 11:33:19 +020028 def __init__(self, msg: str, use_color: bool=True, datefmt: str=None) -> None:
koder aka kdanilov3b4da8b2016-10-17 00:17:53 +030029 logging.Formatter.__init__(self, msg, datefmt=datefmt)
30 self.use_color = use_color
31
koder aka kdanilov22d134e2016-11-08 11:33:19 +020032 def format(self, record: logging.LogRecord) -> str:
koder aka kdanilov3b4da8b2016-10-17 00:17:53 +030033 orig = record.__dict__
34 record.__dict__ = record.__dict__.copy()
35 levelname = record.levelname
36
37 prn_name = levelname + ' ' * (8 - len(levelname))
38 if levelname in self.colors:
39 record.levelname = self.colors[levelname](prn_name)
40 else:
41 record.levelname = prn_name
42
43 # super doesn't work here in 2.6 O_o
44 res = logging.Formatter.format(self, record)
45
46 # res = super(ColoredFormatter, self).format(record)
47
48 # restore record, as it will be used by other formatters
49 record.__dict__ = orig
50 return res
51
52
koder aka kdanilov962ee5f2016-12-19 02:40:08 +020053def setup_loggers(def_level: int = logging.DEBUG,
54 log_fname: str = None,
55 log_fd: IO = None,
56 config_file: str = None) -> None:
koder aka kdanilov3b4da8b2016-10-17 00:17:53 +030057
koder aka kdanilov962ee5f2016-12-19 02:40:08 +020058 # TODO: need to better combine file with custom settings
59 if config_file is not None:
60 data = yaml.load(open(config_file).read())
61 logging.config.dictConfig(data)
62 else:
63 log_format = '%(asctime)s - %(levelname)8s - %(name)-10s - %(message)s'
64 colored_formatter = ColoredFormatter(log_format, datefmt="%H:%M:%S")
koder aka kdanilov3b4da8b2016-10-17 00:17:53 +030065
koder aka kdanilov962ee5f2016-12-19 02:40:08 +020066 sh = logging.StreamHandler()
67 sh.setLevel(def_level)
68 sh.setFormatter(colored_formatter)
koder aka kdanilov73084622016-11-16 21:51:08 +020069
koder aka kdanilov962ee5f2016-12-19 02:40:08 +020070 logger = logging.getLogger('wally')
71 logger.setLevel(logging.DEBUG)
koder aka kdanilov3b4da8b2016-10-17 00:17:53 +030072
koder aka kdanilov962ee5f2016-12-19 02:40:08 +020073 root_logger = logging.getLogger()
74 root_logger.handlers = []
75 root_logger.addHandler(sh)
76 root_logger.setLevel(logging.DEBUG)
koder aka kdanilov3b4da8b2016-10-17 00:17:53 +030077
koder aka kdanilov962ee5f2016-12-19 02:40:08 +020078 if log_fname or log_fd:
79 if log_fname:
80 handler = logging.FileHandler(log_fname) # type: Optional[logging.Handler]
81 else:
82 handler = logging.StreamHandler(log_fd)
koder aka kdanilov22d134e2016-11-08 11:33:19 +020083
koder aka kdanilov962ee5f2016-12-19 02:40:08 +020084 formatter = logging.Formatter(log_format, datefmt="%H:%M:%S")
85 handler.setFormatter(formatter)
86 handler.setLevel(logging.DEBUG)
koder aka kdanilov73084622016-11-16 21:51:08 +020087
koder aka kdanilov962ee5f2016-12-19 02:40:08 +020088 root_logger.addHandler(handler)
koder aka kdanilov3b4da8b2016-10-17 00:17:53 +030089
koder aka kdanilov962ee5f2016-12-19 02:40:08 +020090 logging.getLogger('paramiko').setLevel(logging.WARNING)