def test_exception_traceback(): # Get exception from ``sys.exc_info()`` try: raise ValueError('Something reasonable') except Exception as ex: tb = exception_traceback() assert 'ValueError: Something reasonable' in tb
def processor(worker_id=None): """ Queue runner. Pull a job from the queue, find the module in charge of handling the service, and invoke the module's plugin to do so. """ while not exit_flag: logger.debug('Job queue has %s items to process' % q_in.qsize()) job = q_in.get() service = job.service section = job.section target = job.target topic = job.topic logger.debug("Processor #%s is handling: `%s' for %s" % (worker_id, service, target)) # Sanity checks. # If service configuration or targets can not be obtained successfully, # log a sensible error message, fail the job and carry on with the next job. try: service_config = context.get_service_config(service) service_targets = context.get_service_targets(service) if target not in service_targets: error_message = "Invalid configuration: Topic '{topic}' points to " \ "non-existing target '{target}' in service '{service}'".format(**locals()) raise KeyError(error_message) except Exception as ex: logger.error("Cannot handle service=%s, target=%s: %s\n%s" % (service, target, ex, exception_traceback())) q_in.task_done() continue item = { 'service' : service, 'section' : section, 'target' : target, 'config' : service_config, 'addrs' : service_targets[target], 'topic' : topic, 'payload' : job.payload, 'data' : None, 'title' : None, 'image' : None, 'message' : None, 'priority' : None } transform_data = job.data item['data'] = dict(list(transform_data.items())) item['title'] = xform(context.get_config(section, 'title'), SCRIPTNAME, transform_data) item['image'] = xform(context.get_config(section, 'image'), '', transform_data) item['message'] = xform(context.get_config(section, 'format'), job.payload, transform_data) try: item['priority'] = int(xform(context.get_config(section, 'priority'), 0, transform_data)) except Exception as e: item['priority'] = 0 logger.warning("Failed to determine the priority, defaulting to zero: %s" % e) if HAVE_JINJA is False and context.get_config(section, 'template'): logger.warning("Templating not possible because Jinja2 is not installed") if HAVE_JINJA is True: template = context.get_config(section, 'template') if template is not None: try: text = render_template(template, transform_data) if text is not None: item['message'] = text except Exception as e: logger.warning("Cannot render `%s' template: %s" % (template, e)) if item.get('message') is not None and len(item.get('message')) > 0: st = Struct(**item) notified = False try: # Fire the plugin in a separate thread and kill it if it doesn't return in 10s module = service_plugins[service]['module'] service_logger_name = 'mqttwarn.services.{}'.format(service) srv = make_service(mqttc=mqttc, name=service_logger_name) notified = timeout(module.plugin, (srv, st)) except Exception as e: logger.error("Cannot invoke service for `%s': %s" % (service, e)) if not notified: logger.warning("Notification of %s for `%s' FAILED or TIMED OUT" % (service, item.get('topic'))) else: logger.warning("Notification of %s for `%s' suppressed: text is empty" % (service, item.get('topic'))) q_in.task_done() logger.debug("Thread exiting...")