reoc/simu-lora/simlib/monitor.py

75 lines
2.8 KiB
Python

#!/usr/bin/env python3
import threading
import io
from simlib.borg import *
from simlib.eventscheduler import *
from simlib.defaults import *
class Monitor(Borg):
''' Public Borg methods to be defined in subclasses '''
def init(self, file_name=None, long_file_enabled=True):
if self.master_exists() and not self.is_master():
raise AttributeError('a bug is present, this must never happen')
if file_name is None:
if self.master_exists():
self.reset()
raise ValueError('master cannot be set without specifying a duration')
return
self.set_master()
self.event_scheduler = EventScheduler()
self.__file_name = file_name
self.__long_file_enabled = long_file_enabled
self.__stop_condition = threading.Event()
self.__lock = threading.Lock()
self.__queue = []
self.__thread = threading.Thread(target=self.__run)
self.__thread.start()
''' Public methods '''
def log(self, log_message, long_file=True, short_file=False, timestamp=False):
if not self.master_exists():
raise AttributeError('this method cannot be called if a master does not exist')
self.__lock.acquire()
log_message = '{} '.format(self.event_scheduler.get_current_time()) * timestamp + log_message
self.__queue.append((log_message, long_file and self.__long_file_enabled, short_file))
self.__lock.release()
def logline(self, log_message, *args, **kwargs):
self.log(log_message + '\n', *args, **kwargs)
def reset(self):
if self.is_master():
self.__stop_condition.set()
self.__thread.join()
self.__stop_condition.clear()
super(Monitor, self).reset()
''' Private helper methods'''
def __run(self):
while not self.__stop_condition.is_set():
self.__stop_condition.wait(100)
dump_long = ''
dump_short = ''
self.__lock.acquire()
for string_to_write, long_file, short_file in self.__queue:
dump_long += long_file * string_to_write
dump_short += short_file * string_to_write
self.__queue.clear()
self.__lock.release()
if self.__stop_condition.is_set():
if self.__long_file_enabled:
dump_long += DEFAULT.SEPARATOR + '\n'
dump_short += DEFAULT.SEPARATOR + '\n'
if dump_long != '' and self.__long_file_enabled:
with io.open(self.__file_name + '_long.txt', 'a', encoding='utf-8') as f:
f.write(dump_long.encode().decode())
if dump_short != '':
with io.open(self.__file_name + '_short.txt', 'a', encoding='utf-8') as f:
f.write(dump_short.encode().decode())