Exemplo n.º 1
0
    def init_app(self, app, **defaults):
        self.app = app
        if not self.client:
            self.client = make_client(self.client_cls, app, **defaults)

        # 0 is a valid log level (NOTSET), so we need to check explicitly for it
        if self.logging or self.logging is 0:
            if self.logging is not True:
                kwargs = {"level": self.logging}
            else:
                kwargs = {}
            setup_logging(LoggingHandler(self.client, **kwargs))

        signals.got_request_exception.connect(self.handle_exception,
                                              sender=app,
                                              weak=False)

        try:
            from elasticapm.contrib.celery import register_exception_tracking

            register_exception_tracking(self.client)
        except ImportError:
            pass

        # Instrument to get spans
        if self.client.config.instrument:
            elasticapm.instrumentation.control.instrument()

            signals.request_started.connect(self.request_started, sender=app)
            signals.request_finished.connect(self.request_finished, sender=app)
            try:
                from elasticapm.contrib.celery import register_instrumentation

                register_instrumentation(self.client)
            except ImportError:
                pass
        else:
            logger.debug(
                "Skipping instrumentation. INSTRUMENT is set to False.")

        @app.context_processor
        def rum_tracing():
            """
            Adds APM related IDs to the context used for correlating the backend transaction with the RUM transaction
            """
            transaction = get_transaction()
            if transaction and transaction.trace_parent:
                return {
                    "apm": {
                        "trace_id":
                        transaction.trace_parent.trace_id,
                        "span_id":
                        lambda: transaction.ensure_parent_id(),
                        "is_sampled":
                        transaction.is_sampled,
                        "is_sampled_js":
                        "true" if transaction.is_sampled else "false",
                    }
                }
            return {}
Exemplo n.º 2
0
def register_handlers(client):
    from django.core.signals import got_request_exception, request_started, request_finished
    from elasticapm.contrib.django.handlers import exception_handler

    # Connect to Django's internal signal handlers
    got_request_exception.disconnect(dispatch_uid=ERROR_DISPATCH_UID)
    got_request_exception.connect(partial(exception_handler, client),
                                  dispatch_uid=ERROR_DISPATCH_UID,
                                  weak=False)

    request_started.disconnect(dispatch_uid=REQUEST_START_DISPATCH_UID)
    request_started.connect(partial(_request_started_handler, client),
                            dispatch_uid=REQUEST_START_DISPATCH_UID,
                            weak=False)

    request_finished.disconnect(dispatch_uid=REQUEST_FINISH_DISPATCH_UID)
    request_finished.connect(
        lambda sender, **kwargs: client.end_transaction()
        if _should_start_transaction(client) else None,
        dispatch_uid=REQUEST_FINISH_DISPATCH_UID,
        weak=False,
    )

    # If we can import celery, register ourselves as exception handler
    try:
        import celery  # noqa F401
        from elasticapm.contrib.celery import register_exception_tracking

        try:
            register_exception_tracking(client)
        except Exception as e:
            client.logger.exception(
                "Failed installing django-celery hook: %s" % e)
    except ImportError:
        client.logger.debug("Not instrumenting Celery, couldn't import")
Exemplo n.º 3
0
    def init_app(self, app, **defaults):
        self.app = app
        if not self.client:
            self.client = make_client(self.client_cls, app, **defaults)

        if self.logging:
            setup_logging(LoggingHandler(self.client))

        signals.got_request_exception.connect(self.handle_exception,
                                              sender=app,
                                              weak=False)

        try:
            from elasticapm.contrib.celery import register_exception_tracking
            register_exception_tracking(self.client)
        except ImportError:
            pass

        # Instrument to get spans
        if self.client.config.instrument:
            elasticapm.instrumentation.control.instrument()

            signals.request_started.connect(self.request_started, sender=app)
            signals.request_finished.connect(self.request_finished, sender=app)
            try:
                from elasticapm.contrib.celery import register_instrumentation
                register_instrumentation(self.client)
            except ImportError:
                pass
        else:
            logger.debug(
                "Skipping instrumentation. INSTRUMENT is set to False.")
Exemplo n.º 4
0
def main(profile: str):
    """
    Celery app main entry point

    Args:
        profile: profile used to run the app

    """
    load_config(profile, CONFIGS_PATH, config, 'NEWS_DISCOVERY')
    load()
    publisher = container.get('exchange_publisher')
    if not publisher.test_connection():
        LOGGER.error('Error connecting to the queue provider. Exiting...')
        sys.exit(1)

    add_logstash_handler(LOG_CONFIG, config.logstash.host,
                         config.logstash.port)
    CELERY_APP.configure(task_queue_name='news-discovery',
                         broker_config=config.rabbit,
                         worker_concurrency=config.celery.concurrency)

    apm_client = Client(
        config={
            'SERVICE_NAME': 'news-discovery-app',
            'SECRET_TOKEN': config.elastic_apm.secret_token,
            'SERVER_URL': config.elastic_apm.url
        })
    register_instrumentation(apm_client)
    register_exception_tracking(apm_client)

    CELERY_APP.run()
Exemplo n.º 5
0
def main(profile: str):
    """
    Celery worker main entry point

    Args:
        profile: profile used to run the app

    """
    load_config(profile, CONFIGS_PATH, config, 'NLP_SERVICE')
    initialize_summary_service()
    load()
    publisher = container.get('exchange_publisher')
    if not publisher.test_connection():
        LOGGER.error('Error connecting to the queue provider. Exiting...')
        sys.exit(1)

    add_logstash_handler(LOG_CONFIG, config.logstash.host, config.logstash.port)
    CELERY_APP.configure(task_queue_name='nlp-worker',
                         broker_config=config.rabbit,
                         worker_concurrency=config.celery.concurrency,
                         result_backend_url=build_redis_url(**config.redis))

    apm_client = Client(config={
        'SERVICE_NAME': config.elastic_apm.service_name,
        'SECRET_TOKEN': config.elastic_apm.secret_token,
        'SERVER_URL': config.elastic_apm.url
    })
    register_instrumentation(apm_client)
    register_exception_tracking(apm_client)

    CELERY_APP.run()
Exemplo n.º 6
0
def test_failing_celery_task(django_elasticapm_client):
    register_exception_tracking(django_elasticapm_client)
    t = failing_task.delay()
    assert t.state == "FAILURE"
    assert len(django_elasticapm_client.events[ERROR]) == 1
    assert len(django_elasticapm_client.events[TRANSACTION]) == 1
    error = django_elasticapm_client.events[ERROR][0]
    assert error["culprit"] == "tests.contrib.django.testapp.tasks.failing_task"
    assert error["exception"]["message"] == "ValueError: foo"
    assert error["exception"]["handled"] is False

    transaction = django_elasticapm_client.events[TRANSACTION][0]
    assert transaction["name"] == "tests.contrib.django.testapp.tasks.failing_task"
    assert transaction["type"] == "celery"
    assert transaction["result"] == "FAILURE"
Exemplo n.º 7
0
def register_handlers(client):
    from django.core.signals import got_request_exception
    from elasticapm.contrib.django.handlers import exception_handler

    # Connect to Django's internal signal handler
    got_request_exception.connect(exception_handler)

    # If we can import celery, register ourselves as exception handler
    try:
        import celery  # noqa F401
        from elasticapm.contrib.celery import register_exception_tracking

        try:
            register_exception_tracking(client)
        except Exception as e:
            client.logger.exception(
                'Failed installing django-celery hook: %s' % e)
    except ImportError:
        client.logger.debug("Not instrumenting Celery, couldn't import")
Exemplo n.º 8
0
def test_failing_celery_task(django_elasticapm_client):
    register_exception_tracking(django_elasticapm_client)
    with mock.patch("elasticapm.traces.TransactionsStore.should_collect"
                    ) as should_collect_mock:
        should_collect_mock.return_value = True
        t = failing_task.delay()
    assert t.state == "FAILURE"
    assert len(django_elasticapm_client.events) == 2
    error = django_elasticapm_client.events[0]["errors"][0]
    assert error[
        "culprit"] == "tests.contrib.django.testapp.tasks.failing_task"
    assert error["exception"]["message"] == "ValueError: foo"
    assert error["exception"]["handled"] is False

    transaction = django_elasticapm_client.events[1]["transactions"][0]
    assert transaction[
        "name"] == "tests.contrib.django.testapp.tasks.failing_task"
    assert transaction["type"] == "celery"
    assert transaction["result"] == "FAILURE"
Exemplo n.º 9
0
def test_failing_celery_task(django_elasticapm_client):
    register_exception_tracking(django_elasticapm_client)
    with mock.patch('elasticapm.traces.TransactionsStore.should_collect'
                    ) as should_collect_mock:
        should_collect_mock.return_value = True
        t = failing_task.delay()
    assert t.state == 'FAILURE'
    assert len(django_elasticapm_client.events) == 2
    error = django_elasticapm_client.events[0]['errors'][0]
    assert error[
        'culprit'] == 'tests.contrib.django.testapp.tasks.failing_task'
    assert error['exception']['message'] == 'ValueError: foo'
    assert error['handled'] is False

    transaction = django_elasticapm_client.events[1]['transactions'][0]
    assert transaction[
        'name'] == 'tests.contrib.django.testapp.tasks.failing_task'
    assert transaction['type'] == 'celery'
    assert transaction['result'] == 'FAILURE'
Exemplo n.º 10
0
    def _setup_exception_manager(self):
        """
        Setup global exception handler where all unhandled exception can be caught and tracked to APM server
        :return:
        """

        # noinspection PyUnusedLocal
        async def _handler(request: Request, exception: BaseException):
            if not self._client:
                return

            self._client.capture_exception(
                exc_info=sys.exc_info(),
                context={
                    "request": await get_request_info(config=self._client.config, request=request),
                },
                handled=True,
            )
            self._setup_transaction_name(request=request)
            set_transaction_result(result="HTTP 5xx", override=False)
            set_transaction_outcome(outcome=constants.OUTCOME.FAILURE, override=False)
            elastic_context(data={"status_code": 500}, key="response")
            self._client.end_transaction()

        if not isinstance(self._app.error_handler, ElasticAPMPatchedErrorHandler):
            patched_client = ElasticAPMPatchedErrorHandler(current_handler=self._app.error_handler)
            patched_client.setup_apm_handler(apm_handler=_handler)
            self._app.error_handler = patched_client
        else:
            self._app.error_handler.setup_apm_handler(apm_handler=_handler)

        try:
            from elasticapm.contrib.celery import register_exception_tracking

            register_exception_tracking(client=self._client)
        except ImportError:
            self._logger.debug(
                "Failed to setup Exception tracking. "
                "Please install requirements for elasticapm.contrib.celery if exception tracking is required"
            )
            pass
Exemplo n.º 11
0
def main(profile: str):
    """
    Celery beat main entry point

    Args:
        profile: profile used to run the beat

    """
    load_config(profile, CONFIGS_PATH, config, 'NEWS_DISCOVERY')

    add_logstash_handler(LOG_CONFIG, config.logstash.host, config.logstash.port)
    CELERY_BEAT.configure(task_queue_name='news-discovery',
                          broker_config=config.rabbit)

    apm_client = Client(config={
        'SERVICE_NAME': 'news-discovery-beat',
        'SECRET_TOKEN': config.elastic_apm.secret_token,
        'SERVER_URL': config.elastic_apm.url
    })
    register_instrumentation(apm_client)
    register_exception_tracking(apm_client)

    CELERY_BEAT.run(beat=True)
Exemplo n.º 12
0
    def init_app(self, app):
        self.app = app
        if not self.client:
            self.client = make_client(
                self.client_cls,
                app,
                self.app_name,
                self.secret_token,
            )

        if self.logging:
            setup_logging(LoggingHandler(self.client))

        signals.got_request_exception.connect(self.handle_exception,
                                              sender=app,
                                              weak=False)

        try:
            from elasticapm.contrib.celery import register_exception_tracking
            register_exception_tracking(self.client)
        except ImportError:
            pass

        # Instrument to get traces
        skip_env_var = 'SKIP_INSTRUMENT'
        if skip_env_var in os.environ:
            logger.debug("Skipping instrumentation. %s is set.", skip_env_var)
        else:
            elasticapm.instrumentation.control.instrument()

            signals.request_started.connect(self.request_started, sender=app)
            signals.request_finished.connect(self.request_finished, sender=app)
            try:
                from elasticapm.contrib.celery import register_instrumentation
                register_instrumentation(self.client)
            except ImportError:
                pass
from celery import Celery

# <SFTRACE-CONFIG> add the below agent specific configuration
from elasticapm import Client, instrument
from elasticapm.contrib.celery import register_exception_tracking, register_instrumentation
import os
instrument()

# <SFTRACE-CONFIG> Replace <service_name> with appropriate value. The service_name is used to identify and filter the traces related to an application and should be named appropriately to distinctly identify it.  Service name must only contain characters from the ASCII alphabet, numbers, dashes, underscores and spaces.
apm_client = Client(server_url=os.getenv('SFTRACE_SERVER_URL', None),
                    global_labels=os.getenv('SFTRACE_GLOBAL_LABELS', None),
                    service_name='<service_name>',
                    verify_server_cert=os.getenv('SFTRACE_VERFIY_SERVER_CERT',
                                                 None))
register_exception_tracking(apm_client)
register_instrumentation(apm_client)

# sfagent config finish

app = Celery('tasks', broker='amqp://guest@localhost:5672')


@app.task
def add(x, y):
    return x + y