Development of an internal social media platform with personalised dashboards for students
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

colorlog.py 4.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. """Nicer log formatting with colours.
  2. Code copied from Tornado, Apache licensed.
  3. """
  4. # Copyright 2012 Facebook
  5. #
  6. # Licensed under the Apache License, Version 2.0 (the "License"); you may
  7. # not use this file except in compliance with the License. You may obtain
  8. # a copy of the License at
  9. #
  10. # http://www.apache.org/licenses/LICENSE-2.0
  11. #
  12. # Unless required by applicable law or agreed to in writing, software
  13. # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  14. # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  15. # License for the specific language governing permissions and limitations
  16. # under the License.
  17. import logging
  18. import sys
  19. try:
  20. import curses
  21. except ImportError:
  22. curses = None
  23. def _stderr_supports_color():
  24. color = False
  25. if curses and hasattr(sys.stderr, 'isatty') and sys.stderr.isatty():
  26. try:
  27. curses.setupterm()
  28. if curses.tigetnum("colors") > 0:
  29. color = True
  30. except Exception:
  31. pass
  32. return color
  33. class LogFormatter(logging.Formatter):
  34. """Log formatter with colour support
  35. """
  36. DEFAULT_COLORS = {
  37. logging.INFO: 2, # Green
  38. logging.WARNING: 3, # Yellow
  39. logging.ERROR: 1, # Red
  40. logging.CRITICAL: 1,
  41. }
  42. def __init__(self, color=True, datefmt=None):
  43. r"""
  44. :arg bool color: Enables color support.
  45. :arg string fmt: Log message format.
  46. It will be applied to the attributes dict of log records. The
  47. text between ``%(color)s`` and ``%(end_color)s`` will be colored
  48. depending on the level if color support is on.
  49. :arg dict colors: color mappings from logging level to terminal color
  50. code
  51. :arg string datefmt: Datetime format.
  52. Used for formatting ``(asctime)`` placeholder in ``prefix_fmt``.
  53. .. versionchanged:: 3.2
  54. Added ``fmt`` and ``datefmt`` arguments.
  55. """
  56. logging.Formatter.__init__(self, datefmt=datefmt)
  57. self._colors = {}
  58. if color and _stderr_supports_color():
  59. # The curses module has some str/bytes confusion in
  60. # python3. Until version 3.2.3, most methods return
  61. # bytes, but only accept strings. In addition, we want to
  62. # output these strings with the logging module, which
  63. # works with unicode strings. The explicit calls to
  64. # unicode() below are harmless in python2 but will do the
  65. # right conversion in python 3.
  66. fg_color = (curses.tigetstr("setaf") or
  67. curses.tigetstr("setf") or "")
  68. if (3, 0) < sys.version_info < (3, 2, 3):
  69. fg_color = str(fg_color, "ascii")
  70. for levelno, code in self.DEFAULT_COLORS.items():
  71. self._colors[levelno] = str(curses.tparm(fg_color, code), "ascii")
  72. self._normal = str(curses.tigetstr("sgr0"), "ascii")
  73. scr = curses.initscr()
  74. self.termwidth = scr.getmaxyx()[1]
  75. curses.endwin()
  76. else:
  77. self._normal = ''
  78. # Default width is usually 80, but too wide is worse than too narrow
  79. self.termwidth = 70
  80. def formatMessage(self, record):
  81. l = len(record.message)
  82. right_text = '{initial}-{name}'.format(initial=record.levelname[0],
  83. name=record.name)
  84. if l + len(right_text) < self.termwidth:
  85. space = ' ' * (self.termwidth - (l + len(right_text)))
  86. else:
  87. space = ' '
  88. if record.levelno in self._colors:
  89. start_color = self._colors[record.levelno]
  90. end_color = self._normal
  91. else:
  92. start_color = end_color = ''
  93. return record.message + space + start_color + right_text + end_color
  94. def enable_colourful_output(level=logging.INFO):
  95. handler = logging.StreamHandler()
  96. handler.setFormatter(LogFormatter())
  97. logging.root.addHandler(handler)
  98. logging.root.setLevel(level)