naeural-client 2.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- naeural_client/__init__.py +13 -0
- naeural_client/_ver.py +13 -0
- naeural_client/base/__init__.py +6 -0
- naeural_client/base/distributed_custom_code_presets.py +44 -0
- naeural_client/base/generic_session.py +1763 -0
- naeural_client/base/instance.py +616 -0
- naeural_client/base/payload/__init__.py +1 -0
- naeural_client/base/payload/payload.py +66 -0
- naeural_client/base/pipeline.py +1499 -0
- naeural_client/base/plugin_template.py +5209 -0
- naeural_client/base/responses.py +209 -0
- naeural_client/base/transaction.py +157 -0
- naeural_client/base_decentra_object.py +143 -0
- naeural_client/bc/__init__.py +3 -0
- naeural_client/bc/base.py +1046 -0
- naeural_client/bc/chain.py +0 -0
- naeural_client/bc/ec.py +324 -0
- naeural_client/certs/__init__.py +0 -0
- naeural_client/certs/r9092118.ala.eu-central-1.emqxsl.com.crt +22 -0
- naeural_client/code_cheker/__init__.py +1 -0
- naeural_client/code_cheker/base.py +520 -0
- naeural_client/code_cheker/checker.py +294 -0
- naeural_client/comm/__init__.py +2 -0
- naeural_client/comm/amqp_wrapper.py +338 -0
- naeural_client/comm/mqtt_wrapper.py +539 -0
- naeural_client/const/README.md +3 -0
- naeural_client/const/__init__.py +9 -0
- naeural_client/const/base.py +101 -0
- naeural_client/const/comms.py +80 -0
- naeural_client/const/environment.py +26 -0
- naeural_client/const/formatter.py +7 -0
- naeural_client/const/heartbeat.py +111 -0
- naeural_client/const/misc.py +20 -0
- naeural_client/const/payload.py +190 -0
- naeural_client/default/__init__.py +1 -0
- naeural_client/default/instance/__init__.py +4 -0
- naeural_client/default/instance/chain_dist_custom_job_01_plugin.py +54 -0
- naeural_client/default/instance/custom_web_app_01_plugin.py +118 -0
- naeural_client/default/instance/net_mon_01_plugin.py +45 -0
- naeural_client/default/instance/view_scene_01_plugin.py +28 -0
- naeural_client/default/session/mqtt_session.py +72 -0
- naeural_client/io_formatter/__init__.py +2 -0
- naeural_client/io_formatter/base/__init__.py +1 -0
- naeural_client/io_formatter/base/base_formatter.py +80 -0
- naeural_client/io_formatter/default/__init__.py +3 -0
- naeural_client/io_formatter/default/a_dummy.py +51 -0
- naeural_client/io_formatter/default/aixp1.py +113 -0
- naeural_client/io_formatter/default/default.py +22 -0
- naeural_client/io_formatter/io_formatter_manager.py +96 -0
- naeural_client/logging/__init__.py +1 -0
- naeural_client/logging/base_logger.py +2056 -0
- naeural_client/logging/logger_mixins/__init__.py +12 -0
- naeural_client/logging/logger_mixins/class_instance_mixin.py +92 -0
- naeural_client/logging/logger_mixins/computer_vision_mixin.py +443 -0
- naeural_client/logging/logger_mixins/datetime_mixin.py +344 -0
- naeural_client/logging/logger_mixins/download_mixin.py +421 -0
- naeural_client/logging/logger_mixins/general_serialization_mixin.py +242 -0
- naeural_client/logging/logger_mixins/json_serialization_mixin.py +481 -0
- naeural_client/logging/logger_mixins/pickle_serialization_mixin.py +301 -0
- naeural_client/logging/logger_mixins/process_mixin.py +63 -0
- naeural_client/logging/logger_mixins/resource_size_mixin.py +81 -0
- naeural_client/logging/logger_mixins/timers_mixin.py +501 -0
- naeural_client/logging/logger_mixins/upload_mixin.py +260 -0
- naeural_client/logging/logger_mixins/utils_mixin.py +675 -0
- naeural_client/logging/small_logger.py +93 -0
- naeural_client/logging/tzlocal/__init__.py +20 -0
- naeural_client/logging/tzlocal/unix.py +231 -0
- naeural_client/logging/tzlocal/utils.py +113 -0
- naeural_client/logging/tzlocal/win32.py +151 -0
- naeural_client/logging/tzlocal/windows_tz.py +718 -0
- naeural_client/plugins_manager_mixin.py +273 -0
- naeural_client/utils/__init__.py +2 -0
- naeural_client/utils/comm_utils.py +44 -0
- naeural_client/utils/dotenv.py +75 -0
- naeural_client-2.0.0.dist-info/METADATA +365 -0
- naeural_client-2.0.0.dist-info/RECORD +78 -0
- naeural_client-2.0.0.dist-info/WHEEL +4 -0
- naeural_client-2.0.0.dist-info/licenses/LICENSE +201 -0
@@ -0,0 +1,72 @@
|
|
1
|
+
import json
|
2
|
+
|
3
|
+
from ...base import GenericSession
|
4
|
+
from ...comm import MQTTWrapper
|
5
|
+
from ...const import comms as comm_ct
|
6
|
+
|
7
|
+
|
8
|
+
class MqttSession(GenericSession):
|
9
|
+
def startup(self):
|
10
|
+
self._default_communicator = MQTTWrapper(
|
11
|
+
log=self.log,
|
12
|
+
config=self._config,
|
13
|
+
send_channel_name=comm_ct.COMMUNICATION_CONFIG_CHANNEL,
|
14
|
+
recv_channel_name=comm_ct.COMMUNICATION_PAYLOADS_CHANNEL,
|
15
|
+
comm_type=comm_ct.COMMUNICATION_DEFAULT,
|
16
|
+
recv_buff=self._payload_messages,
|
17
|
+
connection_name=self.name,
|
18
|
+
verbosity=self._verbosity,
|
19
|
+
)
|
20
|
+
|
21
|
+
self._heartbeats_communicator = MQTTWrapper(
|
22
|
+
log=self.log,
|
23
|
+
config=self._config,
|
24
|
+
recv_channel_name=comm_ct.COMMUNICATION_CTRL_CHANNEL,
|
25
|
+
comm_type=comm_ct.COMMUNICATION_HEARTBEATS,
|
26
|
+
recv_buff=self._hb_messages,
|
27
|
+
connection_name=self.name,
|
28
|
+
verbosity=self._verbosity,
|
29
|
+
)
|
30
|
+
|
31
|
+
self._notifications_communicator = MQTTWrapper(
|
32
|
+
log=self.log,
|
33
|
+
config=self._config,
|
34
|
+
recv_channel_name=comm_ct.COMMUNICATION_NOTIF_CHANNEL,
|
35
|
+
comm_type=comm_ct.COMMUNICATION_NOTIFICATIONS,
|
36
|
+
recv_buff=self._notif_messages,
|
37
|
+
connection_name=self.name,
|
38
|
+
verbosity=self._verbosity,
|
39
|
+
)
|
40
|
+
return super(MqttSession, self).startup()
|
41
|
+
|
42
|
+
@property
|
43
|
+
def _connected(self):
|
44
|
+
"""
|
45
|
+
Check if the session is connected to the communication server.
|
46
|
+
"""
|
47
|
+
return self._default_communicator.connected and self._heartbeats_communicator.connected and self._notifications_communicator.connected
|
48
|
+
|
49
|
+
def _connect(self) -> None:
|
50
|
+
if self._default_communicator.connection is None:
|
51
|
+
self._default_communicator.server_connect()
|
52
|
+
self._default_communicator.subscribe()
|
53
|
+
if self._heartbeats_communicator.connection is None:
|
54
|
+
self._heartbeats_communicator.server_connect()
|
55
|
+
self._heartbeats_communicator.subscribe()
|
56
|
+
if self._notifications_communicator.connection is None:
|
57
|
+
self._notifications_communicator.server_connect()
|
58
|
+
self._notifications_communicator.subscribe()
|
59
|
+
return
|
60
|
+
|
61
|
+
def _communication_close(self, **kwargs):
|
62
|
+
self._default_communicator.release()
|
63
|
+
self._heartbeats_communicator.release()
|
64
|
+
self._notifications_communicator.release()
|
65
|
+
return
|
66
|
+
|
67
|
+
def _send_payload(self, to, msg):
|
68
|
+
payload = json.dumps(msg)
|
69
|
+
|
70
|
+
self._default_communicator._send_to = to
|
71
|
+
self._default_communicator.send(payload)
|
72
|
+
return
|
@@ -0,0 +1 @@
|
|
1
|
+
from .base_formatter import BaseFormatter
|
@@ -0,0 +1,80 @@
|
|
1
|
+
import traceback
|
2
|
+
from time import time
|
3
|
+
|
4
|
+
from ...const import PAYLOAD_DATA
|
5
|
+
|
6
|
+
|
7
|
+
class BaseFormatter(object):
|
8
|
+
|
9
|
+
def __init__(self, log, signature, **kwargs):
|
10
|
+
self.signature = signature
|
11
|
+
self.log = log
|
12
|
+
super(BaseFormatter, self).__init__()
|
13
|
+
return
|
14
|
+
|
15
|
+
def P(self, *args, **kwargs):
|
16
|
+
return self.log.P(*args, **kwargs)
|
17
|
+
|
18
|
+
def _decode_streams(self, dct_config_streams):
|
19
|
+
"""
|
20
|
+
Maybe implement
|
21
|
+
"""
|
22
|
+
return dct_config_streams
|
23
|
+
|
24
|
+
def _encode_output(self, output):
|
25
|
+
"""
|
26
|
+
Maybe implement
|
27
|
+
"""
|
28
|
+
return output
|
29
|
+
|
30
|
+
def _decode_output(self, encoded_output):
|
31
|
+
"""
|
32
|
+
Maybe implement
|
33
|
+
"""
|
34
|
+
return encoded_output
|
35
|
+
|
36
|
+
def decode_streams(self, dct_config_streams):
|
37
|
+
try:
|
38
|
+
dct_config_streams = self._decode_streams(dct_config_streams)
|
39
|
+
except Exception as e:
|
40
|
+
dct_config_streams = {}
|
41
|
+
msg = "ERROR! Could not decode streams!\n{}".format(e)
|
42
|
+
self.P(msg)
|
43
|
+
self.P(traceback.format_exc(), color='r')
|
44
|
+
|
45
|
+
return dct_config_streams
|
46
|
+
|
47
|
+
def encode_output(self, output):
|
48
|
+
tm = time()
|
49
|
+
self.log.start_timer('encode', section='Formatter_' + str(self.signature))
|
50
|
+
try:
|
51
|
+
encoded_output = self._encode_output(output)
|
52
|
+
except Exception as e:
|
53
|
+
encoded_output = {}
|
54
|
+
msg = "ERROR! Could not encode output {}\n{}".format(output, e)
|
55
|
+
self.P(msg)
|
56
|
+
self.P(traceback.format_exc(), color='r')
|
57
|
+
# end try-except
|
58
|
+
|
59
|
+
elapsed = time() - tm
|
60
|
+
self.log.stop_timer('encode', section='Formatter_' + str(self.signature))
|
61
|
+
return encoded_output, elapsed
|
62
|
+
|
63
|
+
def decode_output(self, encoded_output):
|
64
|
+
ee_impl = encoded_output.get(PAYLOAD_DATA.EE_FORMATTER, encoded_output.get(PAYLOAD_DATA.SB_IMPLEMENTATION, None))
|
65
|
+
if ee_impl is None or (isinstance(ee_impl, str) and ee_impl.lower() != self.signature.lower()):
|
66
|
+
return encoded_output
|
67
|
+
|
68
|
+
self.log.start_timer('decode', section='Formatter_' + str(self.signature))
|
69
|
+
try:
|
70
|
+
output = self._decode_output(encoded_output)
|
71
|
+
except Exception as e:
|
72
|
+
output = {}
|
73
|
+
msg = "ERROR! Could not decode {}\n{}".format(encoded_output, e)
|
74
|
+
self.P(msg)
|
75
|
+
self.P(traceback.format_exc(), color='r')
|
76
|
+
# end try-except
|
77
|
+
self.log.stop_timer('decode', section='Formatter_' + str(self.signature))
|
78
|
+
if isinstance(output, dict):
|
79
|
+
output[PAYLOAD_DATA.EE_FORMATTER] = ee_impl
|
80
|
+
return output
|
@@ -0,0 +1,51 @@
|
|
1
|
+
|
2
|
+
from ...io_formatter.base import BaseFormatter
|
3
|
+
import re
|
4
|
+
|
5
|
+
|
6
|
+
def camel_to_upper_snake(name):
|
7
|
+
name = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name)
|
8
|
+
return re.sub('([a-z0-9])([A-Z])', r'\1_\2', name).upper()
|
9
|
+
|
10
|
+
|
11
|
+
def snake_to_camel(name):
|
12
|
+
name = name.lower()
|
13
|
+
|
14
|
+
words = []
|
15
|
+
for i, x in enumerate(name.split('_')):
|
16
|
+
if i > 0:
|
17
|
+
words.append(x.title())
|
18
|
+
else:
|
19
|
+
words.append(x)
|
20
|
+
|
21
|
+
return ''.join(words)
|
22
|
+
|
23
|
+
|
24
|
+
class ADummyFormatter(BaseFormatter):
|
25
|
+
|
26
|
+
def __init__(self, **kwargs):
|
27
|
+
super(ADummyFormatter, self).__init__(**kwargs)
|
28
|
+
return
|
29
|
+
|
30
|
+
def _decode_streams(self, dct_config_streams):
|
31
|
+
return dct_config_streams
|
32
|
+
|
33
|
+
def _encode_output(self, output):
|
34
|
+
# transforms the first level keys to camelCase
|
35
|
+
new_output = {}
|
36
|
+
|
37
|
+
for k, v in output.items():
|
38
|
+
k_camel_case = snake_to_camel(k)
|
39
|
+
new_output[k_camel_case] = v
|
40
|
+
|
41
|
+
return new_output
|
42
|
+
|
43
|
+
def _decode_output(self, encoded_output):
|
44
|
+
# it is used mainly for map-reduce jobs in reduce phase!
|
45
|
+
decoded_output = {}
|
46
|
+
|
47
|
+
for k, v in encoded_output.items():
|
48
|
+
k_snake_case = camel_to_upper_snake(k)
|
49
|
+
decoded_output[k_snake_case] = v
|
50
|
+
|
51
|
+
return decoded_output
|
@@ -0,0 +1,113 @@
|
|
1
|
+
# local dependencies
|
2
|
+
from ...io_formatter.base import BaseFormatter
|
3
|
+
|
4
|
+
|
5
|
+
class Aixp1Formatter(BaseFormatter):
|
6
|
+
|
7
|
+
def __init__(self, log, **kwargs):
|
8
|
+
super(Aixp1Formatter, self).__init__(
|
9
|
+
log=log, prefix_log='[INV-FORM]', **kwargs)
|
10
|
+
return
|
11
|
+
|
12
|
+
def startup(self):
|
13
|
+
pass
|
14
|
+
|
15
|
+
def _encode_output(self, output):
|
16
|
+
event_type = output.pop('EE_EVENT_TYPE', None)
|
17
|
+
|
18
|
+
# below fields are not required as they will be decorated post-formatting anyway
|
19
|
+
output.pop('EE_MESSAGE_ID', None)
|
20
|
+
output.pop('EE_MESSAGE_SEQ', None)
|
21
|
+
output.pop('EE_TOTAL_MESSAGES', None)
|
22
|
+
|
23
|
+
output.pop('EE_TIMESTAMP', None)
|
24
|
+
output.pop('EE_ID', None)
|
25
|
+
output.pop('STREAM_NAME', None)
|
26
|
+
output.pop('SIGNATURE', None)
|
27
|
+
output.pop('INSTANCE_ID', None)
|
28
|
+
|
29
|
+
output.pop('EE_TIMEZONE', None)
|
30
|
+
output.pop('EE_VERSION', None)
|
31
|
+
output.pop('EE_TZ', None)
|
32
|
+
|
33
|
+
output.pop('INITIATOR_ID', None)
|
34
|
+
output.pop('SESSION_ID', None)
|
35
|
+
# end non-managed fields
|
36
|
+
|
37
|
+
lvl_0_dct = {
|
38
|
+
"DATA": {
|
39
|
+
},
|
40
|
+
}
|
41
|
+
|
42
|
+
lvl_1_dct = lvl_0_dct['DATA']
|
43
|
+
|
44
|
+
if event_type == 'PAYLOAD':
|
45
|
+
# add payload context
|
46
|
+
output.pop('STREAM')
|
47
|
+
output.pop('PIPELINE')
|
48
|
+
|
49
|
+
# Plugin meta
|
50
|
+
if True:
|
51
|
+
lvl_1_dct['PLUGIN_META'] = {}
|
52
|
+
plugin_meta_keys = [k for k in output.keys() if k.startswith('_P_')]
|
53
|
+
for k in plugin_meta_keys:
|
54
|
+
lvl_1_dct['PLUGIN_META'][k] = output.pop(k, None)
|
55
|
+
# end for
|
56
|
+
|
57
|
+
# Pipeline meta
|
58
|
+
if True:
|
59
|
+
lvl_1_dct['PIPELINE_META'] = {}
|
60
|
+
pipeline_meta_keys = [k for k in output.keys() if k.startswith('_C_')]
|
61
|
+
for k in pipeline_meta_keys:
|
62
|
+
lvl_1_dct['PIPELINE_META'][k] = output.pop(k, None)
|
63
|
+
# end for
|
64
|
+
|
65
|
+
# endif payload
|
66
|
+
|
67
|
+
for k, v in output.items():
|
68
|
+
lvl_1_dct[k] = v
|
69
|
+
|
70
|
+
return lvl_0_dct
|
71
|
+
|
72
|
+
def _decode_output(self, encoded_output):
|
73
|
+
# Pop the unimportant stuff
|
74
|
+
encoded_output.get('EE_FORMATTER', None)
|
75
|
+
|
76
|
+
node_id, pipeline, signature, instance_id = encoded_output.get('EE_PAYLOAD_PATH', [None, None, None, None])
|
77
|
+
|
78
|
+
encoded_output['EE_ID'] = node_id
|
79
|
+
|
80
|
+
if encoded_output['EE_EVENT_TYPE'] != 'HEARTBEAT':
|
81
|
+
encoded_output['STREAM_NAME'] = pipeline
|
82
|
+
|
83
|
+
if pipeline is not None:
|
84
|
+
encoded_output['SIGNATURE'] = signature
|
85
|
+
|
86
|
+
if instance_id is not None:
|
87
|
+
encoded_output['INSTANCE_ID'] = instance_id
|
88
|
+
|
89
|
+
lvl_1_dct = encoded_output.pop('DATA')
|
90
|
+
if encoded_output['EE_EVENT_TYPE'] == 'PAYLOAD':
|
91
|
+
encoded_output['STREAM'] = pipeline
|
92
|
+
encoded_output['PIPELINE'] = pipeline
|
93
|
+
|
94
|
+
# Plugin meta
|
95
|
+
plugin_meta = lvl_1_dct.pop('PLUGIN_META', {}) or {}
|
96
|
+
for k, v in plugin_meta.items():
|
97
|
+
encoded_output[k] = v
|
98
|
+
|
99
|
+
# Pipeline meta
|
100
|
+
pipeline_meta = lvl_1_dct.pop('PIPELINE_META', {}) or {}
|
101
|
+
for k, v in pipeline_meta.items():
|
102
|
+
encoded_output[k] = v
|
103
|
+
|
104
|
+
encoded_output['PLUGIN_CATEGORY'] = 'general'
|
105
|
+
a = 1
|
106
|
+
|
107
|
+
for k, v in lvl_1_dct.items():
|
108
|
+
encoded_output[k] = v
|
109
|
+
|
110
|
+
return encoded_output
|
111
|
+
|
112
|
+
def _decode_streams(self, dct_config_streams):
|
113
|
+
return dct_config_streams
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# local dependencies
|
2
|
+
from ...io_formatter.base import BaseFormatter
|
3
|
+
|
4
|
+
|
5
|
+
class DefaultFormatter(BaseFormatter):
|
6
|
+
|
7
|
+
def __init__(self, log, **kwargs):
|
8
|
+
super(DefaultFormatter, self).__init__(
|
9
|
+
log=log, prefix_log='[DEFAULT-FMT]', **kwargs)
|
10
|
+
return
|
11
|
+
|
12
|
+
def startup(self):
|
13
|
+
pass
|
14
|
+
|
15
|
+
def _encode_output(self, output):
|
16
|
+
return output
|
17
|
+
|
18
|
+
def _decode_output(self, encoded_output):
|
19
|
+
return encoded_output
|
20
|
+
|
21
|
+
def _decode_streams(self, dct_config_streams):
|
22
|
+
return dct_config_streams
|
@@ -0,0 +1,96 @@
|
|
1
|
+
from time import time
|
2
|
+
|
3
|
+
from ..plugins_manager_mixin import _PluginsManagerMixin
|
4
|
+
from ..const import PAYLOAD_DATA
|
5
|
+
from ..io_formatter.default import Aixp1Formatter, DefaultFormatter
|
6
|
+
|
7
|
+
|
8
|
+
class IOFormatterWrapper(_PluginsManagerMixin):
|
9
|
+
FORMATTER_CLASSES = [DefaultFormatter, Aixp1Formatter]
|
10
|
+
|
11
|
+
def __init__(self, log, plugin_search_locations=['plugins.io_formatters'], plugin_search_suffix='Formatter', **kwargs):
|
12
|
+
super(IOFormatterWrapper, self).__init__()
|
13
|
+
self._dct_formatters = {}
|
14
|
+
self.log = log
|
15
|
+
self.plugin_search_locations = plugin_search_locations
|
16
|
+
self.plugin_search_suffix = plugin_search_suffix
|
17
|
+
|
18
|
+
self._last_search_invalid_formatter = {}
|
19
|
+
|
20
|
+
self.__init_formatters()
|
21
|
+
return
|
22
|
+
|
23
|
+
def __init_formatters(self):
|
24
|
+
formatter_names_and_classes = [(cls.__name__.lower().split('formatter')[0], cls) for cls in self.FORMATTER_CLASSES]
|
25
|
+
for formatter_name, formatter_class in formatter_names_and_classes:
|
26
|
+
try:
|
27
|
+
self._dct_formatters[formatter_name] = formatter_class(log=self.log, signature=formatter_name)
|
28
|
+
self.D("Successfully created IO formatter {}.".format(formatter_name))
|
29
|
+
except Exception as exc:
|
30
|
+
msg = "Exception '{}' when initializing io_formatter plugin {}".format(exc, formatter_name)
|
31
|
+
self.P(msg, color='r')
|
32
|
+
|
33
|
+
return
|
34
|
+
|
35
|
+
def _get_formatter_name_from_payload(self, msg):
|
36
|
+
return msg.get(PAYLOAD_DATA.EE_FORMATTER, msg.get(PAYLOAD_DATA.SB_IMPLEMENTATION, ''))
|
37
|
+
|
38
|
+
def _get_plugin_class(self, name):
|
39
|
+
_module_name, _class_name, _class_def, _class_config = self._get_module_name_and_class(
|
40
|
+
locations=self.plugin_search_locations,
|
41
|
+
name=name,
|
42
|
+
suffix=self.plugin_search_suffix,
|
43
|
+
safe_locations=[],
|
44
|
+
)
|
45
|
+
|
46
|
+
if _class_def is None:
|
47
|
+
msg = "Error loading io_formatter plugin '{}'".format(name)
|
48
|
+
self.D(msg, color='r')
|
49
|
+
return _class_def
|
50
|
+
|
51
|
+
def formatter_ready(self, name):
|
52
|
+
return name in self._dct_formatters or name is None or name == ''
|
53
|
+
|
54
|
+
def get_formatter_by_name(self, name):
|
55
|
+
return self._create_formatter(name)
|
56
|
+
|
57
|
+
def _create_formatter(self, name):
|
58
|
+
# TODO: change name to maybe_create_formatter
|
59
|
+
if name is None or name == '':
|
60
|
+
# check if we want to create a default formatter
|
61
|
+
return self._dct_formatters['default']
|
62
|
+
|
63
|
+
if name in self._dct_formatters:
|
64
|
+
# formatter already created
|
65
|
+
if self._dct_formatters[name] is None:
|
66
|
+
# formatter is not available
|
67
|
+
if name not in self._last_search_invalid_formatter:
|
68
|
+
self._last_search_invalid_formatter[name] = 0
|
69
|
+
if time() - self._last_search_invalid_formatter[name] < 10 * 60:
|
70
|
+
return self._dct_formatters[name]
|
71
|
+
else:
|
72
|
+
return self._dct_formatters[name]
|
73
|
+
# end if name in self._dct_formatters
|
74
|
+
|
75
|
+
self.D("Creating formatter '{}'".format(name))
|
76
|
+
_cls = self._get_plugin_class(name)
|
77
|
+
|
78
|
+
formatter = None
|
79
|
+
|
80
|
+
if _cls is not None:
|
81
|
+
formatter = _cls(log=self.log, signature=name.lower())
|
82
|
+
self.D("Successfully created IO formatter {}.".format(name))
|
83
|
+
else:
|
84
|
+
self._last_search_invalid_formatter[name] = time()
|
85
|
+
self._dct_formatters[name] = formatter
|
86
|
+
return formatter
|
87
|
+
|
88
|
+
def get_required_formatter_from_payload(self, payload):
|
89
|
+
name = self._get_formatter_name_from_payload(payload)
|
90
|
+
return self._create_formatter(name)
|
91
|
+
|
92
|
+
def D(self, *args, **kwargs):
|
93
|
+
return self.log.D(*args, **kwargs)
|
94
|
+
|
95
|
+
def P(self, *args, **kwargs):
|
96
|
+
return self.log.P(*args, **kwargs)
|
@@ -0,0 +1 @@
|
|
1
|
+
from .small_logger import Logger
|