Forking what is left of ZeroNet and hopefully adding an AT Proto Frontend/Proxy
at main 101 lines 3.3 kB view raw
1import re 2import logging 3 4from Plugin import PluginManager 5from Config import config 6from Debug import Debug 7from util import SafeRe 8from util.Flag import flag 9 10 11class WsLogStreamer(logging.StreamHandler): 12 def __init__(self, stream_id, ui_websocket, filter): 13 self.stream_id = stream_id 14 self.ui_websocket = ui_websocket 15 16 if filter: 17 if not SafeRe.isSafePattern(filter): 18 raise Exception("Not a safe prex pattern") 19 self.filter_re = re.compile(".*" + filter) 20 else: 21 self.filter_re = None 22 return super(WsLogStreamer, self).__init__() 23 24 def emit(self, record): 25 if self.ui_websocket.ws.closed: 26 self.stop() 27 return 28 line = self.format(record) 29 if self.filter_re and not self.filter_re.match(line): 30 return False 31 32 self.ui_websocket.cmd("logLineAdd", {"stream_id": self.stream_id, "lines": [line]}) 33 34 def stop(self): 35 logging.getLogger('').removeHandler(self) 36 37 38@PluginManager.registerTo("UiWebsocket") 39class UiWebsocketPlugin(object): 40 def __init__(self, *args, **kwargs): 41 self.log_streamers = {} 42 return super(UiWebsocketPlugin, self).__init__(*args, **kwargs) 43 44 @flag.no_multiuser 45 @flag.admin 46 def actionConsoleLogRead(self, to, filter=None, read_size=32 * 1024, limit=500): 47 log_file_path = "%s/debug.log" % config.log_dir 48 log_file = open(log_file_path, encoding="utf-8") 49 log_file.seek(0, 2) 50 end_pos = log_file.tell() 51 log_file.seek(max(0, end_pos - read_size)) 52 if log_file.tell() != 0: 53 log_file.readline() # Partial line junk 54 55 pos_start = log_file.tell() 56 lines = [] 57 if filter: 58 assert SafeRe.isSafePattern(filter) 59 filter_re = re.compile(".*" + filter) 60 61 last_match = False 62 for line in log_file: 63 if not line.startswith("[") and last_match: # Multi-line log entry 64 lines.append(line.replace(" ", " ")) 65 continue 66 67 if filter and not filter_re.match(line): 68 last_match = False 69 continue 70 last_match = True 71 lines.append(line) 72 73 num_found = len(lines) 74 lines = lines[-limit:] 75 76 return {"lines": lines, "pos_end": log_file.tell(), "pos_start": pos_start, "num_found": num_found} 77 78 def addLogStreamer(self, stream_id, filter=None): 79 logger = WsLogStreamer(stream_id, self, filter) 80 logger.setFormatter(logging.Formatter('[%(asctime)s] %(levelname)-8s %(name)s %(message)s')) 81 logger.setLevel(logging.getLevelName("DEBUG")) 82 83 logging.getLogger('').addHandler(logger) 84 return logger 85 86 @flag.no_multiuser 87 @flag.admin 88 def actionConsoleLogStream(self, to, filter=None): 89 stream_id = to 90 self.log_streamers[stream_id] = self.addLogStreamer(stream_id, filter) 91 self.response(to, {"stream_id": stream_id}) 92 93 @flag.no_multiuser 94 @flag.admin 95 def actionConsoleLogStreamRemove(self, to, stream_id): 96 try: 97 self.log_streamers[stream_id].stop() 98 del self.log_streamers[stream_id] 99 return "ok" 100 except Exception as err: 101 return {"error": Debug.formatException(err)}