# Copyright (C) 2018 Avatao.com Innovative Learning Kft. # All Rights Reserved. See LICENSE file for details. import logging from os.path import dirname from watchdog.events import PatternMatchingEventHandler as PatternMatchingWatchdogEventHandler from tfw.networking.event_handlers import ServerUplinkConnector from tfw.decorators import RateLimiter from tfw.mixins import ObserverMixin, SupervisorLogMixin class LogMonitor(ObserverMixin): def __init__(self, process_name, log_tail=0): self.prevent_log_recursion() event_handler = SendLogWatchdogEventHandler( process_name, log_tail=log_tail ) self.observer.schedule( event_handler, event_handler.path ) @staticmethod def prevent_log_recursion(): # This is done to prevent inotify event logs triggering themselves (infinite log recursion) logging.getLogger('watchdog.observers.inotify_buffer').propagate = False class SendLogWatchdogEventHandler(PatternMatchingWatchdogEventHandler, SupervisorLogMixin): def __init__(self, process_name, log_tail=0): self.process_name = process_name self.procinfo = self.supervisor.getProcessInfo(self.process_name) super().__init__([ self.procinfo['stdout_logfile'], self.procinfo['stderr_logfile'] ]) self.uplink = ServerUplinkConnector() self.log_tail = log_tail @property def path(self): return dirname(self.procinfo['stdout_logfile']) @RateLimiter(rate_per_second=5) def on_modified(self, event): self.uplink.send({ 'key': 'processlog', 'data': { 'command': 'new_log', 'stdout': self.read_stdout(self.process_name, tail=self.log_tail), 'stderr': self.read_stderr(self.process_name, tail=self.log_tail) } })