openrvdas.logger.writers.sealog_writer
1#!/usr/bin/env python3 2 3import pprint 4import logging 5import urllib 6from typing import Union 7from logger.utils.das_record import DASRecord # noqa:E402 8from logger.utils.read_config import read_config # noqa:E402 9from logger.utils.sealog_event import SealogEvent, to_event # noqa:E402 10from logger.writers.writer import Writer # noqa: E402 11 12 13################################################################################ 14class SealogWriter(Writer): 15 """Submit Sealog event dicts to a Sealog Server API. 16 17 url - URL to Sealog Server, i.e. http://<ip_addr>:8000/sealog-server 18 19 token - Java Web Token (JWT) authorized to submit new events to the 20 Sealog Server API 21 22 config_file - Path to a YAML configuration file specifying: 23 `data_id` to determine which set of rules to apply 24 `event_value` (optional): default event value for the record. 25 `event_author` (optional): author string to include in the event. 26 `event_free_text` (optional): free text string for the event. 27 `field_map` (optional): mapping of input record field names to event 28 option names. 29 `_default` (optional): fallback configuration applied if the record's 30 `data_id` is not found. 31 32 Sample configuration file: 33 --- 34 qinsy: 35 event_value: LOGGING_STATUS 36 event_author: "qinsy" 37 event_free_text: "" 38 event_options: 39 system: EM124 40 field_map: 41 status: status 42 filename: filename 43 44 _default: 45 event_value: UNKNOWN 46 event_free_text: "" 47 field_map: null 48 49 50 quiet - suppress warning messages 51 52 """ 53 54 ############################ 55 def __init__(self, url: str, token: str, config_file: str, **kwargs): 56 super().__init__(**kwargs) # processes 'quiet' and type hints 57 58 self.url = url 59 self.token = token 60 61 try: 62 self.configs = read_config(config_file) 63 logging.info('Loaded sealog config file: %s', pprint.pformat(self.configs)) 64 except Exception as err: 65 logging.error("Could not find or could not process config file." 66 " All records will be ignored.") 67 logging.info(str(err)) 68 pass 69 70 self.test_api_connectivity() 71 72 ############################ 73 def test_api_connectivity(self) -> bool: 74 """ 75 Test connectivity to a restricted API route using JWT authentication 76 77 Returns: 78 bool: True if request succeeds (HTTP 200), False otherwise. 79 """ 80 req = urllib.request.Request(self.url + '/restricted') 81 req.add_header("Authorization", f"Bearer {self.token}") 82 83 try: 84 with urllib.request.urlopen(req, timeout=5) as response: 85 if response.status == 200: 86 logging.info("Connection to Sealog Server successful") 87 return True 88 else: 89 logging.error(f"Connection to Sealog Server failed: {response.status}") 90 return False 91 except urllib.error.HTTPError as e: 92 logging.error(f"HTTP error: {e.code} {e.reason}") 93 return False 94 except urllib.error.URLError as e: 95 logging.error(f"Connection error: {e.reason}") 96 return False 97 98 ############################ 99 def write(self, record: Union[DASRecord, SealogEvent, list]): 100 """Submit dicts to Sealog Server 101 Note: Assume record is a dict or list of dict. 102 """ 103 104 if isinstance(record, list): 105 for single_record in record: 106 self.write(single_record) 107 return 108 109 event = record if isinstance(record, SealogEvent) else to_event(record, self.configs) 110 111 json_data = event.as_json().encode("utf-8") 112 113 req = urllib.request.Request(self.url + '/api/v1/events', data=json_data, method="POST") 114 req.add_header("Authorization", f"Bearer {self.token}") 115 req.add_header("Content-Type", "application/json") 116 117 try: 118 with urllib.request.urlopen(req, timeout=5) as response: 119 if response.status == 201: 120 logging.debug("POST successful") 121 else: 122 logging.error(f"POST failed: {response.status}") 123 except urllib.error.HTTPError as e: 124 logging.error(f"HTTP error: {e.code} {e.reason}") 125 except urllib.error.URLError as e: 126 logging.error(f"Connection error: {e.reason}")
15class SealogWriter(Writer): 16 """Submit Sealog event dicts to a Sealog Server API. 17 18 url - URL to Sealog Server, i.e. http://<ip_addr>:8000/sealog-server 19 20 token - Java Web Token (JWT) authorized to submit new events to the 21 Sealog Server API 22 23 config_file - Path to a YAML configuration file specifying: 24 `data_id` to determine which set of rules to apply 25 `event_value` (optional): default event value for the record. 26 `event_author` (optional): author string to include in the event. 27 `event_free_text` (optional): free text string for the event. 28 `field_map` (optional): mapping of input record field names to event 29 option names. 30 `_default` (optional): fallback configuration applied if the record's 31 `data_id` is not found. 32 33 Sample configuration file: 34 --- 35 qinsy: 36 event_value: LOGGING_STATUS 37 event_author: "qinsy" 38 event_free_text: "" 39 event_options: 40 system: EM124 41 field_map: 42 status: status 43 filename: filename 44 45 _default: 46 event_value: UNKNOWN 47 event_free_text: "" 48 field_map: null 49 50 51 quiet - suppress warning messages 52 53 """ 54 55 ############################ 56 def __init__(self, url: str, token: str, config_file: str, **kwargs): 57 super().__init__(**kwargs) # processes 'quiet' and type hints 58 59 self.url = url 60 self.token = token 61 62 try: 63 self.configs = read_config(config_file) 64 logging.info('Loaded sealog config file: %s', pprint.pformat(self.configs)) 65 except Exception as err: 66 logging.error("Could not find or could not process config file." 67 " All records will be ignored.") 68 logging.info(str(err)) 69 pass 70 71 self.test_api_connectivity() 72 73 ############################ 74 def test_api_connectivity(self) -> bool: 75 """ 76 Test connectivity to a restricted API route using JWT authentication 77 78 Returns: 79 bool: True if request succeeds (HTTP 200), False otherwise. 80 """ 81 req = urllib.request.Request(self.url + '/restricted') 82 req.add_header("Authorization", f"Bearer {self.token}") 83 84 try: 85 with urllib.request.urlopen(req, timeout=5) as response: 86 if response.status == 200: 87 logging.info("Connection to Sealog Server successful") 88 return True 89 else: 90 logging.error(f"Connection to Sealog Server failed: {response.status}") 91 return False 92 except urllib.error.HTTPError as e: 93 logging.error(f"HTTP error: {e.code} {e.reason}") 94 return False 95 except urllib.error.URLError as e: 96 logging.error(f"Connection error: {e.reason}") 97 return False 98 99 ############################ 100 def write(self, record: Union[DASRecord, SealogEvent, list]): 101 """Submit dicts to Sealog Server 102 Note: Assume record is a dict or list of dict. 103 """ 104 105 if isinstance(record, list): 106 for single_record in record: 107 self.write(single_record) 108 return 109 110 event = record if isinstance(record, SealogEvent) else to_event(record, self.configs) 111 112 json_data = event.as_json().encode("utf-8") 113 114 req = urllib.request.Request(self.url + '/api/v1/events', data=json_data, method="POST") 115 req.add_header("Authorization", f"Bearer {self.token}") 116 req.add_header("Content-Type", "application/json") 117 118 try: 119 with urllib.request.urlopen(req, timeout=5) as response: 120 if response.status == 201: 121 logging.debug("POST successful") 122 else: 123 logging.error(f"POST failed: {response.status}") 124 except urllib.error.HTTPError as e: 125 logging.error(f"HTTP error: {e.code} {e.reason}") 126 except urllib.error.URLError as e: 127 logging.error(f"Connection error: {e.reason}")
Submit Sealog event dicts to a Sealog Server API.
url - URL to Sealog Server, i.e. http://
token - Java Web Token (JWT) authorized to submit new events to the Sealog Server API
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
quiet - suppress warning messages
56 def __init__(self, url: str, token: str, config_file: str, **kwargs): 57 super().__init__(**kwargs) # processes 'quiet' and type hints 58 59 self.url = url 60 self.token = token 61 62 try: 63 self.configs = read_config(config_file) 64 logging.info('Loaded sealog config file: %s', pprint.pformat(self.configs)) 65 except Exception as err: 66 logging.error("Could not find or could not process config file." 67 " All records will be ignored.") 68 logging.info(str(err)) 69 pass 70 71 self.test_api_connectivity()
Abstract base class for data Writers.
74 def test_api_connectivity(self) -> bool: 75 """ 76 Test connectivity to a restricted API route using JWT authentication 77 78 Returns: 79 bool: True if request succeeds (HTTP 200), False otherwise. 80 """ 81 req = urllib.request.Request(self.url + '/restricted') 82 req.add_header("Authorization", f"Bearer {self.token}") 83 84 try: 85 with urllib.request.urlopen(req, timeout=5) as response: 86 if response.status == 200: 87 logging.info("Connection to Sealog Server successful") 88 return True 89 else: 90 logging.error(f"Connection to Sealog Server failed: {response.status}") 91 return False 92 except urllib.error.HTTPError as e: 93 logging.error(f"HTTP error: {e.code} {e.reason}") 94 return False 95 except urllib.error.URLError as e: 96 logging.error(f"Connection error: {e.reason}") 97 return False
Test connectivity to a restricted API route using JWT authentication
Returns: bool: True if request succeeds (HTTP 200), False otherwise.
100 def write(self, record: Union[DASRecord, SealogEvent, list]): 101 """Submit dicts to Sealog Server 102 Note: Assume record is a dict or list of dict. 103 """ 104 105 if isinstance(record, list): 106 for single_record in record: 107 self.write(single_record) 108 return 109 110 event = record if isinstance(record, SealogEvent) else to_event(record, self.configs) 111 112 json_data = event.as_json().encode("utf-8") 113 114 req = urllib.request.Request(self.url + '/api/v1/events', data=json_data, method="POST") 115 req.add_header("Authorization", f"Bearer {self.token}") 116 req.add_header("Content-Type", "application/json") 117 118 try: 119 with urllib.request.urlopen(req, timeout=5) as response: 120 if response.status == 201: 121 logging.debug("POST successful") 122 else: 123 logging.error(f"POST failed: {response.status}") 124 except urllib.error.HTTPError as e: 125 logging.error(f"HTTP error: {e.code} {e.reason}") 126 except urllib.error.URLError as e: 127 logging.error(f"Connection error: {e.reason}")
Submit dicts to Sealog Server Note: Assume record is a dict or list of dict.