Example #1
0
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
Example #2
0
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...")