From 5e9dcadb625719fbe9907d96155e84baa0c11475 Mon Sep 17 00:00:00 2001 From: karel26 <41538366+karel26@users.noreply.github.com> Date: Mon, 20 Jan 2025 18:57:47 +0100 Subject: [PATCH] HOTFIX: - LogAnalyser: performance issue fixed --- extensions/loganalyser/extension.py | 61 +++++++++++++++++++---------- 1 file changed, 40 insertions(+), 21 deletions(-) diff --git a/extensions/loganalyser/extension.py b/extensions/loganalyser/extension.py index d1d93254..b4df72a5 100644 --- a/extensions/loganalyser/extension.py +++ b/extensions/loganalyser/extension.py @@ -54,6 +54,7 @@ async def do_startup(self): asyncio.create_task(self.check_log()) async def prepare(self) -> bool: + os.remove(self.logfile) await self.do_startup() self.running = True return await super().startup() @@ -71,6 +72,12 @@ def shutdown(self) -> bool: self.stop_event.set() return super().shutdown() + @property + def logfile(self) -> str: + return os.path.expandvars( + self.config.get('log', os.path.join(self.server.instance.home, 'Logs', 'dcs.log')) + ) + async def check_log(self): try: logfile = os.path.expandvars( @@ -83,28 +90,40 @@ async def check_log(self): self.log_pos = 0 while not self.stop_event.is_set(): - if not os.path.exists(logfile): - self.log_pos = 0 - await asyncio.sleep(1) - continue - - async with aiofiles.open(logfile, mode='r', encoding='utf-8', errors='ignore') as file: - await file.seek(self.log_pos, 0) - async for line in file: - if '=== Log closed.' in line: - self.log_pos = -1 - return - match = combined_pattern.search(line) - if match: - for key, value in match.groupdict().items(): - if value: - callback = callback_map[key] - if asyncio.iscoroutinefunction(callback): - asyncio.create_task(callback(self.log_pos, line, match)) - else: - self.loop.run_in_executor(None, callback, self.log_pos, line, match) + try: + if not os.path.exists(logfile): + self.log_pos = 0 + continue + + async with aiofiles.open(logfile, mode='r', encoding='utf-8', errors='ignore') as file: + max_pos = os.fstat(file.fileno()).st_size + if self.log_pos == -1 or max_pos == self.log_pos: + self.log_pos = max_pos + continue + # if the logfile was rotated, seek to the beginning of the file + elif max_pos < self.log_pos: + self.log_pos = 0 + + self.log_pos = await file.seek(self.log_pos, 0) + await file.seek(self.log_pos, 0) + async for line in file: + if '=== Log closed.' in line: + self.log_pos = -1 + return + match = combined_pattern.search(line) + if match: + for key, value in match.groupdict().items(): + if value: + callback = callback_map[key] + if asyncio.iscoroutinefunction(callback): + asyncio.create_task(callback(self.log_pos, line, match)) + else: + self.loop.run_in_executor(None, callback, self.log_pos, line, match) self.log_pos = await file.tell() - + except FileNotFoundError as ex: + pass + finally: + await asyncio.sleep(1) except Exception as ex: self.log.exception(ex) finally: