Skip to content
Snippets Groups Projects
Commit c4766b93 authored by Christoph Schmidt's avatar Christoph Schmidt
Browse files

Logs can be now redirected to a file as well.

parent ea3f4deb
No related branches found
No related tags found
No related merge requests found
......@@ -12,7 +12,7 @@ class ChildProcess3(cmp.CProcess):
self.logger = None
def postrun_init(self):
self.logger, self.logger_h = self.create_new_logger(f"{self.__class__.__name__}-({os.getpid()})")
self.logger = self.create_new_logger(f"{self.__class__.__name__}-({os.getpid()})")
@cmp.CProcess.register_signal()
def test_call(self, a):
......
......@@ -24,8 +24,8 @@ class Form(QDialog):
def __init__(self, parent=None):
super().__init__(parent)
child_con = ChildProcessControl3(self, internal_log=False, internal_log_level=logging.INFO)
child_con.set_internal_log_level(logging.CRITICAL)
child_con = ChildProcessControl3(self, internal_log=True, internal_log_level=logging.INFO, log_file="log.log")
child_con.set_internal_log_level(logging.WARNING)
child_con.mp_finished.connect(self.updateUI)
......
......@@ -15,23 +15,35 @@ class CBase:
def create_new_logger(self, logger_name: str,
logger_handler: logging.Handler = None,
logger_format: str = " %(name)s %(message)s") -> (logging.Logger, logging.Handler):
logger_format: str = "%(asctime)s - %(name)s %(message)s",
to_file=None) -> (logging.Logger, logging.Handler):
"""
Creates a new logger with the given name and handler. If no handler is given, a RichHandler will be used.
:param logger_name:
:param logger_handler:
:param logger_format:
:param to_file:
:return:
"""
if logger_handler is None:
logger_handler = RichHandler(rich_tracebacks=True)
logger_handler.setLevel(logging.DEBUG)
_internal_logger = logging.getLogger(logger_name)
_internal_logger.handlers = [logger_handler]
_internal_logger.setLevel(logging.DEBUG)
formatter = logging.Formatter(logger_format)
logger_handler.setFormatter(formatter)
return _internal_logger, logger_handler
if to_file is not None:
_file_handler = logging.FileHandler(to_file)
_file_handler.setLevel(logging.DEBUG)
_file_handler_formated = logging.Formatter(f"%(levelname)s > {logger_format})")
_file_handler.setFormatter(_file_handler_formated)
_internal_logger.addHandler(_file_handler)
return _internal_logger
@property
def internal_log_enabled(self):
......@@ -60,7 +72,7 @@ class CBase:
@property
def internal_log_level(self):
return self._internal_logger.level
return self._internal_logger.handlers[0].level
@internal_log_level.setter
def internal_log_level(self, level: int) -> None:
......@@ -82,7 +94,7 @@ class CBase:
self._internal_logger.info(f"Internal log level of {self.__class__.__name__} has been set to CRITICAL.")
else:
self._internal_logger.info(f"Internal log level of {self.__class__.__name__} has been set to {level}.")
self._internal_logger.setLevel(level)
self._internal_logger.handlers[0].setLevel(level)
else:
raise Exception("Can't set internal log level. Internal logger not initialized")
......@@ -19,7 +19,7 @@ class CProcess(CBase, Process):
def __init__(self, state_queue: Queue, cmd_queue: Queue,
kill_flag,
internal_log, internal_log_level,
internal_log, internal_log_level, log_file=None,
*args, **kwargs):
Process.__init__(self)
......@@ -27,6 +27,7 @@ class CProcess(CBase, Process):
self._internal_log_level_ = internal_log_level
self.logger = None
self.logger_handler = None
self.log_file = log_file
self.cmd_queue = cmd_queue
self.state_queue = state_queue
......@@ -54,23 +55,23 @@ class CProcess(CBase, Process):
def run(self):
self.name = f"{os.getpid()}({self.name})"
self._internal_logger, self._internal_log_handler = self.create_new_logger(
self._internal_logger = self.create_new_logger(
f"(cmp) {self.name}",
logger_handler=logging.handlers.QueueHandler(self.state_queue))
logger_handler=logging.handlers.QueueHandler(self.state_queue),
logger_format="%(message)s")
self.internal_log_enabled = self._internal_log_enabled_
self.internal_log_level = self._internal_log_level_
self.logger, self.logger_handler = self.create_new_logger(f"{os.getpid()}({self.__class__.__name__})",
logger_handler=logging.handlers.QueueHandler(
self.state_queue))
self.logger = self.create_new_logger(
f"{os.getpid()}({self.__class__.__name__})",
logger_handler=logging.handlers.QueueHandler(self.state_queue))
self._internal_logger.debug(f"Child process {self.__class__.__name__} started.")
sys.stderr.write = self.logger.error
sys.stdout.write = self.logger.info
#sys.stderr.write = self.logger.error
#sys.stdout.write = self.logger.info
self.postrun_init()
......@@ -103,7 +104,7 @@ class CProcess(CBase, Process):
except Exception as e:
self._internal_logger.warning(f"Received Exception {e}! Exiting Process {os.getpid()}")
self._internal_logger.debug(f"Child process monitor {self.__class__.__name__} ended.")
self._internal_logger.warning(f"Child process monitor {self.__class__.__name__} ended.")
def __del__(self):
#self.logger.warning(f"Child process {self.name} deleted.")
......@@ -128,7 +129,6 @@ class CProcess(CBase, Process):
@staticmethod
def register_signal(postfix=None, signal_name: str = None):
_postfix = postfix.strip() if postfix is not None else None
......@@ -171,6 +171,14 @@ class CProcess(CBase, Process):
def set_internal_log_enabled(self, enabled):
self.internal_log_enabled = enabled
@register_signal()
def set_child_log_level(self, level):
self.logger.setLevel(level)
@register_signal()
def set_child_log_enabled(self, enabled):
self.logger.disabled = not enabled
@staticmethod
def setter(signal_same: str = None):
def register(func):
......
......@@ -25,10 +25,20 @@ class CProcessControl(CBase, QObject):
def __init__(self, parent: QObject = None,
signal_class: QObject = None,
internal_log: bool = False,
internal_log_level: int = logging.DEBUG):
internal_log_level: int = logging.DEBUG,
log_file: str = None):
QObject.__init__(self, parent)
CBase.__init__(self)
# self._kill_child_process_flag = kill_child_process_flag
self.log_file = log_file
self._internal_logger = self.create_new_logger(
f"(cmp) {self.name}",
to_file=self.log_file)
self.logger = self.create_new_logger(
f"{self.__class__.__name__}({os.getpid()})",
to_file=self.log_file)
self.internal_log_enabled = internal_log
self.internal_log_level = internal_log_level
if isinstance(parent, QWidget) or isinstance(parent, QWindow):
parent.destroyed.connect(lambda: self.safe_exit(reason="Parent destroyed."))
......@@ -57,10 +67,6 @@ class CProcessControl(CBase, QObject):
self._child_kill_flag = Value('i', 1)
self._internal_logger, self._internal_log_handler = self.create_new_logger(f"(cmp) {self.name}")
self.internal_log_enabled = internal_log
self.internal_log_level = internal_log_level
self.logger, self.logger_handler = self.create_new_logger(f"{self.__class__.__name__}({os.getpid()})")
self.on_exception_raised.connect(self.display_exception)
self.msg_box = QMessageBox()
......@@ -82,6 +88,7 @@ class CProcessControl(CBase, QObject):
kill_flag=self._child_kill_flag,
internal_log=self.internal_log_enabled,
internal_log_level=self.internal_log_level,
log_file=self.log_file,
*args, **kwargs)
# self._child.register_kill_flag(self._child_kill_flag)
self._child_process_pid = child.pid
......@@ -89,8 +96,6 @@ class CProcessControl(CBase, QObject):
self._internal_logger.debug(f"Child process {self._child.name} created.")
self.thread_manager.start(self._monitor_result_state)
@property
def child(self):
return self._child
......@@ -213,6 +218,22 @@ class CProcessControl(CBase, QObject):
def set_internal_log_enabled(self, enabled):
self.internal_log_enabled = enabled
@register_function()
def set_child_log_level(self, level):
"""
Sets the regular logging level of the child process.
:param level:
:return:
"""
@register_function()
def set_child_log_enabled(self, enabled):
"""
Enables or disables logging of the child process.
:param enabled:
:return:
"""
def safe_exit(self, reason: str = ""):
self._internal_logger.warning(f"Shutting down ProcessControl {os.getpid()}. Reason: {reason}")
self._child_kill_flag.value = 0
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment