colorer.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. #!/usr/bin/env python
  2. # encoding: utf-8
  3. import logging
  4. # Source : # http://stackoverflow.com/questions/384076/how-can-i-color-python-logging-output
  5. # now we patch Python code to add color support to logging.StreamHandler
  6. def add_coloring_to_emit_windows(fn):
  7. # add methods we need to the class
  8. def _out_handle(self):
  9. import ctypes
  10. return ctypes.windll.kernel32.GetStdHandle(self.STD_OUTPUT_HANDLE)
  11. out_handle = property(_out_handle)
  12. def _set_color(self, code):
  13. import ctypes
  14. # Constants from the Windows API
  15. self.STD_OUTPUT_HANDLE = -11
  16. hdl = ctypes.windll.kernel32.GetStdHandle(self.STD_OUTPUT_HANDLE)
  17. ctypes.windll.kernel32.SetConsoleTextAttribute(hdl, code)
  18. setattr(logging.StreamHandler, '_set_color', _set_color)
  19. def new(*args):
  20. FOREGROUND_BLUE = 0x0001 # text color contains blue.
  21. FOREGROUND_GREEN = 0x0002 # text color contains green.
  22. FOREGROUND_RED = 0x0004 # text color contains red.
  23. FOREGROUND_INTENSITY = 0x0008 # text color is intensified.
  24. FOREGROUND_WHITE = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED
  25. # winbase.h
  26. STD_INPUT_HANDLE = -10
  27. STD_OUTPUT_HANDLE = -11
  28. STD_ERROR_HANDLE = -12
  29. # wincon.h
  30. FOREGROUND_BLACK = 0x0000
  31. FOREGROUND_BLUE = 0x0001
  32. FOREGROUND_GREEN = 0x0002
  33. FOREGROUND_CYAN = 0x0003
  34. FOREGROUND_RED = 0x0004
  35. FOREGROUND_MAGENTA = 0x0005
  36. FOREGROUND_YELLOW = 0x0006
  37. FOREGROUND_GREY = 0x0007
  38. FOREGROUND_INTENSITY = 0x0008 # foreground color is intensified.
  39. BACKGROUND_BLACK = 0x0000
  40. BACKGROUND_BLUE = 0x0010
  41. BACKGROUND_GREEN = 0x0020
  42. BACKGROUND_CYAN = 0x0030
  43. BACKGROUND_RED = 0x0040
  44. BACKGROUND_MAGENTA = 0x0050
  45. BACKGROUND_YELLOW = 0x0060
  46. BACKGROUND_GREY = 0x0070
  47. BACKGROUND_INTENSITY = 0x0080 # background color is intensified.
  48. levelno = args[1].levelno
  49. if (levelno >= 50):
  50. color = BACKGROUND_YELLOW | FOREGROUND_RED | FOREGROUND_INTENSITY | BACKGROUND_INTENSITY
  51. elif (levelno >= 40):
  52. color = FOREGROUND_RED | FOREGROUND_INTENSITY
  53. elif (levelno >= 30):
  54. color = FOREGROUND_YELLOW | FOREGROUND_INTENSITY
  55. elif (levelno >= 20):
  56. color = FOREGROUND_GREEN
  57. elif (levelno >= 10):
  58. color = FOREGROUND_MAGENTA
  59. else:
  60. color = FOREGROUND_WHITE
  61. args[0]._set_color(color)
  62. ret = fn(*args)
  63. args[0]._set_color(FOREGROUND_WHITE)
  64. # print "after"
  65. return ret
  66. return new
  67. def add_coloring_to_emit_ansi(fn):
  68. # add methods we need to the class
  69. def new(*args):
  70. levelno = args[1].levelno
  71. if (levelno >= 50):
  72. color = '\x1b[31m' # red
  73. elif (levelno >= 40):
  74. color = '\x1b[31m' # red
  75. elif (levelno >= 30):
  76. color = '\x1b[33m' # yellow
  77. elif (levelno >= 20):
  78. color = '\x1b[32m' # green
  79. elif (levelno >= 10):
  80. color = '\x1b[35m' # pink
  81. else:
  82. color = '\x1b[0m' # normal
  83. args[1].msg = color + args[1].msg + '\x1b[0m' # normal
  84. # print "after"
  85. return fn(*args)
  86. return new
  87. import platform
  88. if platform.system() == 'Windows':
  89. # Windows does not support ANSI escapes and we are using API calls to set the console color
  90. logging.StreamHandler.emit = add_coloring_to_emit_windows(logging.StreamHandler.emit)
  91. else:
  92. # all non-Windows platforms are supporting ANSI escapes so we use them
  93. logging.StreamHandler.emit = add_coloring_to_emit_ansi(logging.StreamHandler.emit)
  94. # log = logging.getLogger()
  95. # log.addFilter(log_filter())
  96. # //hdlr = logging.StreamHandler()
  97. # //hdlr.setFormatter(formatter())