|
| 1 | +Communication Logging |
| 2 | +===================== |
| 3 | +UDS communication logging utilities are provided in :mod:`uds.transport_interface.logger` module. |
| 4 | + |
| 5 | + |
| 6 | +TransportLogger |
| 7 | +--------------- |
| 8 | +:class:`~uds.transport_interface.logger.TransportLogger` is the recommended implementation |
| 9 | +of the communication logging feature. |
| 10 | +The logger works by wrapping transport interface methods responsible for sending and receiving |
| 11 | +:ref:`UDS Messages <knowledge-base-diagnostic-message>` and :ref:`Packets <knowledge-base-packet>`. |
| 12 | + |
| 13 | +This logger integrates with the built-in |
| 14 | +`logging <https://docs.python.org/3/library/logging.html>`_ module. |
| 15 | + |
| 16 | +Thanks to the modular package design, custom logging implementations can easily be inserted |
| 17 | +between existing communication layers. |
| 18 | + |
| 19 | +.. seealso:: `Python logging documentation <https://docs.python.org/3/library/logging.html>`_ |
| 20 | + |
| 21 | +Attributes: |
| 22 | + |
| 23 | +- :attr:`~uds.transport_interface.logger.TransportLogger.logger` |
| 24 | +- :attr:`~uds.transport_interface.logger.TransportLogger.message_logging_level` |
| 25 | +- :attr:`~uds.transport_interface.logger.TransportLogger.packet_logging_level` |
| 26 | +- :attr:`~uds.transport_interface.logger.TransportLogger.log_sending` |
| 27 | +- :attr:`~uds.transport_interface.logger.TransportLogger.log_receiving` |
| 28 | +- :attr:`~uds.transport_interface.logger.TransportLogger.message_log_format` |
| 29 | +- :attr:`~uds.transport_interface.logger.TransportLogger.packet_log_format` |
| 30 | + |
| 31 | + |
| 32 | +Configuration |
| 33 | +````````````` |
| 34 | + |
| 35 | +Upon :class:`~uds.transport_interface.logger.TransportLogger` object creation, the user can configure how the logger |
| 36 | +behaves during the communication. |
| 37 | + |
| 38 | +**Example code:** |
| 39 | + |
| 40 | +.. code-block:: python |
| 41 | +
|
| 42 | + import logging |
| 43 | + from uds.transport_interface import TransportLogger |
| 44 | +
|
| 45 | + # create example Transport Logger |
| 46 | + transport_logger = TransportLogger( |
| 47 | + logger_name="UDS", |
| 48 | + message_logging_level=logging.INFO, |
| 49 | + packet_logging_level=logging.DEBUG, |
| 50 | + log_sending=True, |
| 51 | + log_receiving=True, |
| 52 | + message_log_format="{record.direction.name} {record.addressing_type.name} {record.payload}", |
| 53 | + packet_log_format="{record.direction.name} {record}") |
| 54 | +
|
| 55 | + transport_logger.log_sending = False # do not log outgoing communication |
| 56 | + transport_logger.packet_logging_level = None # do not log packets |
| 57 | +
|
| 58 | +
|
| 59 | +Activation |
| 60 | +`````````` |
| 61 | +There are two ways to activate the logger: |
| 62 | + |
| 63 | +- `Decorating Transport Interface class`_ |
| 64 | +- `Decorating Transport Interface instance`_ |
| 65 | + |
| 66 | + |
| 67 | +Decorating Transport Interface class |
| 68 | +'''''''''''''''''''''''''''''''''''' |
| 69 | +Transport Logger activation is possible by decorating Transport Interface class. |
| 70 | +This is the recommended (and most Pythonic) approach when implementing custom transport interfaces. |
| 71 | + |
| 72 | +**Example code:** |
| 73 | + |
| 74 | +.. code-block:: python |
| 75 | +
|
| 76 | + from uds.transport_interface import AbstractTransportInterface, TransportLogger |
| 77 | +
|
| 78 | + # let's assume that we have `transport_logger` already configured |
| 79 | + transport_logger: TransportLogger |
| 80 | +
|
| 81 | + @transport_logger |
| 82 | + class MyTransportInterface(AbstractTransportInterface): |
| 83 | + ... # TODO: custom implementation |
| 84 | +
|
| 85 | +
|
| 86 | +It is also possible to decorate existing Transport Interfaces. |
| 87 | + |
| 88 | +**Example code:** |
| 89 | + |
| 90 | +.. code-block:: python |
| 91 | +
|
| 92 | + from uds.transport_interface import TransportLogger |
| 93 | + from uds.can import PyCanTransportInterface |
| 94 | +
|
| 95 | + # let's assume that we have `transport_logger` already configured |
| 96 | + transport_logger: TransportLogger |
| 97 | +
|
| 98 | + PyCanTransportInterfaceWithLogging = transport_logger(PyCanTransportInterface) |
| 99 | +
|
| 100 | +.. seealso:: :ref:`An example script <example-transport-logger-class>` |
| 101 | + |
| 102 | + |
| 103 | +Decorating Transport Interface instance |
| 104 | +''''''''''''''''''''''''''''''''''''''' |
| 105 | +Another option is to decorate an already existing transport interface instance. |
| 106 | + |
| 107 | +**Example code:** |
| 108 | + |
| 109 | +.. code-block:: python |
| 110 | +
|
| 111 | + from uds.transport_interface import AbstractTransportInterface, TransportLogger |
| 112 | +
|
| 113 | + # let's assume that we have `transport_interface` already configured |
| 114 | + transport_interface: AbstractTransportInterface |
| 115 | +
|
| 116 | + # let's assume that we have `transport_logger` already configured |
| 117 | + transport_logger: TransportLogger |
| 118 | +
|
| 119 | + # add logging to the transport_interface |
| 120 | + transport_interface_with_logger = transport_logger(transport_interface) |
| 121 | +
|
| 122 | +.. seealso:: :ref:`An example script <example-transport-logger-instance>` |
| 123 | + |
| 124 | + |
| 125 | +Customization |
| 126 | +````````````` |
| 127 | +The easiest way to create your own transport logger is to inherit after |
| 128 | +:class:`~uds.transport_interface.logger.TransportLogger` class and add your own features. |
| 129 | +This is also the easiest way to define more advanced or custom logging messages. |
| 130 | + |
| 131 | +**Example code:** |
| 132 | + |
| 133 | +.. code-block:: python |
| 134 | +
|
| 135 | + from uds.transport_interface import TransportLogger |
| 136 | + from uds.addressing import TransmissionDirection |
| 137 | + from uds.message import UdsMessageRecord |
| 138 | + from uds.utilities import bytes_to_hex |
| 139 | +
|
| 140 | + class MyTransportLogger(TransportLogger): |
| 141 | +
|
| 142 | + def log_message(self, record: UdsMessageRecord) -> None: |
| 143 | + """Log a message after receiving/transmitting UDS Message.""" |
| 144 | + if self.message_logging_level is not None: |
| 145 | + if record.direction == TransmissionDirection.TRANSMITTED: |
| 146 | + message = f"Transmitted message with payload: {bytes_to_hex(record.payload)}" |
| 147 | + else: |
| 148 | + message = f"Received message with payload: {bytes_to_hex(record.payload)}" |
| 149 | + self.logger.log(level=self.message_logging_level, |
| 150 | + msg=message) |
0 commit comments