Release b2cd74413a21bced599aa52431777de0; Logging + Restructuring

This commit is contained in:
Dirk Alders 2021-01-11 07:36:18 +01:00
parent 35d9f688a4
commit 54ff073143
8 changed files with 158734 additions and 49473 deletions

View File

@ -94,6 +94,16 @@ STATUS_CHECKSUM_ERROR = 5
"""Status for 'checksum error'"""
STATUS_OPERATION_NOT_PERMITTED = 6
"""Status for 'operation not permitted'"""
STATUS_LOG_LVL = {
STATUS_OKAY: logging.INFO,
STATUS_BUFFERING_UNHANDLED_REQUEST: logging.WARNING,
STATUS_CALLBACK_ERROR: logging.ERROR,
STATUS_AUTH_REQUIRED: logging.WARNING,
STATUS_SERVICE_OR_DATA_UNKNOWN: logging.ERROR,
STATUS_CHECKSUM_ERROR: logging.ERROR,
STATUS_OPERATION_NOT_PERMITTED: logging.WARNING,
}
"""Status depending log level for messages"""
AUTH_STATE_UNTRUSTED_CONNECTION = 0
"""Authentification Status for an 'Untrusted Connection'"""
@ -271,8 +281,8 @@ class pure_json_protocol(object):
#
self.__status_name_dict = {}
self.add_status(STATUS_OKAY, 'okay')
self.add_status(STATUS_BUFFERING_UNHANDLED_REQUEST, 'no callback for service, data buffered.')
self.add_status(STATUS_CALLBACK_ERROR, 'callback error.')
self.add_status(STATUS_BUFFERING_UNHANDLED_REQUEST, 'no callback for service, data buffered')
self.add_status(STATUS_CALLBACK_ERROR, 'callback error')
self.add_status(STATUS_AUTH_REQUIRED, 'authentification required')
self.add_status(STATUS_SERVICE_OR_DATA_UNKNOWN, 'service or data unknown')
self.add_status(STATUS_CHECKSUM_ERROR, 'checksum error')
@ -374,8 +384,8 @@ class pure_json_protocol(object):
self.__msg_buffer__[msg.get_service_id()][msg.get_data_id()].append(msg)
self.logger.debug("%s Message data is stored in buffer and is now ready to be retrieved by receive method", self.__log_prefix__())
def __build_frame__(self, service_id, data_id, data, status=STATUS_OKAY):
data_frame = json.dumps(self.__mk_msg__(status, service_id, data_id, data))
def __build_frame__(self, msg):
data_frame = json.dumps(self.__mk_msg__(msg.get_status(), msg.get_service_id(), msg.get_data_id(), msg.get_data()))
if sys.version_info >= (3, 0):
data_frame = bytes(data_frame, 'utf-8')
checksum = self.__calc_chksum__(data_frame)
@ -424,48 +434,52 @@ class pure_json_protocol(object):
if self.__auto_auth__ and self.__comm_inst__.IS_CLIENT and self.__secret__ is not None:
self.authentificate()
def __log_msg__(self, msg, rx_tx_prefix):
self.logger.log(
self.__status_log_lvl__(msg.get_status()),
'%s %s %s, %s, data: "%s"',
self.__log_prefix__(),
rx_tx_prefix,
self.__get_message_name__(msg.get_service_id(), msg.get_data_id()),
self.__get_status_name__(msg.get_status()),
repr(msg.get_data())
)
def __data_available_callback__(self, comm_inst):
frame = comm_inst.receive()
msg = self.__analyse_frame__(frame)
if not self.__check_frame_checksum__(frame):
# Wrong Checksum
self.logger.warning("%s RX <- Received message has a wrong checksum. Message will be ignored.", self.__log_prefix__())
self.logger.log(self.__status_log_lvl__(STATUS_CHECKSUM_ERROR), "%s Received message has an invalid checksum. Message will be ignored.", self.__log_prefix__())
return # No response needed
elif not self.check_authentification_state() and self.__authentification_required__(msg.get_service_id(), msg.get_data_id()):
# Authentification required
self.__log_msg__(msg, 'RX <-')
if msg.get_service_id() in self.__sid_response_dict__.keys():
self.logger.warning("%s RX <- Authentification is required. Just sending negative response.", self.__log_prefix__())
self.logger.log(self.__status_log_lvl__(STATUS_AUTH_REQUIRED), "%s Authentification is required. Just sending negative response.", self.__log_prefix__())
status = STATUS_AUTH_REQUIRED
data = None
else:
self.logger.warning("%s RX <- Authentification is required. Message will be ignored.", self.__log_prefix__())
self.logger.log(self.__status_log_lvl__(STATUS_AUTH_REQUIRED), "%s Authentification is required. Incomming message will be ignored.", self.__log_prefix__())
return # No response needed
else:
# Valid message
self.logger.info(
'%s RX <- %s, %s, data: "%s"',
self.__log_prefix__(),
self.__get_message_name__(msg.get_service_id(), msg.get_data_id()),
self.__get_status_name__(msg.get_status()),
repr(msg.get_data())
)
if msg.get_status() not in [STATUS_OKAY]:
self.logger.warning("%s RX <- Message has a peculiar status: %s", self.__log_prefix__(), self.__get_status_name__(msg.get_status()))
self.__log_msg__(msg, 'RX <-')
callback, args, kwargs = self.__callbacks__.get(msg.get_service_id(), msg.get_data_id())
if msg.get_service_id() in self.__sid_response_dict__.keys():
#
# REQUEST RECEIVED
#
if callback is None:
self.logger.warning("%s RX <- Message with no registered callback. Sending negative response.", self.__log_prefix__())
self.logger.warning("%s Incomming message with no registered callback. Sending negative response.", self.__log_prefix__())
status = STATUS_BUFFERING_UNHANDLED_REQUEST
data = None
else:
try:
self.logger.debug("%s RX <- Executing callback %s to process received data", self.__log_prefix__(), callback.__name__)
self.logger.debug("%s Executing callback %s to process received data", self.__log_prefix__(), callback.__name__)
status, data = callback(msg, *args, **kwargs)
except Exception:
logger.error('{lp} RX <- Exception raised. Check callback {callback_name} and it\'s return values for service_id {service_id} and data_id {data_id}'.format(lp=self.__log_prefix__(), callback_name=callback.__name__, service_id=repr(msg.get_service_id()), data_id=repr(msg.get_data_id())))
logger.error('{lp} Exception raised. Check callback {callback_name} and it\'s return values for service_id {service_id} and data_id {data_id}'.format(lp=self.__log_prefix__(), callback_name=callback.__name__, service_id=repr(msg.get_service_id()), data_id=repr(msg.get_data_id())))
status = STATUS_CALLBACK_ERROR
data = None
else:
@ -498,11 +512,14 @@ class pure_json_protocol(object):
self.logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__ + '.' + channel_name)
def __log_prefix__(self):
return 'SP client:' if self.__comm_inst__.IS_CLIENT else 'SP server:'
return 'prot-client:' if self.__comm_inst__.IS_CLIENT else 'prot-server:'
def __mk_msg__(self, status, service_id, data_id, data):
return data_storage({data_storage.KEY_DATA_ID: data_id, data_storage.KEY_SERVICE_ID: service_id, data_storage.KEY_STATUS: status, data_storage.KEY_DATA: data})
def __status_log_lvl__(self, status):
return STATUS_LOG_LVL.get(status, logging.CRITICAL)
def add_data(self, service_id, data_id, name):
"""
Method to add a name for a specific message.
@ -711,23 +728,19 @@ class pure_json_protocol(object):
:rtype: bool
"""
if (self.check_authentification_state() or not self.__authentification_required__(service_id, data_id)) or (service_id in self.__sid_response_dict__.values() and status == STATUS_AUTH_REQUIRED and data is None):
self.logger.info(
'%s TX <- %s, %s, data: "%s"',
self.__log_prefix__(),
self.__get_message_name__(service_id, data_id),
self.__get_status_name__(status),
repr(data)
)
return self.__comm_inst__.send(self.__build_frame__(service_id, data_id, data, status), timeout=timeout, log_lvl=logging.DEBUG)
msg = data_storage(service_id=service_id, data_id=data_id, data=data, status=status)
self.__log_msg__(msg, 'TX ->')
return self.__comm_inst__.send(self.__build_frame__(msg), timeout=timeout)
else:
# Authentification required
self.logger.warning("%s TX -> Authentification is required. Message %s, %s, data: %s will be ignored.", self.__log_prefix__(), self.__get_message_name__(service_id, data_id), self.__get_status_name__(status), repr(data))
self.logger.warning("%s Authentification is required. TX-Message %s, %s, data: %s will be ignored.", self.__log_prefix__(), self.__get_message_name__(service_id, data_id), self.__get_status_name__(status), repr(data))
return False
class struct_json_protocol(pure_json_protocol):
"""
This Class has the same functionality like :class:`pure_json_protocol`. The message length is less than for :class:`pure_json_protocol`, but the functionality and compatibility is reduced.
See also parent :py:class:`pure_json_protocol`.
.. note::
This class is depreceated and here for compatibility reasons (to support old clients or servers). Usage of :class:`pure_json_protocol` is recommended.
@ -743,13 +756,13 @@ class struct_json_protocol(pure_json_protocol):
data = json.loads(frame[12:-1])
return self.__mk_msg__(status, service_id, data_id, data)
def __build_frame__(self, service_id, data_id, data, status=STATUS_OKAY):
frame = struct.pack('>III', status, service_id, data_id)
def __build_frame__(self, msg):
frame = struct.pack('>III', msg.get_status(), msg.get_service_id(), msg.get_data_id())
if sys.version_info >= (3, 0):
frame += bytes(json.dumps(data), 'utf-8')
frame += bytes(json.dumps(msg.get_data()), 'utf-8')
frame += self.__calc_chksum__(frame)
else:
frame += json.dumps(data)
frame += json.dumps(msg.get_data())
frame += self.__calc_chksum__(frame)
return frame

View File

@ -302,6 +302,8 @@
<li><a href="index.html#socket_protocol.STATUS_CALLBACK_ERROR">STATUS_CALLBACK_ERROR (in module socket_protocol)</a>
</li>
<li><a href="index.html#socket_protocol.STATUS_CHECKSUM_ERROR">STATUS_CHECKSUM_ERROR (in module socket_protocol)</a>
</li>
<li><a href="index.html#socket_protocol.STATUS_LOG_LVL">STATUS_LOG_LVL (in module socket_protocol)</a>
</li>
<li><a href="index.html#socket_protocol.STATUS_OKAY">STATUS_OKAY (in module socket_protocol)</a>
</li>

View File

@ -321,6 +321,12 @@
<dd><p>Status for checksum error</p>
</dd></dl>
<dl class="data">
<dt id="socket_protocol.STATUS_LOG_LVL">
<code class="descclassname">socket_protocol.</code><code class="descname">STATUS_LOG_LVL</code><em class="property"> = {0: 20, 1: 30, 2: 40, 3: 30, 4: 40, 5: 40, 6: 30}</em><a class="headerlink" href="#socket_protocol.STATUS_LOG_LVL" title="Permalink to this definition"></a></dt>
<dd><p>Status depending log level for messages</p>
</dd></dl>
<dl class="data">
<dt id="socket_protocol.STATUS_OKAY">
<code class="descclassname">socket_protocol.</code><code class="descname">STATUS_OKAY</code><em class="property"> = 0</em><a class="headerlink" href="#socket_protocol.STATUS_OKAY" title="Permalink to this definition"></a></dt>
@ -724,7 +730,8 @@ If a message hitting these parameters has been received, the callback will be ex
<dl class="class">
<dt id="socket_protocol.struct_json_protocol">
<em class="property">class </em><code class="descclassname">socket_protocol.</code><code class="descname">struct_json_protocol</code><span class="sig-paren">(</span><em>*args</em>, <em>**kwargs</em><span class="sig-paren">)</span><a class="headerlink" href="#socket_protocol.struct_json_protocol" title="Permalink to this definition"></a></dt>
<dd><p>This Class has the same functionality like <a class="reference internal" href="#socket_protocol.pure_json_protocol" title="socket_protocol.pure_json_protocol"><code class="xref py py-class docutils literal notranslate"><span class="pre">pure_json_protocol</span></code></a>. The message length is less than for <a class="reference internal" href="#socket_protocol.pure_json_protocol" title="socket_protocol.pure_json_protocol"><code class="xref py py-class docutils literal notranslate"><span class="pre">pure_json_protocol</span></code></a>, but the functionality and compatibility is reduced.</p>
<dd><p>This Class has the same functionality like <a class="reference internal" href="#socket_protocol.pure_json_protocol" title="socket_protocol.pure_json_protocol"><code class="xref py py-class docutils literal notranslate"><span class="pre">pure_json_protocol</span></code></a>. The message length is less than for <a class="reference internal" href="#socket_protocol.pure_json_protocol" title="socket_protocol.pure_json_protocol"><code class="xref py py-class docutils literal notranslate"><span class="pre">pure_json_protocol</span></code></a>, but the functionality and compatibility is reduced.
See also parent <a class="reference internal" href="#socket_protocol.pure_json_protocol" title="socket_protocol.pure_json_protocol"><code class="xref py py-class docutils literal notranslate"><span class="pre">pure_json_protocol</span></code></a>.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">This class is depreceated and here for compatibility reasons (to support old clients or servers). Usage of <a class="reference internal" href="#socket_protocol.pure_json_protocol" title="socket_protocol.pure_json_protocol"><code class="xref py py-class docutils literal notranslate"><span class="pre">pure_json_protocol</span></code></a> is recommended.</p>

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

Binary file not shown.