def init(cls, component: str, source: str): """ Set the Event Message context Parameters: component Component that generates the IEM. For e.g. 'S3', 'SSPL' source Single character that indicates the type of component. For e.g. H-Hardware, S-Software, F-Firmware, O-OS """ cls._component = component cls._source = source try: Conf.load('cluster', cls._conf_file, skip_reload=True) ids = Conf.get('cluster', 'server_node') cls._site_id = ids['site_id'] cls._rack_id = ids['rack_id'] cls._node_id = ids['node_id'] cls._cluster_id = ids['cluster_id'] except Exception as e: raise EventMessageError(errno.EINVAL, "Invalid config in %s. %s", \ cls._conf_file, e) if cls._component is None: raise EventMessageError(errno.EINVAL, "Invalid component type: %s", \ cls._component) if cls._source not in cls._SOURCE.keys(): raise EventMessageError(errno.EINVAL, "Invalid source type: %s", \ cls._source) cls._producer = MessageProducer(producer_id='event_producer', \ message_type='IEM', method='sync')
def init(cls, component: str, source: str, cluster_id: str, \ message_server_endpoints: str, **message_server_kwargs): """ Set the Event Message context Parameters: component Component that generates the IEM. For e.g. 'S3', 'SSPL' source Single character that indicates the type of component. For e.g. H-Hardware, S-Software, F-Firmware, O-OS """ cls._component = component cls._source = source cls._site_id = 1 cls._rack_id = 1 cls._node_id = Conf.machine_id cls._cluster_id = cluster_id if cls._component is None: Log.error("Invalid component type: %s" % cls._component ) raise EventMessageError(errno.EINVAL, "Invalid component type: %s", \ cls._component) if cls._source not in cls._SOURCE.keys(): Log.error("Invalid source type: %s" % cls._source) raise EventMessageError(errno.EINVAL, "Invalid source type: %s", \ cls._source) MessageBus.init(message_server_endpoints, **message_server_kwargs) cls._producer = MessageProducer(producer_id='event_producer', \ message_type='IEM', method='sync') Log.info("IEM Producer initialized for component %s and source %s" % \ (cls._component, cls._source))
def init(cls, component: str, source: str): """ Set the Event Message context Parameters: component Component that generates the IEM. For e.g. 'S3', 'SSPL' source Single character that indicates the type of component. For e.g. H-Hardware, S-Software, F-Firmware, O-OS """ cls._component = component cls._source = source Conf.load('config_file', 'json:///etc/cortx/cortx.conf', skip_reload=True) # if Log.logger is already initialized by some parent process # the same file will be used to log all the messagebus related # logs, else standard iem.log will be used. if not Log.logger: LOG_DIR='/var/log' iem_log_dir = os.path.join(LOG_DIR, 'cortx/utils/iem') log_level = Conf.get('config_file', 'utils>log_level', 'INFO') Log.init('iem', iem_log_dir, level=log_level, \ backup_count=5, file_size_in_mb=5) try: Conf.load('cluster', cls._conf_file, skip_reload=True) ids = Conf.get('cluster', 'server_node') cls._site_id = ids['site_id'] cls._rack_id = ids['rack_id'] cls._node_id = ids['node_id'] cls._cluster_id = ids['cluster_id'] except Exception as e: Log.error("Invalid config in %s." % cls._conf_file) raise EventMessageError(errno.EINVAL, "Invalid config in %s. %s", \ cls._conf_file, e) if cls._component is None: Log.error("Invalid component type: %s" % cls._component ) raise EventMessageError(errno.EINVAL, "Invalid component type: %s", \ cls._component) if cls._source not in cls._SOURCE.keys(): Log.error("Invalid source type: %s" % cls._source) raise EventMessageError(errno.EINVAL, "Invalid source type: %s", \ cls._source) cls._producer = MessageProducer(producer_id='event_producer', \ message_type='IEM', method='sync') Log.info("IEM Producer initialized for component %s and source %s" % \ (cls._component, cls._source))
def receive(cls): """ Receive IEM alert message """ if cls._consumer is None: raise EventMessageError(errors.ERR_SERVICE_NOT_INITIALIZED, \ "Consumer is not subscribed") alert = cls._consumer.receive() if alert is not None: try: return json.loads(alert.decode('utf-8')) except Exception as e: raise EventMessageError( errno.EPERM, "Unable to load the json. \ %s", e) return alert
def _parse_send_args(args) -> dict: """ Maps values from cmd line args to send_args dict """ send_args = IemCli._get_empty_send_args() try: send_args['component'], send_args['module'] = args.source.split( ':') send_args['source_type'], send_args['severity'] \ = args.info.split(':') if ':' in args.contents: send_args['event_id'], send_args['message'] \ = args.contents.split(':') elif args.file: send_args['event_id'] = args.contents with open(args.file, 'r') as fd: send_args['message'] = ''.join(fd.readlines()) except ValueError: raise EventMessageError(errno.EINVAL, "Invalid send arguments!") if args.location: cluster_id, site_id, node_id, rack_id, host = \ args.location.split(':') send_args['problem_cluster_id'] = cluster_id send_args['problem_site_id'] = site_id send_args['problem_node_id'] = node_id send_args['problem_rack_id'] = rack_id send_args['problem_host'] = host return send_args
async def receive(request): Log.debug(f"Received GET request for component " \ f"{request.rel_url.query['component']}") try: component = request.rel_url.query['component'] EventMessage.subscribe(component=component) alert = EventMessage.receive() except EventMessageError as e: status_code = e.rc error_message = e.desc Log.error(f"Unable to receive event message for component: " \ f"{component}, status code: {status_code}," \ f" error: {error_message}") response_obj = {'error_code': status_code, 'exception': \ ['EventMessageError', {'message': error_message}]} except Exception as e: exception_key = type(e).__name__ exception = RestServerError(exception_key).http_error() status_code = exception[0] error_message = exception[1] Log.error(f"Internal error while receiving event messages for " \ f"component: {component}, status code: " \ f"{status_code}, error: {error_message}") response_obj = {'error_code': status_code, 'exception': \ [exception_key, {'message': error_message}]} raise EventMessageError(status_code, error_message) from e else: status_code = 200 # No exception, Success response_obj = {'alert': alert} Log.debug(f"GET method finished with status code: {status_code}" \ f"for component {component} and received event message " \ f"alert info. - {alert['iem']['info']}.") finally: return web.Response(text=json.dumps(response_obj), \ status=status_code)
def __init__(cls): try: Conf.load('cluster', cls._conf_file) ids = Conf.get('cluster', 'server_node') cls._site_id = int(ids['site_id']) cls._rack_id = int(ids['rack_id']) cls._node_id = int(ids['node_id']) except Exception as e: raise EventMessageError(errno.EINVAL, "Invalid config in %s. %s", \ cls._conf_file, e)
def receive(cls): """ Receive IEM alert message """ alert = cls._client.receive() if alert is not None: try: return json.loads(alert.decode('utf-8')) except Exception as e: raise EventMessageError(errno.EPERM, "Unable to load the json. \ %s", e) return alert
def receive(cls): """Receive IEM alert message.""" if cls._consumer is None: Log.error("IEM Consumer is not subscribed") raise EventMessageError(errors.ERR_SERVICE_NOT_INITIALIZED,\ "Consumer is not subscribed") alert = cls._consumer.receive() Log.debug("Recieved alert: %s" % alert) if alert is not None: try: return json.loads(alert.decode('utf-8')) except Exception as e: Log.error("unable to parse alert json") raise EventMessageError( errno.EPERM, "Unable to load the json. \ %s", e) return alert
def init(cls, component: str, source: str, receiver: bool = False): """ Set the Event Message context """ cls._component = component cls._source = source cls() if cls._component is None: raise EventMessageError(errno.EINVAL, "Invalid component type: %s", \ cls._component) if cls._source not in cls._SOURCE.keys(): raise EventMessageError(errno.EINVAL, "Invalid source type: %s", \ cls._source) if receiver: cls._client = MessageConsumer(consumer_id='event_consumer', \ consumer_group=cls._component, message_types=['IEM'], \ auto_ack=True, offset='earliest') else: cls._client = MessageProducer(producer_id='event_producer', \ message_type='IEM', method='sync')
def send(cls, module: str, event_id: str, severity: str, message: str, \ *params): """ Sends IEM alert message """ # Validate attributes before sending for attribute in [module, event_id, message]: if attribute is None: raise EventMessageError(errno.EINVAL, "Invalid IEM attributes \ %s", attribute) if severity not in cls._SEVERITY_LEVELS: raise EventMessageError(errno.EINVAL, "Invalid severity level: %s" \ , severity) alert = json.dumps({ 'iem': { 'version': '1', 'info': { 'severity': cls._SEVERITY_LEVELS[severity], 'type': cls._SOURCE[cls._source], 'event_time': time.time() }, 'location': { 'site_id': cls._site_id, 'node_id': cls._node_id, 'rack_id': cls._rack_id }, 'source': { 'component': cls._component, 'module': module }, 'contents': { 'event': event_id, 'message': message, 'params': params, } } }) cls._client.send([alert])
def subscribe(cls, component: str, **filters): """ Subscribe to IEM alerts Parameters: component Component that generates the IEM. For e.g. 'S3', 'SSPL' """ if component is None: raise EventMessageError(errno.EINVAL, "Invalid component type: %s", \ component) cls._consumer = MessageConsumer(consumer_id='event_consumer', \ consumer_group=component, message_types=['IEM'], \ auto_ack=True, offset='earliest')
def subscribe(cls, component: str, message_server_endpoints: str, \ **message_server_kwargs): """ Subscribe to IEM alerts Parameters: component Component that generates the IEM. For e.g. 'S3', 'SSPL' """ if component is None: Log.error("Invalid component type: %s" % component) raise EventMessageError(errno.EINVAL, "Invalid component type: %s", \ component) MessageBus.init(message_server_endpoints, **message_server_kwargs) cls._consumer = MessageConsumer(consumer_id='event_consumer', \ consumer_group=component, message_types=['IEM'], \ auto_ack=True, offset='earliest') Log.info("IEM Consumer initialized for component: %s" % component)
async def send(request): try: payload = await request.json() component = payload['component'] source = payload['source'] EventMessage.init(component=component, source=source,\ cluster_id=IemRequestHandler.cluster_id,\ message_server_endpoints=IemRequestHandler.message_server_endpoints) del payload['component'] del payload['source'] EventMessage.send(**payload) except EventMessageError as e: status_code = e.rc error_message = e.desc Log.error(f"Unable to send event message for component: " \ f"{component}, status code: {status_code}," \ f" error: {error_message}") response_obj = {'error_code': status_code, 'exception': \ ['EventMessageError', {'message': error_message}]} except Exception as e: exception_key = type(e).__name__ exception = RestServerError(exception_key).http_error() status_code = exception[0] error_message = exception[1] Log.error(f"Internal error while sending event messages for " \ f"component: {component}, status code: " \ f"{status_code}, error: {error_message}") response_obj = {'error_code': status_code, 'exception': \ [exception_key, {'message': error_message}]} raise EventMessageError(status_code, error_message) from e else: status_code = 200 # No exception, Success response_obj = {'status_code': status_code, 'status': 'success'} Log.debug(f"POST method finished for component: {component} " f"and source: {source}, with status code: {status_code}") finally: return web.Response(text=json.dumps(response_obj), \ status=status_code)
def receive(args) -> str: """ Receives IEM Message and returns to the caller, If file[-f] is passed, writes message to file and returns blank string to caller """ IemCli.subscribe(component=args.source) rec_data = '' event = ' ' while event: try: event = EventMessage.receive() rec_data += Format.dump(event, 'json') + '\n' if event else '\n' except Exception: raise EventMessageError( errno.EINVAL, "Error occurred while receiving IEM data") if args.file: with open(args.file, 'a') as fd: fd.write(rec_data) return '' return rec_data
def send(cls, module: str, event_id: str, severity: str, message_blob: str,\ problem_cluster_id: str = None, problem_site_id: int = None, \ problem_rack_id: int = None, problem_node_id: int = None, \ problem_host: str = None, event_time: float = None): """ Sends IEM alert message Parameters: module Indicates the sub module of a component that generated the IEM. i.e SSPL submodule like HPI. event_id A numerical value that uniquely identifies an event. severity The degree of impact an event has on the operation of a component. message_blob Blob alert message. problem_cluster_id A alpha numerical value that indicates cluster ID. (Problem Location) problem_site_id Uniquely identifies a single data center site. (Problem Location) problem_rack_id A numerical value that identifies a single Rack in a single site. (Problem Location) problem_node_id A numerical value that indicates node ID. (UUID) (Problem Location) problem_host A string that indicates the hostname. (Problem Location) event_time Time of the event """ import socket sender_host = socket.gethostname() cls._initiate_logger() if cls._producer is None: Log.error("IEM Producer not initialized.") raise EventMessageError(errors.ERR_SERVICE_NOT_INITIALIZED, \ "Producer is not initialised") site_id = problem_site_id if problem_site_id is not None else \ cls._site_id rack_id = problem_rack_id if problem_rack_id is not None else \ cls._rack_id node_id = problem_node_id if problem_node_id is not None else \ cls._node_id cluster_id = problem_cluster_id if problem_cluster_id is not None else \ cls._cluster_id host = problem_host if problem_host is not None else sender_host event_time = event_time if event_time is not None else time.time() Log.debug("site_id: %s, rack_id: %s, node_id: %s, cluster_id: %s,\ host: %s" % (site_id, rack_id, node_id, cluster_id, host)) # Validate attributes before sending for attribute in [module, event_id, message_blob, site_id, rack_id, \ node_id, cluster_id]: if attribute is None: Log.error("Invalid IEM attributes %s.", attribute) raise EventMessageError( errno.EINVAL, "Invalid IEM attributes \ %s", attribute) if severity not in cls._SEVERITY_LEVELS: Log.error("Invalid severity level: %s." % severity) raise EventMessageError(errno.EINVAL, "Invalid severity level: %s" \ , severity) alert = json.dumps({ 'iem': { 'version': '1', 'info': { 'severity': cls._SEVERITY_LEVELS[severity], 'type': cls._SOURCE[cls._source], 'event_time': event_time }, 'location': { 'cluster_id': cluster_id, 'site_id': site_id, 'rack_id': rack_id, 'node_id': node_id, 'host': host }, 'source': { 'site_id': cls._site_id, 'rack_id': cls._rack_id, 'node_id': cls._node_id, 'component': cls._component, 'module': module }, 'contents': { 'event': event_id, 'message': message_blob } } }) cls._producer.send([alert]) Log.debug("alert sent: %s" % alert)