All of lore.kernel.org
 help / color / mirror / Atom feed
From: John Snow <jsnow@redhat.com>
To: qemu-devel@nongnu.org
Cc: Eduardo Habkost <ehabkost@redhat.com>,
	Eric Blake <eblake@redhat.com>,
	Stefan Hajnoczi <stefanha@redhat.com>,
	Markus Armbruster <armbru@redhat.com>,
	Wainer dos Santos Moschetta <wainersm@redhat.com>,
	"Niteesh G . S ." <niteesh.gs@gmail.com>,
	Willian Rampazzo <wrampazz@redhat.com>,
	Cleber Rosa <crosa@redhat.com>, John Snow <jsnow@redhat.com>
Subject: [PATCH v4 11/27] python/aqmp: add _cb_inbound and _cb_outbound logging hooks
Date: Wed, 15 Sep 2021 12:29:39 -0400	[thread overview]
Message-ID: <20210915162955.333025-12-jsnow@redhat.com> (raw)
In-Reply-To: <20210915162955.333025-1-jsnow@redhat.com>

Add hooks designed to log/filter incoming/outgoing messages. The primary
intent for these is to be able to support iotests which may want to log
messages with specific filters for reproducible output.

Another use is for plugging into Urwid frameworks; all messages in/out
can be automatically added to a rendering list for the purposes of a
qmp-shell like tool.

Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
---
 python/qemu/aqmp/protocol.py | 50 +++++++++++++++++++++++++++++++++---
 1 file changed, 46 insertions(+), 4 deletions(-)

diff --git a/python/qemu/aqmp/protocol.py b/python/qemu/aqmp/protocol.py
index 2ef19e9693..80c2004737 100644
--- a/python/qemu/aqmp/protocol.py
+++ b/python/qemu/aqmp/protocol.py
@@ -177,6 +177,11 @@ class AsyncProtocol(Generic[T]):
          can be written after the super() call.
      - `_on_message`:
          Actions to be performed when a message is received.
+     - `_cb_outbound`:
+         Logging/Filtering hook for all outbound messages.
+     - `_cb_inbound`:
+         Logging/Filtering hook for all inbound messages.
+         This hook runs *before* `_on_message()`.
 
     :param name:
         Name used for logging messages, if any. By default, messages
@@ -752,6 +757,43 @@ async def _bh_recv_message(self) -> None:
     # Section: Message I/O
     # --------------------
 
+    @upper_half
+    @bottom_half
+    def _cb_outbound(self, msg: T) -> T:
+        """
+        Callback: outbound message hook.
+
+        This is intended for subclasses to be able to add arbitrary
+        hooks to filter or manipulate outgoing messages. The base
+        implementation does nothing but log the message without any
+        manipulation of the message.
+
+        :param msg: raw outbound message
+        :return: final outbound message
+        """
+        self.logger.debug("--> %s", str(msg))
+        return msg
+
+    @upper_half
+    @bottom_half
+    def _cb_inbound(self, msg: T) -> T:
+        """
+        Callback: inbound message hook.
+
+        This is intended for subclasses to be able to add arbitrary
+        hooks to filter or manipulate incoming messages. The base
+        implementation does nothing but log the message without any
+        manipulation of the message.
+
+        This method does not "handle" incoming messages; it is a filter.
+        The actual "endpoint" for incoming messages is `_on_message()`.
+
+        :param msg: raw inbound message
+        :return: processed inbound message
+        """
+        self.logger.debug("<-- %s", str(msg))
+        return msg
+
     @upper_half
     @bottom_half
     async def _do_recv(self) -> T:
@@ -780,8 +822,8 @@ async def _recv(self) -> T:
 
         :return: A single (filtered, processed) protocol message.
         """
-        # A forthcoming commit makes this method less trivial.
-        return await self._do_recv()
+        message = await self._do_recv()
+        return self._cb_inbound(message)
 
     @upper_half
     @bottom_half
@@ -811,7 +853,7 @@ async def _send(self, msg: T) -> None:
 
         :raise OSError: For problems with the underlying stream.
         """
-        # A forthcoming commit makes this method less trivial.
+        msg = self._cb_outbound(msg)
         self._do_send(msg)
 
     @bottom_half
@@ -826,6 +868,6 @@ async def _on_message(self, msg: T) -> None:
             directly cause the loop to halt, so logic may be best-kept
             to a minimum if at all possible.
 
-        :param msg: The incoming message
+        :param msg: The incoming message, already logged/filtered.
         """
         # Nothing to do in the abstract case.
-- 
2.31.1



  parent reply	other threads:[~2021-09-15 16:43 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-15 16:29 [PATCH v4 00/27] python: introduce Asynchronous QMP package John Snow
2021-09-15 16:29 ` [PATCH v4 01/27] python/aqmp: add asynchronous QMP (AQMP) subpackage John Snow
2021-09-15 16:29 ` [PATCH v4 02/27] python/aqmp: add error classes John Snow
2021-09-15 16:29 ` [PATCH v4 03/27] python/pylint: Add exception for TypeVar names ('T') John Snow
2021-09-15 16:29 ` [PATCH v4 04/27] python/aqmp: add asyncio compatibility wrappers John Snow
2021-09-15 16:29 ` [PATCH v4 05/27] python/aqmp: add generic async message-based protocol support John Snow
2021-09-15 16:29 ` [PATCH v4 06/27] python/aqmp: add runstate state machine to AsyncProtocol John Snow
2021-09-15 16:29 ` [PATCH v4 07/27] python/aqmp: Add logging utility helpers John Snow
2021-09-15 16:29 ` [PATCH v4 08/27] python/aqmp: add logging to AsyncProtocol John Snow
2021-09-15 16:29 ` [PATCH v4 09/27] python/aqmp: add AsyncProtocol.accept() method John Snow
2021-09-15 16:29 ` [PATCH v4 10/27] python/aqmp: add configurable read buffer limit John Snow
2021-09-15 16:29 ` John Snow [this message]
2021-09-15 16:29 ` [PATCH v4 12/27] python/aqmp: add AsyncProtocol._readline() method John Snow
2021-09-15 16:29 ` [PATCH v4 13/27] python/aqmp: add QMP Message format John Snow
2021-09-15 16:29 ` [PATCH v4 14/27] python/aqmp: add well-known QMP object models John Snow
2021-09-15 16:29 ` [PATCH v4 15/27] python/aqmp: add QMP event support John Snow
2021-09-15 16:29 ` [PATCH v4 16/27] python/pylint: disable too-many-function-args John Snow
2021-09-15 16:29 ` [PATCH v4 17/27] python/aqmp: add QMP protocol support John Snow
2021-09-15 16:29 ` [PATCH v4 18/27] python/pylint: disable no-member check John Snow
2021-09-15 16:29 ` [PATCH v4 19/27] python/aqmp: Add message routing to QMP protocol John Snow
2021-09-15 16:29 ` [PATCH v4 20/27] python/aqmp: add execute() interfaces John Snow
2021-09-15 16:29 ` [PATCH v4 21/27] python/aqmp: add _raw() execution interface John Snow
2021-09-15 16:29 ` [PATCH v4 22/27] python/aqmp: add asyncio_run compatibility wrapper John Snow
2021-09-15 16:29 ` [PATCH v4 23/27] python/aqmp: add scary message John Snow
2021-09-15 16:29 ` [PATCH v4 24/27] python: bump avocado to v90.0 John Snow
2021-09-15 16:29 ` [PATCH v4 25/27] python/aqmp: add AsyncProtocol unit tests John Snow
2021-09-15 16:29 ` [PATCH v4 26/27] python/aqmp: add LineProtocol tests John Snow
2021-09-15 16:29 ` [PATCH v4 27/27] python/aqmp: Add Coverage.py support John Snow
2021-09-20 19:51 ` [PATCH v4 00/27] python: introduce Asynchronous QMP package John Snow

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210915162955.333025-12-jsnow@redhat.com \
    --to=jsnow@redhat.com \
    --cc=armbru@redhat.com \
    --cc=crosa@redhat.com \
    --cc=eblake@redhat.com \
    --cc=ehabkost@redhat.com \
    --cc=niteesh.gs@gmail.com \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@redhat.com \
    --cc=wainersm@redhat.com \
    --cc=wrampazz@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.