openrvdas.logger.transforms.to_sealog_transform
1#!/usr/bin/env python3 2 3import logging 4import pprint 5from typing import Union 6 7from logger.utils.read_config import read_config # noqa:E402 8from logger.utils.das_record import DASRecord # noqa: E402 9from logger.utils.sealog_event import SealogEvent, to_event # noqa: E402 10from logger.transforms.transform import Transform # noqa: E402 11 12 13################################################################################ 14# 15class ToSealogTransform(Transform): 16 """ 17 The class uses a YAML-formatted configuration to determine how to map input 18 data fields to Sealog event fields, and converts records accordingly. It 19 supports single records or lists of records. It also handles unknown fields 20 gracefully using a fallback mechanism. 21 22 Key behaviors: 23 - If a record's `data_id` is not found in the configuration, a fallback `_default` config is used. 24 - If `field_map` is not specified for a data_id, all fields from the record are included as event options. 25 - Any `None` values in the resulting event dictionary are automatically removed. 26 - Can process a single record or recursively handle lists of records. 27 28 config_file - Path to a YAML configuration file specifying: 29 `data_id` to determine which set of rules to apply 30 `event_value` (optional): default event value for the record. 31 `event_author` (optional): author string to include in the event. 32 `event_free_text` (optional): free text string for the event. 33 `field_map` (optional): mapping of input record field names to event option names. 34 `_default` (optional): fallback configuration applied if the record's `data_id` is not found. 35 36 Sample configuration file: 37 --- 38 qinsy: 39 event_value: LOGGING_STATUS 40 event_author: "qinsy" 41 event_free_text: "" 42 event_options: 43 system: EM124 44 field_map: 45 status: status 46 filename: filename 47 48 _default: 49 event_value: UNKNOWN 50 event_free_text: "" 51 field_map: null 52 53 """ 54 55 ############################ 56 def __init__(self, config_file: str, **kwargs): 57 super().__init__(**kwargs) # processes 'quiet' and type hints 58 59 try: 60 self.configs = read_config(config_file) 61 logging.info('Loaded sealog config file: %s', pprint.pformat(self.configs)) 62 except Exception as err: 63 logging.error("Could not find or could not process config file. All records will be ignored.") 64 pass 65 66 67 def transform(self, record: Union[DASRecord, list]) -> SealogEvent: 68 """Parse DASRecord and return Sealog event dict.""" 69 if not self.configs: 70 return None 71 72 # See if it's something we can process, and if not, try digesting 73 if not self.can_process_record(record): # inherited from BaseModule() 74 return self.digest_record(record) # inherited from BaseModule() 75 76 return to_event(record, self.configs)
16class ToSealogTransform(Transform): 17 """ 18 The class uses a YAML-formatted configuration to determine how to map input 19 data fields to Sealog event fields, and converts records accordingly. It 20 supports single records or lists of records. It also handles unknown fields 21 gracefully using a fallback mechanism. 22 23 Key behaviors: 24 - If a record's `data_id` is not found in the configuration, a fallback `_default` config is used. 25 - If `field_map` is not specified for a data_id, all fields from the record are included as event options. 26 - Any `None` values in the resulting event dictionary are automatically removed. 27 - Can process a single record or recursively handle lists of records. 28 29 config_file - Path to a YAML configuration file specifying: 30 `data_id` to determine which set of rules to apply 31 `event_value` (optional): default event value for the record. 32 `event_author` (optional): author string to include in the event. 33 `event_free_text` (optional): free text string for the event. 34 `field_map` (optional): mapping of input record field names to event option names. 35 `_default` (optional): fallback configuration applied if the record's `data_id` is not found. 36 37 Sample configuration file: 38 --- 39 qinsy: 40 event_value: LOGGING_STATUS 41 event_author: "qinsy" 42 event_free_text: "" 43 event_options: 44 system: EM124 45 field_map: 46 status: status 47 filename: filename 48 49 _default: 50 event_value: UNKNOWN 51 event_free_text: "" 52 field_map: null 53 54 """ 55 56 ############################ 57 def __init__(self, config_file: str, **kwargs): 58 super().__init__(**kwargs) # processes 'quiet' and type hints 59 60 try: 61 self.configs = read_config(config_file) 62 logging.info('Loaded sealog config file: %s', pprint.pformat(self.configs)) 63 except Exception as err: 64 logging.error("Could not find or could not process config file. All records will be ignored.") 65 pass 66 67 68 def transform(self, record: Union[DASRecord, list]) -> SealogEvent: 69 """Parse DASRecord and return Sealog event dict.""" 70 if not self.configs: 71 return None 72 73 # See if it's something we can process, and if not, try digesting 74 if not self.can_process_record(record): # inherited from BaseModule() 75 return self.digest_record(record) # inherited from BaseModule() 76 77 return to_event(record, self.configs)
The class uses a YAML-formatted configuration to determine how to map input data fields to Sealog event fields, and converts records accordingly. It supports single records or lists of records. It also handles unknown fields gracefully using a fallback mechanism.
Key behaviors:
- If a record's data_id is not found in the configuration, a fallback _default config is used.
- If field_map is not specified for a data_id, all fields from the record are included as event options.
- Any None values in the resulting event dictionary are automatically removed.
- Can process a single record or recursively handle lists of records.
config_file - Path to a YAML configuration file specifying:
data_id to determine which set of rules to apply
event_value (optional): default event value for the record.
event_author (optional): author string to include in the event.
event_free_text (optional): free text string for the event.
field_map (optional): mapping of input record field names to event option names.
_default (optional): fallback configuration applied if the record's data_id is not found.
Sample configuration file:
qinsy: event_value: LOGGING_STATUS event_author: "qinsy" event_free_text: "" event_options: system: EM124 field_map: status: status filename: filename
_default: event_value: UNKNOWN event_free_text: "" field_map: null
57 def __init__(self, config_file: str, **kwargs): 58 super().__init__(**kwargs) # processes 'quiet' and type hints 59 60 try: 61 self.configs = read_config(config_file) 62 logging.info('Loaded sealog config file: %s', pprint.pformat(self.configs)) 63 except Exception as err: 64 logging.error("Could not find or could not process config file. All records will be ignored.") 65 pass
quiet - if type checking should log type errors or operate silently.
Two additional arguments govern how records will be encoded/decoded
from bytes, if desired by the Writer subclass when it calls
_encode_str() or _decode_bytes:
encoding - 'utf-8' by default. If empty or None, do not attempt any
decoding and return raw bytes. Other possible encodings are
listed in online documentation here:
https://docs.python.org/3/library/codecs.html#standard-encodings
encoding_errors - 'ignore' by default. Other error strategies are
'strict', 'replace', and 'backslashreplace', described here:
https://docs.python.org/3/howto/unicode.html#encodings
mirror_to - Optional Writer to which all records read or transformed
by this module (if it is a Reader or Transform) will be
"mirrored" (copied). Mirroring happens asynchronously via
a queue and background thread to minimize impact on the
primary data flow. Writers cannot be mirrored.
68 def transform(self, record: Union[DASRecord, list]) -> SealogEvent: 69 """Parse DASRecord and return Sealog event dict.""" 70 if not self.configs: 71 return None 72 73 # See if it's something we can process, and if not, try digesting 74 if not self.can_process_record(record): # inherited from BaseModule() 75 return self.digest_record(record) # inherited from BaseModule() 76 77 return to_event(record, self.configs)
Parse DASRecord and return Sealog event dict.