From 360aeb5574f83890630bea2ab4c5a1ceab3172d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mose=20M=C3=BCller?= Date: Thu, 27 Feb 2025 15:37:35 +0100 Subject: [PATCH 1/4] log: pydase.server logs are written to stdout, the rest is written to stderr --- src/pydase/utils/logging.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/pydase/utils/logging.py b/src/pydase/utils/logging.py index cb83c04..0bda417 100644 --- a/src/pydase/utils/logging.py +++ b/src/pydase/utils/logging.py @@ -31,12 +31,22 @@ LOGGING_CONFIG = { }, "handlers": { "default": { + "formatter": "default", + "class": "logging.StreamHandler", + "stream": "ext://sys.stderr", + }, + "stdout": { "formatter": "default", "class": "logging.StreamHandler", "stream": "ext://sys.stdout", }, }, "loggers": { + "pydase.server": { + "handlers": ["stdout"], + "level": LOG_LEVEL, + "propagate": False, + }, "pydase": {"handlers": ["default"], "level": LOG_LEVEL, "propagate": False}, "aiohttp_middlewares": { "handlers": ["default"], From f2183ec3e4fd513c98d6f2bb430c8210dbddbf2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mose=20M=C3=BCller?= Date: Thu, 27 Feb 2025 15:45:01 +0100 Subject: [PATCH 2/4] log: changing log level of trigger_method --- src/pydase/server/web_server/sio_setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pydase/server/web_server/sio_setup.py b/src/pydase/server/web_server/sio_setup.py index f1d9da8..2342b8e 100644 --- a/src/pydase/server/web_server/sio_setup.py +++ b/src/pydase/server/web_server/sio_setup.py @@ -202,7 +202,7 @@ def setup_sio_events(sio: socketio.AsyncServer, state_manager: StateManager) -> @sio.event async def trigger_method(sid: str, data: TriggerMethodDict) -> Any: async with sio.session(sid) as session: - logger.debug( + logger.info( "Client [%s] is triggering the method '%s'", session["client_id"], data["access_path"], From 3d13b20fdab1622b09e4425756767cd256960684 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mose=20M=C3=BCller?= Date: Fri, 28 Feb 2025 15:43:24 +0100 Subject: [PATCH 3/4] log: using filters to separate server and task logs from the rest --- src/pydase/utils/logging.py | 51 +++++++++++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 11 deletions(-) diff --git a/src/pydase/utils/logging.py b/src/pydase/utils/logging.py index 0bda417..b5e33d4 100644 --- a/src/pydase/utils/logging.py +++ b/src/pydase/utils/logging.py @@ -29,32 +29,44 @@ LOGGING_CONFIG = { "datefmt": "%Y-%m-%d %H:%M:%S", }, }, - "handlers": { - "default": { - "formatter": "default", - "class": "logging.StreamHandler", - "stream": "ext://sys.stderr", + "filters": { + "only_pydase_server_or_task": { + "()": "pydase.utils.logging.NameFilter", + "matches": ["pydase.server", "pydase.task"], }, - "stdout": { + "exclude_pydase_server_and_task": { + "()": "pydase.utils.logging.NameFilter", + "matches": ["pydase.server", "pydase.task"], + "invert": True, + }, + }, + "handlers": { + "stdout_handler": { "formatter": "default", "class": "logging.StreamHandler", "stream": "ext://sys.stdout", + "filters": ["only_pydase_server_or_task"], + }, + "stderr_handler": { + "formatter": "default", + "class": "logging.StreamHandler", + "stream": "ext://sys.stderr", + "filters": ["exclude_pydase_server_and_task"], }, }, "loggers": { - "pydase.server": { - "handlers": ["stdout"], + "pydase": { + "handlers": ["stdout_handler", "stderr_handler"], "level": LOG_LEVEL, "propagate": False, }, - "pydase": {"handlers": ["default"], "level": LOG_LEVEL, "propagate": False}, "aiohttp_middlewares": { - "handlers": ["default"], + "handlers": ["stderr_handler"], "level": logging.WARNING, "propagate": False, }, "aiohttp": { - "handlers": ["default"], + "handlers": ["stderr_handler"], "level": logging.INFO, "propagate": False, }, @@ -62,6 +74,23 @@ LOGGING_CONFIG = { } +class NameFilter(logging.Filter): + """ + Logging filter that allows filtering logs based on the logger name. + Can either include or exclude a specific logger. + """ + + def __init__(self, matches: list[str], invert: bool = False): + super().__init__() + self.matches = matches + self.invert = invert + + def filter(self, record: logging.LogRecord) -> bool: + if self.invert: + return not any(record.name.startswith(match) for match in self.matches) + return any(record.name.startswith(match) for match in self.matches) + + class DefaultFormatter(logging.Formatter): """ A custom log formatter class that: From 9a8628cfbd29caacdaa8583e0c87ceb9804cb8f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mose=20M=C3=BCller?= Date: Fri, 28 Feb 2025 15:53:14 +0100 Subject: [PATCH 4/4] log: only write pydase.server to stdout, the rest to stderr --- src/pydase/utils/logging.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/pydase/utils/logging.py b/src/pydase/utils/logging.py index b5e33d4..f071d6b 100644 --- a/src/pydase/utils/logging.py +++ b/src/pydase/utils/logging.py @@ -30,13 +30,13 @@ LOGGING_CONFIG = { }, }, "filters": { - "only_pydase_server_or_task": { + "only_pydase_server": { "()": "pydase.utils.logging.NameFilter", - "matches": ["pydase.server", "pydase.task"], + "match": "pydase.server", }, - "exclude_pydase_server_and_task": { + "exclude_pydase_server": { "()": "pydase.utils.logging.NameFilter", - "matches": ["pydase.server", "pydase.task"], + "match": "pydase.server", "invert": True, }, }, @@ -45,13 +45,13 @@ LOGGING_CONFIG = { "formatter": "default", "class": "logging.StreamHandler", "stream": "ext://sys.stdout", - "filters": ["only_pydase_server_or_task"], + "filters": ["only_pydase_server"], }, "stderr_handler": { "formatter": "default", "class": "logging.StreamHandler", "stream": "ext://sys.stderr", - "filters": ["exclude_pydase_server_and_task"], + "filters": ["exclude_pydase_server"], }, }, "loggers": { @@ -80,15 +80,15 @@ class NameFilter(logging.Filter): Can either include or exclude a specific logger. """ - def __init__(self, matches: list[str], invert: bool = False): + def __init__(self, match: str, invert: bool = False): super().__init__() - self.matches = matches + self.match = match self.invert = invert def filter(self, record: logging.LogRecord) -> bool: if self.invert: - return not any(record.name.startswith(match) for match in self.matches) - return any(record.name.startswith(match) for match in self.matches) + return not record.name.startswith(self.match) + return record.name.startswith(self.match) class DefaultFormatter(logging.Formatter):