Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1# colored stream handler for python logging framework (use the ColorStreamHandler class). 

2# based on: 

3# http://stackoverflow.com/questions/384076/how-can-i-color-python-logging-output/1336640#1336640 

4# 

5# Copyright (c) 2014 Markus Pointner 

6# 

7# Permission is hereby granted, free of charge, to any person obtaining a copy 

8# of this software and associated documentation files (the "Software"), to deal 

9# in the Software without restriction, including without limitation the rights 

10# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 

11# copies of the Software, and to permit persons to whom the Software is 

12# furnished to do so, subject to the following conditions: 

13# 

14# The above copyright notice and this permission notice shall be included in 

15# all copies or substantial portions of the Software. 

16# 

17# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 

18# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 

19# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 

20# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 

21# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 

22# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 

23# THE SOFTWARE. 

24 

25import os 

26import sys 

27import logging 

28 

29class _AnsiColorStreamHandler(logging.StreamHandler): 

30 DEFAULT = '\x1b[0m' 

31 RED = '\x1b[31m' 

32 GREEN = '\x1b[32m' 

33 YELLOW = '\x1b[33m' 

34 CYAN = '\x1b[36m' 

35 NONE = '' 

36 

37 CRITICAL = RED 

38 ERROR = RED 

39 WARNING = YELLOW 

40 INFO = NONE 

41 DEBUG = CYAN 

42 

43 @classmethod 

44 def _get_color(cls, level): 

45 if level >= logging.CRITICAL: 

46 return cls.CRITICAL 

47 if level >= logging.ERROR: 

48 return cls.ERROR 

49 if level >= logging.WARNING: 

50 return cls.WARNING 

51 if level >= logging.INFO: 

52 return cls.INFO 

53 if level >= logging.DEBUG: 

54 return cls.DEBUG 

55 return cls.DEFAULT 

56 

57 def format(self, record): 

58 text = super().format(record) 

59 color = self._get_color(record.levelno) 

60 return color + text + self.DEFAULT 

61 

62class _WinColorStreamHandler(logging.StreamHandler): 

63 # wincon.h 

64 FOREGROUND_BLACK = 0x0000 

65 FOREGROUND_BLUE = 0x0001 

66 FOREGROUND_GREEN = 0x0002 

67 FOREGROUND_CYAN = 0x0003 

68 FOREGROUND_RED = 0x0004 

69 FOREGROUND_MAGENTA = 0x0005 

70 FOREGROUND_YELLOW = 0x0006 

71 FOREGROUND_GREY = 0x0007 

72 FOREGROUND_INTENSITY = 0x0008 # foreground color is intensified. 

73 FOREGROUND_WHITE = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED 

74 

75 BACKGROUND_BLACK = 0x0000 

76 BACKGROUND_BLUE = 0x0010 

77 BACKGROUND_GREEN = 0x0020 

78 BACKGROUND_CYAN = 0x0030 

79 BACKGROUND_RED = 0x0040 

80 BACKGROUND_MAGENTA = 0x0050 

81 BACKGROUND_YELLOW = 0x0060 

82 BACKGROUND_GREY = 0x0070 

83 BACKGROUND_INTENSITY = 0x0080 # background color is intensified. 

84 

85 DEFAULT = FOREGROUND_GREEN 

86 CRITICAL = BACKGROUND_YELLOW | FOREGROUND_RED | FOREGROUND_INTENSITY | BACKGROUND_INTENSITY 

87 ERROR = FOREGROUND_RED | FOREGROUND_INTENSITY 

88 WARNING = FOREGROUND_YELLOW | FOREGROUND_INTENSITY 

89 INFO = FOREGROUND_WHITE 

90 DEBUG = FOREGROUND_CYAN 

91 

92 @classmethod 

93 def _get_color(cls, level): 

94 if level >= logging.CRITICAL: 

95 return cls.CRITICAL 

96 if level >= logging.ERROR: 

97 return cls.ERROR 

98 if level >= logging.WARNING: 

99 return cls.WARNING 

100 if level >= logging.INFO: 

101 return cls.INFO 

102 if level >= logging.DEBUG: 

103 return cls.DEBUG 

104 return cls.DEFAULT 

105 

106 def _set_color(self, code): 

107 import ctypes 

108 ctypes.windll.kernel32.SetConsoleTextAttribute(self._outhdl, code) #@UndefinedVariable 

109 

110 def __init__(self, stream=None): 

111 super().__init__(stream) 

112 # get file handle for the stream 

113 import ctypes.util 

114 crtname = ctypes.util.find_msvcrt() 

115 crtlib = ctypes.cdll.LoadLibrary(crtname) 

116 self._outhdl = crtlib._get_osfhandle(stream.fileno()) #pylint: disable=protected-access 

117 

118 def emit(self, record): 

119 color = self._get_color(record.levelno) 

120 self._set_color(color) 

121 super().emit(record) 

122 self._set_color(self.FOREGROUND_WHITE) 

123 

124# select ColorStreamHandler based on platform 

125if sys.platform.startswith("win") and not os.environ.get("MSYSCON"): 

126 ColorStreamHandler = _WinColorStreamHandler 

127else: 

128 ColorStreamHandler = _AnsiColorStreamHandler