From 4d2b8211d919344c8c5fd6f04b159b1d87ebcb3d Mon Sep 17 00:00:00 2001 From: SantaSpeen Date: Wed, 12 Mar 2025 15:06:19 +0300 Subject: [PATCH] [+] Add logging --- examples/server_custom_logger.py | 17 ++++++++++++++ winConnect/WinConnectBase.py | 28 +++++++++-------------- winConnect/WinConnectClient.py | 38 ++++++++++++++------------------ winConnect/WinConnectDaemon.py | 15 +++++++++++++ 4 files changed, 60 insertions(+), 38 deletions(-) create mode 100644 examples/server_custom_logger.py diff --git a/examples/server_custom_logger.py b/examples/server_custom_logger.py new file mode 100644 index 0000000..ac38636 --- /dev/null +++ b/examples/server_custom_logger.py @@ -0,0 +1,17 @@ +import sys + +from loguru import logger +from winConnect import WinConnectDaemon + +connector = WinConnectDaemon('test') + +logger.remove() +logger.add(sys.stdout, level="DEBUG") + +connector.set_logger(logger) + +for data in connector.listen(): + print(f"({type(data)}) {data=}") + if data is None and connector.closed: + break + connector.send_data(data) diff --git a/winConnect/WinConnectBase.py b/winConnect/WinConnectBase.py index 876beef..28803fb 100644 --- a/winConnect/WinConnectBase.py +++ b/winConnect/WinConnectBase.py @@ -1,4 +1,5 @@ import json +import logging import struct import threading import zlib @@ -12,7 +13,6 @@ from winConnect.errors import WinConnectErrors, WinConnectClientError from winConnect import exceptions from winConnect.utils import SimpleConvertor - # header: len(data) in struct.pack via header_format # data: action:data # headerDATA @@ -28,7 +28,7 @@ class WinConnectBase: ormsgpack_options = ormsgpack.OPT_NON_STR_KEYS | ormsgpack.OPT_NAIVE_UTC | ormsgpack.OPT_PASSTHROUGH_TUPLE # ormsgpack options def __init__(self, pipe_name: str): - self.run = True + self._log = logging.getLogger(f"WinConnect:{pipe_name}") self._version = 1 self._pipe_name = r'\\.\pipe\{}'.format(pipe_name) self._pipe = None @@ -46,6 +46,9 @@ class WinConnectBase: self._lock = threading.Lock() + def set_logger(self, logger): + self._log = logger + def _calc_body_max_size(self): # Max size of body: 2 ** (8 * header_size) - 1 - header_size - 1 # - header_size; X byte for header_size @@ -126,9 +129,9 @@ class WinConnectBase: if not self._connected: return None, None _, data = win32file.ReadFile(self._pipe, message_size) - unpacked_data = self.__unpack_data(data) - print("Received message:", *unpacked_data) - return unpacked_data + action, data = self.__unpack_data(data) + # self._log.debug(f"[{self._pipe_name}] Received message: {action=} {data=}") + return action, data def _send_message(self, action: str, data: Any): action = action.encode(self.encoding) @@ -144,7 +147,7 @@ class WinConnectBase: raise ValueError('Message is too big') _hfmt, _ = self.__header_settings header = struct.pack(_hfmt, message_size) - print("Sending message :", action, data) + # self._log.debug(f"[{self._pipe_name}] Sending message: {action=} {data=}") win32file.WriteFile(self._pipe, header) win32file.WriteFile(self._pipe, packed_data) @@ -170,6 +173,7 @@ class WinConnectBase: command, data = self.__parse_message(data) match command: case b'get_session_settings': + self._log.debug(f"[{self._pipe_name}] Received get_session_settings from {data}") settings = { 'version': self._version, 'encoding': self.default_encoding, @@ -226,7 +230,7 @@ class WinConnectBase: self._connected = False self._inited = False self._pipe = None - print("session closed") + self._log.debug(f"[{self._pipe_name}] Session closed") def _read(self) -> Any: if self.closed: @@ -238,13 +242,3 @@ class WinConnectBase: def read_pipe(self): ... - - def listen(self): - while self.run: - yield self.read_pipe() - self.stop() - - def stop(self): - self.run = False - with self._lock: - self.close() diff --git a/winConnect/WinConnectClient.py b/winConnect/WinConnectClient.py index 65a9324..4362c55 100644 --- a/winConnect/WinConnectClient.py +++ b/winConnect/WinConnectClient.py @@ -30,6 +30,7 @@ class WinConnectClient(WinConnectBase): ) self._opened = True self._connected = True + self._log.debug(f"Pipe '{self._pipe_name}' opened") except pywintypes.error as e: if e.winerror == 2: exc = WinConnectConnectionNoPipeException(f"Error while opening pipe: Pipe not found") @@ -37,39 +38,34 @@ class WinConnectClient(WinConnectBase): raise exc raise e - def _init(self): - self._send_message("command", b"get_session_settings:") + def _init(self, program_name="NoName"): + self._send_message("command", b"get_session_settings:" + program_name.encode(self.encoding)) self._init_session() - def connect(self): - """Connect to server""" - self._open_pipe() - return self.init_session() - - def init_session(self): - """Init session with server: get session settings""" - self._init() - return self - def _close_session(self): """Send close command to server""" if not self.closed: self._send_message("command", b"close:") - def __enter__(self): - if not self._connected: - self.connect() + def __check_pipe(self): + if not self._opened: + self._open_pipe() if not self._inited: - self.init_session() + self._init() + + def __enter__(self): + self.__check_pipe() return self def __exit__(self, exc_type, exc_val, exc_tb): - # self._close_session() self.close() + def connect(self, program_name: str="NoName"): + """Connect to server and initialize session""" + self._open_pipe() + self._init(program_name) + return self + def read_pipe(self): - if not self._connected: - self.connect() - if not self._inited: - self.init_session() + self.__check_pipe() return self._read() diff --git a/winConnect/WinConnectDaemon.py b/winConnect/WinConnectDaemon.py index d0770c2..ea21a6c 100644 --- a/winConnect/WinConnectDaemon.py +++ b/winConnect/WinConnectDaemon.py @@ -16,6 +16,7 @@ class WinConnectDaemon(WinConnectBase): def __init__(self, pipe_name: str): super().__init__(pipe_name) + self.run = True def _open_pipe(self): self._pipe = win32pipe.CreateNamedPipe( @@ -29,12 +30,17 @@ class WinConnectDaemon(WinConnectBase): self.pipe_sa ) self._opened = True + self._log.debug(f"[{self._pipe_name}] Pipe opened") + + def _close_session(self): + self.run = False def wait_client(self): if not self._opened: self._open_pipe() win32pipe.ConnectNamedPipe(self._pipe, None) self._connected = True + self._log.debug(f"[{self._pipe_name}] Client connected") def read_pipe(self): if not self._connected: @@ -44,3 +50,12 @@ class WinConnectDaemon(WinConnectBase): # if not self._read(): # raise return self._read() + + def listen(self): + while self.run: + yield self.read_pipe() + self.stop() + + def stop(self): + self.run = False + self.close()