loghandler.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. import logging
  2. from logging import handlers
  3. import os
  4. import sys
  5. from PyQt4 import QtGui, QtCore
  6. from .. import config
  7. """
  8. This intends to be a QThread save logging handler with syntax highlighting
  9. """
  10. class LogHandler(logging.Handler):
  11. """
  12. Handler Class to configure Logging
  13. This also enables logging to the output field in the gui
  14. """
  15. def __init__(self, log_area):
  16. logging.Handler.__init__(self)
  17. self.text_area = log_area
  18. self.setFormatter(logging.Formatter('%(asctime)s:%(levelname)s: %(message)s'))
  19. self._normal_weight = self.text_area.fontWeight()
  20. self._bold = 100
  21. def emit(self, record):
  22. """
  23. Emit a log record
  24. """
  25. self.acquire()
  26. self.text_area.append_signal.emit(record)
  27. self.release()
  28. class Highlighter(QtGui.QSyntaxHighlighter):
  29. """
  30. Highlighter for the logging area
  31. """
  32. def __init__(self, parent, theme):
  33. super(Highlighter, self).__init__(parent, )
  34. self.parent = parent
  35. self.highlightingRules = []
  36. timestamp = QtGui.QTextCharFormat()
  37. timestamp.setForeground(QtCore.Qt.blue)
  38. timestamp.setFontWeight(QtGui.QFont.Bold)
  39. self.timestamp_pattern = QtCore.QRegExp(r"^.{23}")
  40. self.timestamp_pattern.setMinimal(True)
  41. self.highlightingRules.append((self.timestamp_pattern, timestamp))
  42. loglevel = QtGui.QTextCharFormat()
  43. loglevel.setForeground(QtCore.Qt.black)
  44. loglevel.setFontWeight(QtGui.QFont.Bold)
  45. self.loglevel_pattern = QtCore.QRegExp(r":[A-Z\_]{3,13}:")
  46. self.loglevel_pattern.setMinimal(True)
  47. self.highlightingRules.append((self.loglevel_pattern, loglevel))
  48. success = QtGui.QTextCharFormat()
  49. success.setForeground(QtGui.QColor(30, 210, 0))
  50. success.setFontWeight(QtGui.QFont.Bold)
  51. pattern = QtCore.QRegExp(r".*(S|s)uccess.*")
  52. self.highlightingRules.append((pattern, success))
  53. error = QtGui.QTextCharFormat()
  54. error.setBackground(QtGui.QColor(255, 50, 50))
  55. self.error_pattern = QtCore.QRegExp("ERROR")
  56. self.error_pattern.setMinimal(True)
  57. self.highlightingRules.append((self.error_pattern, error))
  58. def setKeywords(self, kw):
  59. """
  60. Set the keywords to check for
  61. :param kw: the keywords
  62. """
  63. keyword = QtGui.QTextCharFormat()
  64. keyword.setForeground(QtCore.Qt.darkBlue)
  65. keyword.setFontWeight(QtGui.QFont.Bold)
  66. keywords = kw
  67. for word in keywords:
  68. pattern = QtCore.QRegExp("\\b" + word + "\\b")
  69. self.highlightingRules.append((pattern, keyword))
  70. def highlightBlock(self, text):
  71. """
  72. Highlight a block of text
  73. :param text: the text to check in
  74. """
  75. for pattern, format in self.highlightingRules:
  76. start = 0
  77. if pattern not in [self.timestamp_pattern, self.error_pattern, self.loglevel_pattern]:
  78. start = self.loglevel_pattern.indexIn(text)
  79. start += self.loglevel_pattern.matchedLength()
  80. index = pattern.indexIn(text, offset=start)
  81. while index >= 0:
  82. length = pattern.matchedLength()
  83. pref_format = self.format(index)
  84. pref_format.merge(format)
  85. self.setFormat(index, length, pref_format)
  86. index = pattern.indexIn(text, index + length)
  87. self.setCurrentBlockState(0)
  88. class LogArea(QtGui.QTextEdit):
  89. """
  90. The log area for the KCG Gui
  91. """
  92. append_signal = QtCore.pyqtSignal(logging.LogRecord)
  93. def __init__(self):
  94. super(LogArea, self).__init__()
  95. self.highlighter = Highlighter(self, 'Classic')
  96. self.logHandler = None
  97. self.streamLogger = logging.StreamHandler(stream=sys.stdout)
  98. self.streamLogger.setLevel(config.log_level)
  99. self.streamLogger.setFormatter(logging.Formatter('%(asctime)s:%(levelname)s: %(message)s'))
  100. logging.getLogger().addHandler(self.streamLogger)
  101. self.fileLogHandler = handlers.RotatingFileHandler(config.config_path("kcg.log"), maxBytes=10**7, backupCount=5)
  102. self.fileLogHandler.setFormatter(logging.Formatter('%(asctime)s:%(levelname)s: %(message)s'))
  103. self.fileLogHandler.setLevel(config.log_level)
  104. logging.getLogger().addHandler(self.fileLogHandler)
  105. self.append_signal.connect(self.append)
  106. def init_logging(self):
  107. """
  108. Initialize logging
  109. """
  110. self.logHandler = LogHandler(self)
  111. self.logHandler.setLevel(config.log_level)
  112. logging.getLogger().addHandler(self.logHandler)
  113. def append(self, record):
  114. """
  115. Append to the logarea
  116. :param record: the record to append
  117. """
  118. super(LogArea, self).append(self.logHandler.format(record))
  119. self.ensureCursorVisible()
  120. def setKeywords(self, kw):
  121. """
  122. Set the keywords for the highlighter
  123. :param kw: the keywords to set
  124. """
  125. self.highlighter.setKeywords(kw)