def new_ticket(self, ticket_kind, data_dict): if not self._config['active']: return None renderer = self._new_ticket_kind_to_renderer.get(ticket_kind) if renderer is None: return None try: field_name_to_value = self._prepare_new_ticket_fields( renderer, data_dict) with self.rt_client_session() as rt: ticket_id = rt.create_ticket(**field_name_to_value) self._verify_ticket_created(ticket_id) if not isinstance(ticket_id, int): # (the `rt` library's API changed or what?!) raise TypeError( 'ticket_id={!r} is not an int'.format(ticket_id)) if ticket_id < 1: # (the `rt` library's API changed or what?!) raise ValueError( 'ticket_id={!r} is not a positive number'.format( ticket_id)) except: LOGGER.error('Could not create a new RT ticket - %s', make_exc_ascii_str()) raise else: LOGGER.info('RT ticket #%s created successfully', ticket_id) assert isinstance(ticket_id, int) and ticket_id >= 1 return ticket_id
def rt_client_session(self): # This method is made public to make it possible to operate # on an `rt.Rt` instance directly. However, if possible, it # is recommended to use other `RTClientAPI`'s public methods # rather than this one. if not self._config['active']: raise RuntimeError('RT is turn off in the configuration ' '(i.e., the `active` option is false)') rest_api_url = self._config['rest_api_url'] username = self._config['username'] try: rt = Rt(url=rest_api_url) if not rt.login(login=username, password=self._config['password']): raise RTClientAPIError('could not log in to RT') try: yield rt finally: self._try_logout(rt) except (RtError, RTClientAPIError) as exc: raise RTClientAPIError('RT-related error - {} (' 'config option {}: {!r}; ' 'config option {}: {!r})'.format( make_exc_ascii_str(exc), self._repr_opt_name('rest_api_url'), rest_api_url, self._repr_opt_name('username'), username))
def _get_adjusted_value(self, key, value): if key not in self._settable_keys: raise RuntimeError('for {!a}, key {!a} is illegal'.format( self, key)) adjuster_method_name = self._adjuster_name(key) try: adjuster = getattr(self, adjuster_method_name) except AttributeError: raise RuntimeError('{!a} has no adjuster for key {!a}'.format( self, key)) if adjuster is None: # adjuster explicitly set to None -> passing value unchanged return value try: return adjuster(value) except Exception as exc: if getattr(exc, 'propagate_it_anyway', False): raise adjuster_error_msg = ('{!a}.{}({value!a}) raised {exc_str}'.format( self, adjuster_method_name, value=value, exc_str=make_exc_ascii_str(exc))) raise AdjusterError(adjuster_error_msg)
def _log_exc(self, notice_key, context_entered, important_done, exc_suppressed=False): exc_descr = make_exc_ascii_str() msg_preamble = 'Suppressing an exception which ' if exc_suppressed else 'An exception ' if important_done: LOGGER.warning( msg_preamble + ('occurred *after* dealing with dispatch of %a ' 'mail notice(s) [problem with closing the SMTP ' 'connection?] (%s)'), notice_key, exc_descr) elif context_entered: LOGGER.error(msg_preamble + ('occurred *while* dealing with dispatch of %a mail ' 'notice(s) (%s) -- it broke the whole activity ' 'during it, so it is probable that some or all ' 'dispatch actions have not even been tried!'), notice_key, exc_descr, exc_info=exc_suppressed) else: LOGGER.error(msg_preamble + ('occurred *before* dealing with dispatch of %a mail ' 'notice(s) (%s) -- all dispatch actions must fail!'), notice_key, exc_descr, exc_info=exc_suppressed)
def _log_smtp_recipients_exc(self, recipient_problems): recipients_str = ', '.join(map(repr, sorted(recipient_problems.keys()))) exc_descr = make_exc_ascii_str() LOGGER.error( 'Suppressing a mail-recipients-related exception which ' 'signals that a %r mail notice could not be sent to ' 'any of the given recipients: %s (%s)', self._notice_key, recipients_str, exc_descr)
def _try_logout(self, rt): try: logged_out = rt.logout() except RtError as exc: LOGGER.warning('Could not log out from RT properly (%s)', make_exc_ascii_str(exc), exc_info=True) else: if not logged_out: LOGGER.warning('Could not log out from RT properly')
def _log_other_smtp_exc(self, to): exc_descr = make_exc_ascii_str() LOGGER.error( 'Suppressing an exception which signals an error which ' 'caused that a %a mail notice could not be sent [to: %a] ' '(%s)', self._notice_key, to, exc_descr, exc_info=True)
def _header_value_as_ascii_str( self, header_value): #3: remove whole method definition if header_value is None: raise ValueError( 'no header value given (got: {!r})'.format(header_value)) try: return unicode(header_value).encode('ascii') except (UnicodeError, LookupError ) as exc: # Header.__unicode__() may raise LookupError for_repr = (header_value.encode() if isinstance( header_value, Header) else header_value) exc_ascii_str = make_exc_ascii_str(exc) raise ValueError('cannot obtain the actual header value from: ' '{!r} ({})'.format(for_repr, exc_ascii_str))
def load_state(self): """ Load collector's state from cache. Returns: Unpickled object of its original type. """ try: with open(self._cache_file_path, 'rb') as cache_file: state = cPickle.load(cache_file) except (EnvironmentError, ValueError, EOFError) as exc: state = self.make_default_state() LOGGER.warning("Could not load state (%s), returning: %r", make_exc_ascii_str(exc), state) else: LOGGER.info("Loaded state: %r", state) return state
def _get_query_status_and_payload_info_dict(self, payload_filename, payload_info): try: payload_info_dict = json.loads(payload_info) query_status = payload_info_dict['query_status'] except Exception as exc: LOGGER.error( 'Skipping the payload (this time) because of weird/' 'unexpected problem with its info dict (%s). ' 'Archive filename: "%s". ' 'Payload filename: "%s".', make_exc_ascii_str(exc), self._zip_filename, payload_filename) # note: here we do *not* add `payload_filename` # to `handled_payload_filenames` -- so that # this payload remains *unhandled* raise self._PayloadInfoValidationError return query_status, payload_info_dict
def _conv_ticket_kind_to_fields_render_spec(cls, opt_value): result = {} if not opt_value: return result raw_dict = Config.BASIC_CONVERTERS['py_namespaces_dict'](opt_value) raw_items = raw_dict.items() for ticket_kind, field_to_template in raw_items: assert isinstance(ticket_kind, str) try: ticket_fields_renderer = _TicketFieldsRenderer(field_to_template) except Exception as exc: raise ValueError( 'error when trying to create RT ticket fields ' 'renderer for ticket kind {!a} - {}'.format( ticket_kind, make_exc_ascii_str(exc))) result[ticket_kind] = ticket_fields_renderer return result
def ping_connection(self): """ Required to maintain the connection to MySQL. Perform ping before each query to the database. OperationalError if an exception occurs, remove sessions, and connects again. """ try: self.session_db.execute(sqla_text("SELECT 1")) except OperationalError as exc: # OperationalError: (2006, 'MySQL server has gone away') LOGGER.warning("Database server went away: %a", exc) LOGGER.info("Reconnect to server") self.session_db.remove() try: self.session_db.execute(sqla_text("SELECT 1")) except SQLAlchemyError as exc: LOGGER.error("Could not reconnect to the MySQL database: %s", make_exc_ascii_str(exc)) sys.exit(1)
def _actual_operation(self): while True: # noinspection PyBroadException try: self._run_func() if self._future.cancelled(): break # noinspection PyBroadException try: self.loop_iteration_hook(self._future) except Exception: LOGGER.warning( '%r: suppressing exception got from ' '`loop_iteration_hook()`: %s', self, make_exc_ascii_str()) except Exception: # It is fine to silence the exception here as we # have passed it to the future so it will resurface # in the thread(s) calling the future's `result()`. break
def create_and_init_db(timeout): error_msg = 'no connection attempt made' for i in range(timeout): try: with CreateAndInitializeAuthDB( settings=prepare_auth_db_settings(), drop_db_if_exists=True, assume_yes=True, quiet=True, ) as script: script.run() except Exception as exc: error_msg = make_exc_ascii_str(exc) sleep(1) else: break else: raise RuntimeError( 'Cannot connect to database... ({})'.format(error_msg)) sleep(1)
def insert_new_event(self, items, with_transact=True, recorded=False): """ New events and new blacklist add to database, default in the transaction, or the outer transaction(with_transact=False). """ try: if with_transact: with transact: self.session_db.add_all(items) else: assert transact.is_entered self.session_db.add_all(items) except IntegrityError as exc: str_exc = make_exc_ascii_str(exc) LOGGER.warning(str_exc) else: if recorded and not self.cmdline_args.n6recovery: rk = replace_segment(self.routing_key, 1, 'recorded') LOGGER.debug( 'Publish for email notifications ' '-- rk: %a, record_dict: %a', rk, self.record_dict) self.publish_event(self.record_dict, rk)
def handle_parse_error(context_manager_error): if isinstance(context_manager_error, Exception): LOGGER.warning('Event could not be generated due to %s', make_exc_ascii_str(context_manager_error)) return True return False