123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- import re
- import logging
- from Plugin import PluginManager
- from Config import config
- from Debug import Debug
- from util import SafeRe
- from util.Flag import flag
- class WsLogStreamer(logging.StreamHandler):
- def __init__(self, stream_id, ui_websocket, filter):
- self.stream_id = stream_id
- self.ui_websocket = ui_websocket
- if filter:
- if not SafeRe.isSafePattern(filter):
- raise Exception("Not a safe prex pattern")
- self.filter_re = re.compile(".*" + filter)
- else:
- self.filter_re = None
- return super(WsLogStreamer, self).__init__()
- def emit(self, record):
- if self.ui_websocket.ws.closed:
- self.stop()
- return
- line = self.format(record)
- if self.filter_re and not self.filter_re.match(line):
- return False
- self.ui_websocket.cmd("logLineAdd", {"stream_id": self.stream_id, "lines": [line]})
- def stop(self):
- logging.getLogger('').removeHandler(self)
- @PluginManager.registerTo("UiWebsocket")
- class UiWebsocketPlugin(object):
- def __init__(self, *args, **kwargs):
- self.log_streamers = {}
- return super(UiWebsocketPlugin, self).__init__(*args, **kwargs)
- @flag.no_multiuser
- @flag.admin
- def actionConsoleLogRead(self, to, filter=None, read_size=32 * 1024, limit=500):
- log_file_path = "%s/debug.log" % config.log_dir
- log_file = open(log_file_path, encoding="utf-8")
- log_file.seek(0, 2)
- end_pos = log_file.tell()
- log_file.seek(max(0, end_pos - read_size))
- if log_file.tell() != 0:
- log_file.readline() # Partial line junk
- pos_start = log_file.tell()
- lines = []
- if filter:
- assert SafeRe.isSafePattern(filter)
- filter_re = re.compile(".*" + filter)
- last_match = False
- for line in log_file:
- if not line.startswith("[") and last_match: # Multi-line log entry
- lines.append(line.replace(" ", " "))
- continue
- if filter and not filter_re.match(line):
- last_match = False
- continue
- last_match = True
- lines.append(line)
- num_found = len(lines)
- lines = lines[-limit:]
- return {"lines": lines, "pos_end": log_file.tell(), "pos_start": pos_start, "num_found": num_found}
- def addLogStreamer(self, stream_id, filter=None):
- logger = WsLogStreamer(stream_id, self, filter)
- logger.setFormatter(logging.Formatter('[%(asctime)s] %(levelname)-8s %(name)s %(message)s'))
- logger.setLevel(logging.getLevelName("DEBUG"))
- logging.getLogger('').addHandler(logger)
- return logger
- @flag.no_multiuser
- @flag.admin
- def actionConsoleLogStream(self, to, filter=None):
- stream_id = to
- self.log_streamers[stream_id] = self.addLogStreamer(stream_id, filter)
- self.response(to, {"stream_id": stream_id})
- @flag.no_multiuser
- @flag.admin
- def actionConsoleLogStreamRemove(self, to, stream_id):
- try:
- self.log_streamers[stream_id].stop()
- del self.log_streamers[stream_id]
- return "ok"
- except Exception as err:
- return {"error": Debug.formatException(err)}
|