Пример #1
0
def test_should_not_collect_count():
    requests_store = TransactionsStore(lambda: [],
                                       collect_frequency=5,
                                       max_queue_size=5)
    requests_store._transactions = 4 * [1]

    assert not requests_store.should_collect()
def test_should_collect_count():
    requests_store = TransactionsStore(lambda: [],
                                       collect_frequency=5,
                                       max_queue_length=5)
    requests_store._transactions = 6 * [1]
    requests_store._last_collect -= 3

    assert requests_store.should_collect()
Пример #3
0
def test_tag_transaction():
    requests_store = TransactionsStore(lambda: [], 99999)
    t = requests_store.begin_transaction("test")
    elasticapm.tag(foo='bar')
    requests_store.end_transaction(200, 'test')

    assert t.tags == {'foo': 'bar'}
    transaction_dict = t.to_dict()
    assert transaction_dict['context']['tags'] == {'foo': 'bar'}
Пример #4
0
def test_tag_transaction():
    requests_store = TransactionsStore(lambda: [], 99999)
    t = requests_store.begin_transaction("test")
    elasticapm.tag(foo="bar")
    requests_store.end_transaction(200, "test")

    assert t.tags == {"foo": "bar"}
    transaction_dict = t.to_dict()
    assert transaction_dict["context"]["tags"] == {"foo": "bar"}
Пример #5
0
    def __init__(self, config=None, **defaults):
        # configure loggers first
        cls = self.__class__
        self.logger = logging.getLogger('%s.%s' % (cls.__module__, cls.__name__))
        self.error_logger = logging.getLogger('elasticapm.errors')
        self.state = ClientState()

        self.instrumentation_store = None
        self.processors = []
        self.filter_exception_types_dict = {}
        self._send_timer = None
        self._transports = {}
        self._service_info = None

        self.config = Config(config, default_dict=defaults)
        if self.config.errors:
            for msg in self.config.errors.values():
                self.error_logger.error(msg)
            self.config.disable_send = True
            return

        self._transport_class = import_string(self.config.transport_class)

        for exc_to_filter in (self.config.filter_exception_types or []):
            exc_to_filter_type = exc_to_filter.split(".")[-1]
            exc_to_filter_module = ".".join(exc_to_filter.split(".")[:-1])
            self.filter_exception_types_dict[exc_to_filter_type] = exc_to_filter_module

        self.processors = [import_string(p) for p in self.config.processors] if self.config.processors else []

        self.instrumentation_store = TransactionsStore(
            lambda: self._get_stack_info_for_trace(
                stacks.iter_stack_frames(),
                library_frame_context_lines=self.config.source_lines_span_library_frames,
                in_app_frame_context_lines=self.config.source_lines_span_app_frames,
                with_locals=self.config.collect_local_variables in ('all', 'transactions'),
                locals_processor_func=lambda local_var: varmap(lambda k, v: shorten(
                    v,
                    list_length=self.config.local_var_list_max_length,
                    string_length=self.config.local_var_max_length,
                ), local_var)
            ),
            collect_frequency=self.config.flush_interval,
            sample_rate=self.config.transaction_sample_rate,
            max_spans=self.config.transaction_max_spans,
            max_queue_size=self.config.max_queue_size,
            ignore_patterns=self.config.transactions_ignore_patterns,
        )
        self.include_paths_re = stacks.get_path_regex(self.config.include_paths) if self.config.include_paths else None
        self.exclude_paths_re = stacks.get_path_regex(self.config.exclude_paths) if self.config.exclude_paths else None
        compat.atexit_register(self.close)
Пример #6
0
def test_tag_with_non_string_value():
    requests_store = TransactionsStore(lambda: [], 99999)
    t = requests_store.begin_transaction("test")
    elasticapm.tag(foo=1)
    requests_store.end_transaction(200, 'test')
    assert t.tags == {'foo': '1'}
Пример #7
0
def test_should_not_collect_time():
    requests_store = TransactionsStore(lambda: [], collect_frequency=5)
    requests_store._last_collect -= 3

    assert not requests_store.should_collect()
Пример #8
0
def test_get_transaction_clear():
    requests_store = TransactionsStore(lambda: [], 99999)
    t = requests_store.begin_transaction("test")
    assert t == get_transaction(clear=True)
    assert get_transaction() is None
Пример #9
0
def test_get_transaction():
    requests_store = TransactionsStore(lambda: [], 99999)
    t = requests_store.begin_transaction("test")
    assert t == get_transaction()
Пример #10
0
def transaction_store():
    mock_get_frames = Mock()

    frames = [{
        'function': 'something_expensive',
        'abs_path':
        '/var/parent-elasticapm/elasticapm/tests/contrib/django/testapp/views.py',
        'lineno': 52,
        'module': 'tests.contrib.django.testapp.views',
        'filename': 'tests/contrib/django/testapp/views.py'
    }, {
        'function': '_resolve_lookup',
        'abs_path':
        '/home/ron/.virtualenvs/elasticapm/local/lib/python2.7/site-packages/django/template/base.py',
        'lineno': 789,
        'module': 'django.template.base',
        'filename': 'django/template/base.py'
    }, {
        'function': 'resolve',
        'abs_path':
        '/home/ron/.virtualenvs/elasticapm/local/lib/python2.7/site-packages/django/template/base.py',
        'lineno': 735,
        'module': 'django.template.base',
        'filename': 'django/template/base.py'
    }, {
        'function': 'resolve',
        'abs_path':
        '/home/ron/.virtualenvs/elasticapm/local/lib/python2.7/site-packages/django/template/base.py',
        'lineno': 585,
        'module': 'django.template.base',
        'filename': 'django/template/base.py'
    }, {
        'lineno':
        4,
        'filename':
        u'/var/parent-elasticapm/elasticapm/tests/contrib/django/testapp/templates/list_fish.html'
    }, {
        'function': 'render',
        'abs_path':
        '/home/ron/.virtualenvs/elasticapm/local/lib/python2.7/site-packages/django/template/defaulttags.py',
        'lineno': 4,
        'module': 'django.template.defaulttags',
        'filename': 'django/template/defaulttags.py'
    }, {
        'function': 'render_node',
        'abs_path':
        '/home/ron/.virtualenvs/elasticapm/local/lib/python2.7/site-packages/django/template/debug.py',
        'lineno': 78,
        'module': 'django.template.debug',
        'filename': 'django/template/debug.py'
    }, {
        'function': 'render',
        'abs_path':
        '/home/ron/.virtualenvs/elasticapm/local/lib/python2.7/site-packages/django/template/base.py',
        'lineno': 840,
        'module': 'django.template.base',
        'filename': 'django/template/base.py'
    }, {
        'function': 'instrumented_test_render',
        'abs_path':
        '/home/ron/.virtualenvs/elasticapm/local/lib/python2.7/site-packages/django/test/utils.py',
        'lineno': 85,
        'module': 'django.test.utils',
        'filename': 'django/test/utils.py'
    }, {
        'function': 'render',
        'abs_path':
        '/home/ron/.virtualenvs/elasticapm/local/lib/python2.7/site-packages/django/template/base.py',
        'lineno': 140,
        'module': 'django.template.base',
        'filename': 'django/template/base.py'
    }, {
        'function': 'rendered_content',
        'abs_path':
        '/home/ron/.virtualenvs/elasticapm/local/lib/python2.7/site-packages/django/template/response.py',
        'lineno': 82,
        'module': 'django.template.response',
        'filename': 'django/template/response.py'
    }, {
        'function': 'render',
        'abs_path':
        '/home/ron/.virtualenvs/elasticapm/local/lib/python2.7/site-packages/django/template/response.py',
        'lineno': 105,
        'module': 'django.template.response',
        'filename': 'django/template/response.py'
    }, {
        'function': 'get_response',
        'abs_path':
        '/home/ron/.virtualenvs/elasticapm/local/lib/python2.7/site-packages/django/core/handlers/base.py',
        'lineno': 137,
        'module': 'django.core.handlers.base',
        'filename': 'django/core/handlers/base.py'
    }, {
        'function': '__call__',
        'abs_path':
        '/home/ron/.virtualenvs/elasticapm/local/lib/python2.7/site-packages/django/test/client.py',
        'lineno': 109,
        'module': 'django.test.client',
        'filename': 'django/test/client.py'
    }, {
        'function': 'request',
        'abs_path':
        '/home/ron/.virtualenvs/elasticapm/local/lib/python2.7/site-packages/django/test/client.py',
        'lineno': 426,
        'module': 'django.test.client',
        'filename': 'django/test/client.py'
    }, {
        'function': 'get',
        'abs_path':
        '/home/ron/.virtualenvs/elasticapm/local/lib/python2.7/site-packages/django/test/client.py',
        'lineno': 280,
        'module': 'django.test.client',
        'filename': 'django/test/client.py'
    }, {
        'function': 'get',
        'abs_path':
        '/home/ron/.virtualenvs/elasticapm/local/lib/python2.7/site-packages/django/test/client.py',
        'lineno': 473,
        'module': 'django.test.client',
        'filename': 'django/test/client.py'
    }, {
        'function': 'test_template_name_as_view',
        'abs_path':
        '/var/parent-elasticapm/elasticapm/tests/contrib/django/django_tests.py',
        'lineno': 710,
        'module': 'tests.contrib.django.django_tests',
        'filename': 'tests/contrib/django/django_tests.py'
    }]

    mock_get_frames.return_value = frames
    return TransactionsStore(mock_get_frames, 99999)
Пример #11
0
def transaction_store():
    mock_get_frames = Mock()

    frames = [
        {
            "function": "something_expensive",
            "abs_path": "/var/parent-elasticapm/elasticapm/tests/contrib/django/testapp/views.py",
            "lineno": 52,
            "module": "tests.contrib.django.testapp.views",
            "filename": "tests/contrib/django/testapp/views.py",
        },
        {
            "function": "_resolve_lookup",
            "abs_path": "/home/ron/.virtualenvs/elasticapm/local/lib/python2.7/site-packages/django/template/base.py",
            "lineno": 789,
            "module": "django.template.base",
            "filename": "django/template/base.py",
        },
        {
            "function": "resolve",
            "abs_path": "/home/ron/.virtualenvs/elasticapm/local/lib/python2.7/site-packages/django/template/base.py",
            "lineno": 735,
            "module": "django.template.base",
            "filename": "django/template/base.py",
        },
        {
            "function": "resolve",
            "abs_path": "/home/ron/.virtualenvs/elasticapm/local/lib/python2.7/site-packages/django/template/base.py",
            "lineno": 585,
            "module": "django.template.base",
            "filename": "django/template/base.py",
        },
        {
            "lineno": 4,
            "filename": u"/var/parent-elasticapm/elasticapm/tests/contrib/django/testapp/templates/list_fish.html",
        },
        {
            "function": "render",
            "abs_path": "/home/ron/.virtualenvs/elasticapm/local/lib/python2.7/site-packages/django/template/defaulttags.py",
            "lineno": 4,
            "module": "django.template.defaulttags",
            "filename": "django/template/defaulttags.py",
        },
        {
            "function": "render_node",
            "abs_path": "/home/ron/.virtualenvs/elasticapm/local/lib/python2.7/site-packages/django/template/debug.py",
            "lineno": 78,
            "module": "django.template.debug",
            "filename": "django/template/debug.py",
        },
        {
            "function": "render",
            "abs_path": "/home/ron/.virtualenvs/elasticapm/local/lib/python2.7/site-packages/django/template/base.py",
            "lineno": 840,
            "module": "django.template.base",
            "filename": "django/template/base.py",
        },
        {
            "function": "instrumented_test_render",
            "abs_path": "/home/ron/.virtualenvs/elasticapm/local/lib/python2.7/site-packages/django/test/utils.py",
            "lineno": 85,
            "module": "django.test.utils",
            "filename": "django/test/utils.py",
        },
        {
            "function": "render",
            "abs_path": "/home/ron/.virtualenvs/elasticapm/local/lib/python2.7/site-packages/django/template/base.py",
            "lineno": 140,
            "module": "django.template.base",
            "filename": "django/template/base.py",
        },
        {
            "function": "rendered_content",
            "abs_path": "/home/ron/.virtualenvs/elasticapm/local/lib/python2.7/site-packages/django/template/response.py",
            "lineno": 82,
            "module": "django.template.response",
            "filename": "django/template/response.py",
        },
        {
            "function": "render",
            "abs_path": "/home/ron/.virtualenvs/elasticapm/local/lib/python2.7/site-packages/django/template/response.py",
            "lineno": 105,
            "module": "django.template.response",
            "filename": "django/template/response.py",
        },
        {
            "function": "get_response",
            "abs_path": "/home/ron/.virtualenvs/elasticapm/local/lib/python2.7/site-packages/django/core/handlers/base.py",
            "lineno": 137,
            "module": "django.core.handlers.base",
            "filename": "django/core/handlers/base.py",
        },
        {
            "function": "__call__",
            "abs_path": "/home/ron/.virtualenvs/elasticapm/local/lib/python2.7/site-packages/django/test/client.py",
            "lineno": 109,
            "module": "django.test.client",
            "filename": "django/test/client.py",
        },
        {
            "function": "request",
            "abs_path": "/home/ron/.virtualenvs/elasticapm/local/lib/python2.7/site-packages/django/test/client.py",
            "lineno": 426,
            "module": "django.test.client",
            "filename": "django/test/client.py",
        },
        {
            "function": "get",
            "abs_path": "/home/ron/.virtualenvs/elasticapm/local/lib/python2.7/site-packages/django/test/client.py",
            "lineno": 280,
            "module": "django.test.client",
            "filename": "django/test/client.py",
        },
        {
            "function": "get",
            "abs_path": "/home/ron/.virtualenvs/elasticapm/local/lib/python2.7/site-packages/django/test/client.py",
            "lineno": 473,
            "module": "django.test.client",
            "filename": "django/test/client.py",
        },
        {
            "function": "test_template_name_as_view",
            "abs_path": "/var/parent-elasticapm/elasticapm/tests/contrib/django/django_tests.py",
            "lineno": 710,
            "module": "tests.contrib.django.django_tests",
            "filename": "tests/contrib/django/django_tests.py",
        },
    ]

    mock_get_frames.return_value = frames
    return TransactionsStore(mock_get_frames, 99999)
Пример #12
0
    def __init__(self,
                 app_name=None,
                 secret_token=None,
                 transport_class=None,
                 include_paths=None,
                 exclude_paths=None,
                 timeout=None,
                 hostname=None,
                 auto_log_stacks=None,
                 string_max_length=None,
                 list_max_length=None,
                 processors=None,
                 filter_exception_types=None,
                 servers=None,
                 async_mode=None,
                 traces_send_freq_secs=None,
                 transactions_ignore_patterns=None,
                 git_ref=None,
                 app_version=None,
                 **kwargs):
        self.app_name = self.secret_token = self.git_ref = self.app_version = None
        # configure loggers first
        cls = self.__class__
        self.logger = logging.getLogger('%s.%s' %
                                        (cls.__module__, cls.__name__))
        self.error_logger = logging.getLogger('elasticapm.errors')
        self.state = ClientState()
        self._configure(app_name=app_name,
                        secret_token=secret_token,
                        git_ref=git_ref,
                        app_version=app_version)
        self.servers = servers or defaults.SERVERS
        self.async_mode = (async_mode is True or
                           (defaults.ASYNC_MODE and async_mode is not False))
        if not transport_class:
            transport_class = (defaults.ASYNC_TRANSPORT_CLASS
                               if self.async_mode else
                               defaults.SYNC_TRANSPORT_CLASS)
        self._transport_class = import_string(transport_class)
        self._transports = {}

        # servers may be set to a NoneType (for Django)
        if self.servers and not (self.app_name and self.secret_token):
            msg = 'Missing configuration for ElasticAPM client. Please see documentation.'
            self.logger.info(msg)

        self.is_send_disabled = (os.environ.get('ELASTIC_APM_DISABLE_SEND',
                                                '').lower() in ('1', 'true'))
        if self.is_send_disabled:
            self.logger.info(
                'Not sending any data to APM Server due to ELASTIC_APM_DISABLE_SEND '
                'environment variable')

        self.include_paths = set(include_paths or defaults.INCLUDE_PATHS)
        self.exclude_paths = set(exclude_paths or defaults.EXCLUDE_PATHS)
        self.timeout = int(timeout or defaults.TIMEOUT)
        self.hostname = six.text_type(hostname or defaults.HOSTNAME)
        self.auto_log_stacks = bool(auto_log_stacks
                                    or defaults.AUTO_LOG_STACKS)

        self.string_max_length = int(string_max_length
                                     or defaults.MAX_LENGTH_STRING)
        self.list_max_length = int(list_max_length or defaults.MAX_LENGTH_LIST)
        self.traces_send_freq_secs = (traces_send_freq_secs
                                      or defaults.TRACES_SEND_FREQ_SECS)

        self.filter_exception_types_dict = {}
        for exc_to_filter in (filter_exception_types or []):
            exc_to_filter_type = exc_to_filter.split(".")[-1]
            exc_to_filter_module = ".".join(exc_to_filter.split(".")[:-1])
            self.filter_exception_types_dict[
                exc_to_filter_type] = exc_to_filter_module

        if processors is None:
            self.processors = defaults.PROCESSORS
        else:
            self.processors = processors
        self.processors = [import_string(p) for p in self.processors]

        self.instrumentation_store = TransactionsStore(
            lambda: self.get_stack_info_for_trace(iter_stack_frames(), False),
            self.traces_send_freq_secs, transactions_ignore_patterns)
        atexit_register(self.close)
Пример #13
0
    def __init__(self, config=None, **inline):
        # configure loggers first
        cls = self.__class__
        self.logger = logging.getLogger("%s.%s" %
                                        (cls.__module__, cls.__name__))
        self.error_logger = logging.getLogger("elasticapm.errors")
        self.state = ClientState()

        self.transaction_store = None
        self.processors = []
        self.filter_exception_types_dict = {}
        self._send_timer = None
        self._transports = {}
        self._service_info = None

        self.config = Config(config, inline_dict=inline)
        if self.config.errors:
            for msg in self.config.errors.values():
                self.error_logger.error(msg)
            self.config.disable_send = True

        self._transport_class = import_string(self.config.transport_class)

        for exc_to_filter in self.config.filter_exception_types or []:
            exc_to_filter_type = exc_to_filter.split(".")[-1]
            exc_to_filter_module = ".".join(exc_to_filter.split(".")[:-1])
            self.filter_exception_types_dict[
                exc_to_filter_type] = exc_to_filter_module

        self.processors = [import_string(p) for p in self.config.processors
                           ] if self.config.processors else []

        if platform.python_implementation() == "PyPy":
            # PyPy introduces a `_functools.partial.__call__` frame due to our use
            # of `partial` in AbstractInstrumentedModule
            skip_modules = ("elasticapm.", "_functools")
        else:
            skip_modules = ("elasticapm.", )

        def frames_collector_func():
            return self._get_stack_info_for_trace(
                stacks.iter_stack_frames(skip_top_modules=skip_modules),
                library_frame_context_lines=self.config.
                source_lines_span_library_frames,
                in_app_frame_context_lines=self.config.
                source_lines_span_app_frames,
                with_locals=self.config.collect_local_variables
                in ("all", "transactions"),
                locals_processor_func=lambda local_var: varmap(
                    lambda k, v: shorten(
                        v,
                        list_length=self.config.local_var_list_max_length,
                        string_length=self.config.local_var_max_length,
                    ),
                    local_var,
                ),
            )

        self.transaction_store = TransactionsStore(
            frames_collector_func=frames_collector_func,
            collect_frequency=self.config.flush_interval,
            sample_rate=self.config.transaction_sample_rate,
            max_spans=self.config.transaction_max_spans,
            span_frames_min_duration=self.config.span_frames_min_duration_ms,
            max_queue_size=self.config.max_queue_size,
            ignore_patterns=self.config.transactions_ignore_patterns,
        )
        self.include_paths_re = stacks.get_path_regex(
            self.config.include_paths) if self.config.include_paths else None
        self.exclude_paths_re = stacks.get_path_regex(
            self.config.exclude_paths) if self.config.exclude_paths else None
        compat.atexit_register(self.close)