aboutsummaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
authorJohn Snow <jsnow@redhat.com>2021-09-15 12:29:39 -0400
committerJohn Snow <jsnow@redhat.com>2021-09-27 12:10:29 -0400
commit12c7a57f5be577b6bb28c8526122cc51ad40a12b (patch)
tree293c1f8782d942cd252213e40281b1b1425b1bda /python
parent2686ac131634365899570bd8b8df99ae50354e79 (diff)
downloadqemu-12c7a57f5be577b6bb28c8526122cc51ad40a12b.zip
qemu-12c7a57f5be577b6bb28c8526122cc51ad40a12b.tar.gz
qemu-12c7a57f5be577b6bb28c8526122cc51ad40a12b.tar.bz2
python/aqmp: add _cb_inbound and _cb_outbound logging hooks
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> Message-id: 20210915162955.333025-12-jsnow@redhat.com Signed-off-by: John Snow <jsnow@redhat.com>
Diffstat (limited to 'python')
-rw-r--r--python/qemu/aqmp/protocol.py50
1 files changed, 46 insertions, 4 deletions
diff --git a/python/qemu/aqmp/protocol.py b/python/qemu/aqmp/protocol.py
index 2ef19e9..80c2004 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
@@ -754,6 +759,43 @@ class AsyncProtocol(Generic[T]):
@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:
"""
Abstract: Read from the stream and return a message.
@@ -780,8 +822,8 @@ class AsyncProtocol(Generic[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 @@ class AsyncProtocol(Generic[T]):
: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 @@ class AsyncProtocol(Generic[T]):
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.