Completed
Push — master ( a9d037...ae9180 )
by Wu
14s
created

enable_pretty_logging()   B

Complexity

Conditions 6

Size

Total Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 18
c 0
b 0
f 0
rs 8
cc 6
1
# -*- coding:utf-8 -*-
2
3
import six
4
import sys
5
import time
6
import logging
7
8
try:
9
    import curses
10
11
    assert curses
12
except ImportError:
13
    curses = None
14
15
logger = logging.getLogger("WeRoBot")
16
17
18
def enable_pretty_logging(logger, level='info'):
19
    """
20
    按照配置开启 log 的格式化优化。
21
22
    :param logger: 配置的 logger 对象
23
    :param level: 要为 logger 设置的等级
24
    """
25
    logger.setLevel(getattr(logging, level.upper()))
26
27
    if not logger.handlers:
28
        # Set up color if we are in a tty and curses is installed
29
        color = False
30
        if curses and sys.stderr.isatty():
31
            try:
32
                curses.setupterm()
33
                if curses.tigetnum("colors") > 0:
34
                    color = True
35
            finally:
36
                pass
37
        channel = logging.StreamHandler()
38
        channel.setFormatter(_LogFormatter(color=color))
39
        logger.addHandler(channel)
40
41
42
class _LogFormatter(logging.Formatter):
43
    def __init__(self, color, *args, **kwargs):
44
        logging.Formatter.__init__(self, *args, **kwargs)
45
        self._color = color
46
        if color:
47
            fg_color = (curses.tigetstr("setaf") or
48
                        curses.tigetstr("setf") or "")
49
            if (3, 0) < sys.version_info < (3, 2, 3):
50
                fg_color = six.text_type(fg_color, "ascii")
51
            self._colors = {
52
                logging.DEBUG: six.text_type(
53
                    curses.tparm(fg_color, 4),
54
                    "ascii"
55
                ),  # Blue
56
                logging.INFO: six.text_type(
57
                    curses.tparm(fg_color, 2),
58
                    "ascii"
59
                ),  # Green
60
                logging.WARNING: six.text_type(
61
                    curses.tparm(fg_color, 3),
62
                    "ascii"
63
                ),  # Yellow
64
                logging.ERROR: six.text_type(
65
                    curses.tparm(fg_color, 1),
66
                    "ascii"
67
                ),  # Red
68
            }
69
            self._normal = six.text_type(curses.tigetstr("sgr0"), "ascii")
70
71
    def format(self, record):
72
        try:
73
            record.message = record.getMessage()
74
        except Exception as e:
75
            record.message = "Bad message (%r): %r" % (e, record.__dict__)
76
        record.asctime = time.strftime(
77
            "%y%m%d %H:%M:%S", self.converter(record.created))
78
        prefix = '[%(levelname)1.1s %(asctime)s %(module)s:%(lineno)d]' % \
79
                 record.__dict__
80
        if self._color:
81
            prefix = (self._colors.get(record.levelno, self._normal) +
82
                      prefix + self._normal)
83
        formatted = prefix + " " + record.message
84
        if record.exc_info:
85
            if not record.exc_text:
86
                record.exc_text = self.formatException(record.exc_info)
87
        if record.exc_text:
88
            formatted = formatted.rstrip() + "\n" + record.exc_text
89
        return formatted.replace("\n", "\n    ")
90