def _test(): with BackgroundTask(application(), name='T1') as txn: txn._priority = first_priority try: raise ValueError('OOPS') except ValueError: txn.notice_error() with BackgroundTask(application(), name='T2') as txn: txn._priority = second_priority try: raise ValueError('OOPS') except ValueError: txn.notice_error() # Stats engine stats_engine = core_application_stats_engine() error_events = list(stats_engine.error_events) assert len(error_events) == 1 # highest priority should win assert stats_engine.error_events.pq[0][0] == 1 if first_transaction_saved: assert error_events[0][0]['transactionName'].endswith('/T1') else: assert error_events[0][0]['transactionName'].endswith('/T2')
def test_nested_context_managers(): app = application_instance() outer = BackgroundTask(app, 'outer') inner = BackgroundTask(app, 'inner') with outer: with inner: assert not inner.enabled
def test_dead_transaction_ends(circular): if circular and six.PY2: pytest.skip("Circular references in py2 result in a memory leak. " "There is no way to remove transactions from the weakref " "cache in this case.") transaction = BackgroundTask(application_instance(), "test_dead_transaction_ends") if circular: transaction._self = transaction transaction.__enter__() del transaction gc.collect()
def test_sentinel_exited_complete_root_exception(): """ This test forces a transaction to exit while it still has an active trace this causes an exception to be raised in TraceCache complete_root(). It verifies that the sentinel.exited property is set to true if an exception is raised in complete_root() """ expected_error = "not the current trace" try: txn = None sentinel = None txn = BackgroundTask(application_instance(), "Parent") txn.__enter__() sentinel = txn.root_span trace = FunctionTrace("trace") trace.__enter__() txn.__exit__(None, None, None) assert False, "Did not raise exception" except RuntimeError as e: assert str(e) == expected_error finally: assert sentinel.exited # Make sure to exit properly so cleanup is performed trace.__exit__(None, None, None) txn.__exit__(None, None, None)
def test_transaction_end_on_different_task(): import asyncio txn = BackgroundTask(application(), name="Parent") async def parent(): txn.__enter__() child_start = asyncio.Event() parent_end = asyncio.Event() child_task = asyncio.ensure_future(child(child_start, parent_end)) await child_start.wait() parent_end.set() return child_task async def child(child_start, parent_end): child_start.set() await parent_end.wait() # Calling asyncio.sleep(0) allows the scheduled done callbacks to run # done callbacks are scheduled through call_soon await asyncio.sleep(0) txn.__exit__(None, None, None) async def test(): task = await asyncio.ensure_future(parent()) await task loop = asyncio.get_event_loop() loop.run_until_complete(test())
def test_transport_get_connection(): app = application() with BackgroundTask(app, 'transport_perform_request') as transaction: transport = Transport([HOST]) transport.get_connection() expected = (ES_SETTINGS['host'], ES_SETTINGS['port'], None) assert transaction._nr_datastore_instance_info == expected
def test_transport_perform_request_requests(): app = application() with BackgroundTask(app, 'perform_request_requests') as transaction: transport = Transport([HOST], connection_class=RequestsHttpConnection) transport.perform_request('POST', METHOD, params=PARAMS, body=DATA) expected = (ES_SETTINGS['host'], ES_SETTINGS['port'], None) assert transaction._nr_datastore_instance_info == expected
async def trace_in_cache_txn_active(asyncio, bg): event = asyncio.Event() with BackgroundTask(application(), 'fg'): with FunctionTrace('fg') as _: task = asyncio.ensure_future(bg(event)) await event.wait() return task
async def sentinel_in_cache_txn_exited(asyncio, bg): event = asyncio.Event() with BackgroundTask(application(), 'fg') as txn: _ = txn.root_span task = asyncio.ensure_future(bg(event)) await event.wait() return task
def _make_test_transaction(): application = application_instance() if not web_transaction: return BackgroundTask(application, transaction_name) environ = {'REQUEST_URI': '/trace_ends_after_txn'} tn = WSGIWebTransaction(application, environ) tn.set_transaction_name(transaction_name) return tn
def _test(): # Stats engine stats_engine = core_application_stats_engine() with BackgroundTask(application(), name='T1') as txn: txn._priority = first_priority with BackgroundTask(application(), name='T2') as txn: txn._priority = second_priority transaction_events = list(stats_engine.transaction_events) assert len(transaction_events) == 1 # highest priority should win assert stats_engine.transaction_events.pq[0][0] == 1 if first_transaction_saved: assert transaction_events[0][0]['name'].endswith('/T1') else: assert transaction_events[0][0]['name'].endswith('/T2')
def _make_test_transaction(): application = application_instance() request = TestAsgiRequest() if not web_transaction: return BackgroundTask(application, transaction_name) tn = ASGIWebTransaction(application, request.scope, request.send, request.receive) tn.set_transaction_name(transaction_name) return tn
def _test(): with BackgroundTask(application(), name='T1') as txn: txn._priority = first_priority txn.record_custom_event('foobar', {'foo': 'bar'}) with BackgroundTask(application(), name='T2') as txn: txn._priority = second_priority txn.record_custom_event('barbaz', {'foo': 'bar'}) # Stats engine stats_engine = core_application_stats_engine() custom_events = list(stats_engine.custom_events) assert len(custom_events) == 1 # highest priority should win assert stats_engine.custom_events.pq[0][0] == 1 if first_transaction_saved: assert custom_events[0][0]['type'] == 'foobar' else: assert custom_events[0][0]['type'] == 'barbaz'
def wrapper_GearmanWorker_on_job_execute(wrapped, instance, args, kwargs): def _bind_params(current_job, *args, **kwargs): return current_job # The background task is always created against the default # application specified by the agent configuration. The background # task is named after the name the task function was registered as, # and prefixed by the special 'Gearman' group. application = default_application() current_job = _bind_params(*args, **kwargs) with BackgroundTask(application, current_job.task, 'Gearman'): return wrapped(*args, **kwargs)
def test_transport_perform_request_urllib3(): app = application() with BackgroundTask(app, 'perform_request_urllib3') as transaction: transport = Transport([HOST], connection_class=Urllib3HttpConnection) if VERSION >= (7, 16, 0): transport.perform_request('POST', METHOD, headers=HEADERS, params=PARAMS, body=DATA) else: transport.perform_request('POST', METHOD, params=PARAMS, body=DATA) expected = (ES_SETTINGS['host'], ES_SETTINGS['port'], None) assert transaction._nr_datastore_instance_info == expected
def wrapper(wrapped, instance, args, kwargs): transaction = current_transaction() if callable(name): # Start Hotfix v2.2.1. #if instance and inspect.ismethod(wrapped): # _name = name(instance, *args, **kwargs) #else: # _name = name(*args, **kwargs) if instance is not None: _name = name(instance, *args, **kwargs) else: _name = name(*args, **kwargs) # End Hotfix v2.2.1. elif name is None: _name = callable_name(wrapped) else: _name = name # Helper for obtaining the appropriate application object. If # has an activate() method assume it is a valid application # object. Don't check by type so se can easily mock it for # testing if need be. def _application(): if hasattr(application, 'activate'): return application return application_instance(application) # Check to see if we are being called within the context of an # existing transaction. If we are, then we will record the call # as a function trace node instead. This situation can occur # when a function wrapped with Celery task decorator is called # explicitly in the context of an existing transaction. if transaction: with FunctionTrace(transaction, callable_name(wrapped)): return wrapped(*args, **kwargs) # Otherwise treat it as top level background task. with BackgroundTask(_application(), _name, 'Celery'): return wrapped(*args, **kwargs)
def test_sentinel_exited_complete_root_exception(): """ This test forces a transaction to exit while it still has an active trace this causes an exception to be raised in TraceCache complete_root(). It verifies that the sentinel.exited property is set to true if an exception is raised in complete_root(), and that the exception is caught. """ txn = None sentinel = None txn = BackgroundTask(application_instance(), "Parent") txn.__enter__() sentinel = txn.root_span trace = FunctionTrace("trace") trace.__enter__() txn.__exit__(None, None, None) assert sentinel.exited # Make sure to exit properly so cleanup is performed trace.__exit__(None, None, None) txn.__exit__(None, None, None)
def _nr_wrapper_BaseCommand_run_from_argv_(wrapped, instance, args, kwargs): def _args(argv, *args, **kwargs): return argv _argv = _args(*args, **kwargs) subcommand = _argv[1] commands = django_settings.instrumentation.scripts.django_admin startup_timeout = \ django_settings.instrumentation.background_task.startup_timeout if subcommand not in commands: return wrapped(*args, **kwargs) application = register_application(timeout=startup_timeout) with BackgroundTask(application, subcommand, 'Django'): return wrapped(*args, **kwargs)
def test_transaction_freeze_path_segments(testname, transaction_segment_terms, tests): application = current_application() # We can't check all possibilites by doing things via the transaction # as it not possible to set up a metric path of only one segment. with segment_rules(application.name, transaction_segment_terms): for test in tests: segments = test['input'].split() if len(segments) < 2: continue ttype = segments[0] group = '/'.join(segments[1:2]) name = '/'.join(segments[2:]) with BackgroundTask(application, name, group) as transaction: transaction.background_task = (ttype == 'OtherTransaction') assert transaction.path == test['expected']
def wrapper(wrapped, instance, args, kwargs): transaction = current_transaction(active_only=False) if callable(name): # Start Hotfix v2.2.1. # if instance and inspect.ismethod(wrapped): # _name = name(instance, *args, **kwargs) # else: # _name = name(*args, **kwargs) if instance is not None: _name = name(instance, *args, **kwargs) else: _name = name(*args, **kwargs) # End Hotfix v2.2.1. elif name is None: _name = callable_name(wrapped) else: _name = name # Helper for obtaining the appropriate application object. If # has an activate() method assume it is a valid application # object. Don't check by type so se can easily mock it for # testing if need be. def _application(): if hasattr(application, 'activate'): return application return application_instance(application) # A Celery Task can be called either outside of a transaction, or # within the context of an existing transaction. There are 3 # possibilities we need to handle: # # 1. In an inactive transaction # # If the end_of_transaction() or ignore_transaction() API calls # have been invoked, this task may be called in the context # of an inactive transaction. In this case, don't wrap the task # in any way. Just run the original function. # # 2. In an active transaction # # Run the original function inside a FunctionTrace. # # 3. Outside of a transaction # # This is the typical case for a celery Task. Since it's not # running inside of an existing transaction, we want to create # a new background transaction for it. if transaction and (transaction.ignore_transaction or transaction.stopped): return wrapped(*args, **kwargs) elif transaction: with FunctionTrace(callable_name(wrapped)): return wrapped(*args, **kwargs) else: with BackgroundTask(_application(), _name, 'Celery'): return wrapped(*args, **kwargs)
async def bg(event): with BackgroundTask(application(), 'bg'): event.set()