def _wrap_Redis_method_wrapper_(module, instance_class_name, operation): def _nr_wrapper_Redis_method_(wrapped, instance, args, kwargs): transaction = current_transaction() if transaction is None: return wrapped(*args, **kwargs) dt = DatastoreTrace(transaction, product='Redis', target=None, operation=operation) transaction._nr_datastore_instance_info = (None, None, None) with dt: result = wrapped(*args, **kwargs) host, port_path_or_id, db = transaction._nr_datastore_instance_info dt.host = host dt.port_path_or_id = port_path_or_id dt.database_name = db return result name = '%s.%s' % (instance_class_name, operation) wrap_function_wrapper(module, name, _nr_wrapper_Redis_method_)
def _wrap_Redis_method_wrapper_(module, instance_class_name, operation): def _nr_wrapper_Redis_method_(wrapped, instance, args, kwargs): transaction = current_transaction() if transaction is None: return wrapped(*args, **kwargs) dt = DatastoreTrace( transaction, product='Redis', target=None, operation=operation ) transaction._nr_datastore_instance_info = (None, None, None) with dt: result = wrapped(*args, **kwargs) host, port_path_or_id, db = transaction._nr_datastore_instance_info dt.host = host dt.port_path_or_id = port_path_or_id dt.database_name = db return result name = '%s.%s' % (instance_class_name, operation) wrap_function_wrapper(module, name, _nr_wrapper_Redis_method_)
def instrument_flask_app(module): wrap_wsgi_application(module, 'Flask.wsgi_app', framework=framework_details()) wrap_function_wrapper(module, 'Flask.add_url_rule', wrapper_Flask_add_url_rule_input) wrap_function_wrapper(module, 'Flask.handle_http_exception', wrapper_Flask_handle_http_exception) # Use the same wrapper for initial user exception processing and # fallback for unhandled exceptions. if hasattr(module.Flask, 'handle_user_exception'): wrap_function_wrapper(module, 'Flask.handle_user_exception', wrapper_Flask_handle_exception) wrap_function_wrapper(module, 'Flask.handle_exception', wrapper_Flask_handle_exception) # The _register_error_handler() method was only introduced in # Flask version 0.7.0. if hasattr(module.Flask, '_register_error_handler'): wrap_function_wrapper(module, 'Flask._register_error_handler', wrapper_Flask__register_error_handler)
def instrument_tornado_wsgi(module): wrap_function_wrapper(module, 'WSGIContainer.__init__', _nr_wrapper_WSGIContainer___init___) wrap_function_wrapper(module, 'WSGIContainer.__call__', _nr_wrapper_WSGIContainer___call___) wrap_wsgi_application(module, 'WSGIApplication.__call__')
def instrument_tornado_httpserver(module): wrap_function_wrapper( module, '_ServerRequestAdapter.on_connection_close', _nr_wrapper__ServerRequestAdapter_on_connection_close_) wrap_function_wrapper(module, '_ServerRequestAdapter.finish', _nr_wrapper__ServerRequestAdapter_finish_)
def wrap_elasticsearch_client_method(owner, name, arg_extractor, prefix=None): def _nr_wrapper_Elasticsearch_method_(wrapped, instance, args, kwargs): transaction = current_transaction() if transaction is None: return wrapped(*args, **kwargs) # When arg_extractor is None, it means there is no target field # associated with this method. Hence this method will only # create an operation metric and no statement metric. This is # handled by setting the target to None when calling the # DatastoreTrace. if arg_extractor is None: index = None else: index = arg_extractor(*args, **kwargs) if prefix: operation = '%s.%s' % (prefix, name) else: operation = name with DatastoreTrace(transaction, product='Elasticsearch', target=index, operation=operation): return wrapped(*args, **kwargs) if hasattr(owner, name): wrap_function_wrapper(owner, name, _nr_wrapper_Elasticsearch_method_)
def instrument_urllib3_connectionpool(module): wrap_function_wrapper( module, 'HTTPConnectionPool._make_request', functools.partial(_nr_wrapper_make_request_, scheme='http')) wrap_function_wrapper( module, 'HTTPSConnectionPool._make_request', functools.partial(_nr_wrapper_make_request_, scheme='https'))
def instrument_tornado_iostream(module): if hasattr(module, 'BaseIOStream'): wrap_function_wrapper(module, 'BaseIOStream._maybe_run_close_callback', maybe_run_close_callback_wrapper) elif hasattr(module.IOStream, '_maybe_run_close_callback'): wrap_function_wrapper(module, 'IOStream._maybe_run_close_callback', maybe_run_close_callback_wrapper)
def instrument_django_core_handlers_exception(module): if hasattr(module, 'convert_exception_to_response'): wrap_function_wrapper(module, 'convert_exception_to_response', _nr_wrapper_convert_exception_to_response_) if hasattr(module, 'handle_uncaught_exception'): module.handle_uncaught_exception = (wrap_handle_uncaught_exception( module.handle_uncaught_exception))
def instrument_urllib3_connection(module): # Don't combine the instrument functions into a single function. Keep # the 'connect' monkey patch separate, because it is also used to patch # urllib3 within the requests package. wrap_function_wrapper(module, 'HTTPConnection.connect', functools.partial(httplib_connect_wrapper, scheme='http')) wrap_function_wrapper(module, 'HTTPSConnection.connect', functools.partial(httplib_connect_wrapper, scheme='https'))
def instrument_memcache(module): wrap_function_wrapper(module.Client, '_get_server', _nr_get_server_wrapper) for name in _memcache_client_methods: if hasattr(module.Client, name): wrap_memcache_single(module, name, product='Memcached', target=None, operation=name) for name in _memcache_multi_methods: if hasattr(module.Client, name): wrap_datastore_trace(module.Client, name, product='Memcached', target=None, operation=name)
def instrument_gearman_client(module): wrap_function_trace(module, 'GearmanClient.submit_job') wrap_function_trace(module, 'GearmanClient.submit_multiple_jobs') wrap_function_trace(module, 'GearmanClient.submit_multiple_requests') wrap_function_trace(module, 'GearmanClient.wait_until_jobs_accepted') wrap_function_trace(module, 'GearmanClient.wait_until_jobs_completed') wrap_function_trace(module, 'GearmanClient.get_job_status') wrap_function_trace(module, 'GearmanClient.get_job_statuses') wrap_function_trace(module, 'GearmanClient.wait_until_job_statuses_received') wrap_function_wrapper(module, 'GearmanClient.poll_connections_until_stopped', wrapper_GearmanClient_poll_connections_until_stopped)
def patch_motor(module): if (hasattr(module, 'version_tuple') and module.version_tuple >= (0, 6)): return patched_classes = [ 'MotorClient', 'MotorReplicaSetClient', 'MotorDatabase', 'MotorCollection' ] for patched_class in patched_classes: if hasattr(module, patched_class): wrap_function_wrapper(module, patched_class + '.__getattr__', _nr_wrapper_Motor_getattr_)
def instrument_dyndns53(module): wrap_function_trace(module, 'initialise_database') wrap_function_trace(module, 'download_database') wrap_function_trace(module, 'upload_database') wrap_function_trace(module, 'register_ip') wrap_function_trace(module, 'BasicAuthDatabase.check_credentials') wrap_background_task(module, 'upload_database_command') wrap_background_task(module, 'download_database_command') wrap_function_wrapper(module, 'register_ip', wrapper_register_ip)
def instrument(module): wrap_function_wrapper(module, 'HTTPConnectionWithTimeout.connect', _nr_wrapper_httplib2_connect_wrapper('http')) wrap_function_wrapper(module, 'HTTPSConnectionWithTimeout.connect', _nr_wrapper_httplib2_connect_wrapper('https')) def url_request(connection, uri, *args, **kwargs): return uri newrelic.api.external_trace.wrap_external_trace( module, 'Http.request', 'httplib2', url_request)
def instrument(module): wrap_function_wrapper(module, 'HTTPConnectionWithTimeout.connect', _nr_wrapper_httplib2_connect_wrapper('http')) wrap_function_wrapper(module, 'HTTPSConnectionWithTimeout.connect', _nr_wrapper_httplib2_connect_wrapper('https')) def url_request(connection, uri, *args, **kwargs): return uri newrelic.api.external_trace.wrap_external_trace(module, 'Http.request', 'httplib2', url_request)
def instrument_urllib3_connection(module): # Don't combine the instrument functions into a single function. Keep # the 'connect' monkey patch separate, because it is also used to patch # urllib3 within the requests package. wrap_function_wrapper( module, 'HTTPConnection.connect', functools.partial(httplib_connect_wrapper, scheme='http')) wrap_function_wrapper( module, 'HTTPSConnection.connect', functools.partial(httplib_connect_wrapper, scheme='https'))
def instrument_dyndns53(module): wrap_function_trace(module, 'initialise_database') wrap_function_trace(module, 'download_database') wrap_function_trace(module, 'upload_database') wrap_function_trace(module, 'register_ip') wrap_function_trace(module, 'BasicAuthDatabase.check_credentials') wrap_function_wrapper(module, 'register_ip', wrapper_register_ip) for name, callback in list(module._commands.items()): module._commands[name] = BackgroundTaskWrapper(callback)
def instrument_gearman_client(module): wrap_function_trace(module, 'GearmanClient.submit_job') wrap_function_trace(module, 'GearmanClient.submit_multiple_jobs') wrap_function_trace(module, 'GearmanClient.submit_multiple_requests') wrap_function_trace(module, 'GearmanClient.wait_until_jobs_accepted') wrap_function_trace(module, 'GearmanClient.wait_until_jobs_completed') wrap_function_trace(module, 'GearmanClient.get_job_status') wrap_function_trace(module, 'GearmanClient.get_job_statuses') wrap_function_trace(module, 'GearmanClient.wait_until_job_statuses_received') wrap_function_wrapper( module, 'GearmanClient.poll_connections_until_stopped', wrapper_GearmanClient_poll_connections_until_stopped)
def instrument_tornado_gen(module): # The Return class type was introduced in Tornado 3.0. global GeneratorReturn if hasattr(module, 'Return'): GeneratorReturn = module.Return # The gen.coroutine decorator was introduced in Tornado 3.0. if hasattr(module, 'coroutine'): wrap_function_wrapper(module, 'coroutine', _nr_wrapper_gen_coroutine_) # The gen.engine decorator, Runner class type and Task class type # were introduced in Tornado 2.0. if hasattr(module, 'engine'): wrap_function_wrapper(module, 'engine', _nr_wrapper_gen_coroutine_) if hasattr(module, 'Runner'): wrap_function_wrapper(module, 'Runner.__init__', _nr_wrapper_gen_Runner___init___) if hasattr(module, 'Task'): if hasattr(module.Task, 'start'): # The start() method was removed in Tornado 4.0. wrap_function_wrapper(module, 'Task.start', _nr_wrapper_Task_start_)
def instrument_tornado_wsgi(module): wrap_function_wrapper(module, 'WSGIContainer.__init__', _nr_wrapper_WSGIContainer___init___) wrap_function_wrapper(module, 'WSGIContainer.__call__', _nr_wrapper_WSGIContainer___call___) import tornado if hasattr(tornado, 'version_info'): version = '.'.join(map(str, tornado.version_info)) else: version = None wrap_wsgi_application(module, 'WSGIApplication.__call__', framework=('Tornado/WSGI', version))
def instrument_pybald_app(app, name=None): ''' Monkeypatch the Pybald Router and instrument the WSGI stack with FunctionTrace wrappers. This allows the breakdown of all of the components in the Pybald stack and also sets the transaction names to the controller/action pairs for user code. :param app: A WSGI application to apply newrelic instrumentation to :param name: The (optional) name of the application ''' import pybald.core.router wrap_function_wrapper(pybald.core.router, 'Router.get_handler', wrapper_Pybald_Router_get_handler) return instrument_pybald(app, name=name)
def instrument_tornado_web(module): wrap_function_wrapper(module, 'RequestHandler._execute', _nr_wrapper_RequestHandler__execute_) wrap_function_wrapper(module, 'RequestHandler._handle_request_exception', _nr_wrapper_RequestHandler__handle_request_exception_) wrap_function_wrapper(module, 'RequestHandler.__init__', _nr_wrapper_RequestHandler__init__) wrap_function_wrapper(module, 'RequestHandler.finish', _nr_wrapper_RequestHandler_finish_)
def patch_motor(module): wrap_function_wrapper(module, 'MotorClient.__getattr__', _nr_wrapper_Motor_getattr_) wrap_function_wrapper(module, 'MotorReplicaSetClient.__getattr__', _nr_wrapper_Motor_getattr_) wrap_function_wrapper(module, 'MotorDatabase.__getattr__', _nr_wrapper_Motor_getattr_) wrap_function_wrapper(module, 'MotorCollection.__getattr__', _nr_wrapper_Motor_getattr_)
def instrument_bottle(module): global module_bottle module_bottle = module framework_details = ('Bottle', getattr(module, '__version__')) if hasattr(module.Bottle, 'wsgi'): # version >= 0.9 wrap_wsgi_application(module, 'Bottle.wsgi', framework=framework_details) elif hasattr(module.Bottle, '__call__'): # version < 0.9 wrap_wsgi_application(module, 'Bottle.__call__', framework=framework_details) if (hasattr(module, 'Route') and hasattr(module.Route, '_make_callback')): # version >= 0.10 wrap_out_function(module, 'Route._make_callback', output_wrapper_Route_make_callback) elif hasattr(module.Bottle, '_match'): # version >= 0.9 wrap_out_function(module, 'Bottle._match', output_wrapper_Bottle_match) elif hasattr(module.Bottle, 'match_url'): # version < 0.9 wrap_out_function(module, 'Bottle.match_url', output_wrapper_Bottle_match) wrap_object_attribute(module, 'Bottle.error_handler', proxy_Bottle_error_handler) if hasattr(module, 'auth_basic'): wrap_function_wrapper(module, 'auth_basic', wrapper_auth_basic) if hasattr(module, 'SimpleTemplate'): wrap_function_trace(module, 'SimpleTemplate.render') if hasattr(module, 'MakoTemplate'): wrap_function_trace(module, 'MakoTemplate.render') if hasattr(module, 'CheetahTemplate'): wrap_function_trace(module, 'CheetahTemplate.render') if hasattr(module, 'Jinja2Template'): wrap_function_trace(module, 'Jinja2Template.render') if hasattr(module, 'SimpleTALTemplate'): wrap_function_trace(module, 'SimpleTALTemplate.render')
def instrument_gearman_connection_manager(module): wrap_function_wrapper(module, 'GearmanConnectionManager.handle_read', wrapper_GearmanConnectionManager_handle_function) wrap_function_wrapper(module, 'GearmanConnectionManager.handle_write', wrapper_GearmanConnectionManager_handle_function) wrap_function_wrapper(module, 'GearmanConnectionManager.handle_error', wrapper_GearmanConnectionManager_handle_function) wrap_function_wrapper(module, 'GearmanConnectionManager.poll_connections_until_stopped', wrapper_GearmanConnectionManager_poll_connections_until_stopped)
def instrument_gearman_connection_manager(module): wrap_function_wrapper(module, 'GearmanConnectionManager.handle_read', wrapper_GearmanConnectionManager_handle_function) wrap_function_wrapper(module, 'GearmanConnectionManager.handle_write', wrapper_GearmanConnectionManager_handle_function) wrap_function_wrapper(module, 'GearmanConnectionManager.handle_error', wrapper_GearmanConnectionManager_handle_function) wrap_function_wrapper( module, 'GearmanConnectionManager.poll_connections_until_stopped', wrapper_GearmanConnectionManager_poll_connections_until_stopped)
def _nr_wrapper_RequestHandler___init___(wrapped, instance, args, kwargs): # In this case we are actually wrapping the instance method on an # actual instance of a handler class rather than the class itself. # This is so we can wrap any derived version of this method when # it has been overridden in a handler class. wrap_function_wrapper(instance, 'on_connection_close', _nr_wrapper_RequestHandler_on_connection_close) wrap_function_trace(instance, 'prepare') wrap_function_trace(instance, 'on_finish') handler = instance for name in handler.SUPPORTED_METHODS: name = name.lower() if hasattr(handler, name): wrap_function_trace(instance, name) return wrapped(*args, **kwargs)
def instrument_tornado_web(module): wrap_function_wrapper(module, 'RequestHandler._execute', _nr_wrapper_RequestHandler__execute_) wrap_function_wrapper(module, 'RequestHandler._handle_request_exception', _nr_wrapper_RequestHandler__handle_request_exception_) wrap_function_wrapper(module, 'RequestHandler.__init__', _nr_wrapper_RequestHandler__init__)
def instrument_tornado_template(module): wrap_function_wrapper(module, 'Template.generate', template_generate_wrapper) wrap_function_wrapper(module, 'Template._generate_python', template_generate_python_wrapper) wrap_function_wrapper(module, '_NamedBlock.generate', block_generate_wrapper)
def instrument_bottle(module): global module_bottle module_bottle = module framework_details = ("Bottle", getattr(module, "__version__")) if hasattr(module.Bottle, "wsgi"): # version >= 0.9 wrap_wsgi_application(module, "Bottle.wsgi", framework=framework_details) elif hasattr(module.Bottle, "__call__"): # version < 0.9 wrap_wsgi_application(module, "Bottle.__call__", framework=framework_details) if hasattr(module, "Route") and hasattr(module.Route, "_make_callback"): # version >= 0.10 wrap_out_function(module, "Route._make_callback", output_wrapper_Route_make_callback) elif hasattr(module.Bottle, "_match"): # version >= 0.9 wrap_out_function(module, "Bottle._match", output_wrapper_Bottle_match) elif hasattr(module.Bottle, "match_url"): # version < 0.9 wrap_out_function(module, "Bottle.match_url", output_wrapper_Bottle_match) wrap_object_attribute(module, "Bottle.error_handler", proxy_Bottle_error_handler) if hasattr(module, "auth_basic"): wrap_function_wrapper(module, "auth_basic", wrapper_auth_basic) if hasattr(module, "SimpleTemplate"): wrap_function_trace(module, "SimpleTemplate.render") if hasattr(module, "MakoTemplate"): wrap_function_trace(module, "MakoTemplate.render") if hasattr(module, "CheetahTemplate"): wrap_function_trace(module, "CheetahTemplate.render") if hasattr(module, "Jinja2Template"): wrap_function_trace(module, "Jinja2Template.render") if hasattr(module, "SimpleTALTemplate"): wrap_function_trace(module, "SimpleTALTemplate.render")
def instrument_django_template_base(module): global module_django_template_base module_django_template_base = module wrap_function_wrapper(module, 'generic_tag_compiler', _nr_wrapper_django_template_base_generic_tag_compiler_) wrap_function_wrapper(module, 'Library.tag', _nr_wrapper_django_template_base_Library_tag_) wrap_function_wrapper(module, 'Library.inclusion_tag', _nr_wrapper_django_template_base_Library_inclusion_tag_)
def instrument_tornado_httpserver(module): if hasattr(module, 'HTTPConnection'): # The HTTPConnection class only existed prior to Tornado 4.0. wrap_function_wrapper(module, 'HTTPConnection._on_headers', _nr_wrapper_HTTPConnection__on_headers_) wrap_function_wrapper(module, 'HTTPConnection._on_request_body', _nr_wrapper_HTTPConnection__on_request_body_) wrap_function_wrapper(module, 'HTTPConnection._finish_request', _nr_wrapper_HTTPConnection__finish_request) if hasattr(module.HTTPRequest, '_parse_mime_body'): wrap_function_trace(module, 'HTTPRequest._parse_mime_body')
def instrument_django_template_base(module): global module_django_template_base module_django_template_base = module wrap_function_wrapper( module, 'generic_tag_compiler', _nr_wrapper_django_template_base_generic_tag_compiler_) wrap_function_wrapper(module, 'Library.tag', _nr_wrapper_django_template_base_Library_tag_) wrap_function_wrapper( module, 'Library.inclusion_tag', _nr_wrapper_django_template_base_Library_inclusion_tag_)
def instrument_django_template_base(module): global module_django_template_base module_django_template_base = module settings = global_settings() if 'django.instrumentation.inclusion-tags.r1' in settings.feature_flag: wrap_function_wrapper(module, 'generic_tag_compiler', _nr_wrapper_django_template_base_generic_tag_compiler_) wrap_function_wrapper(module, 'Library.tag', _nr_wrapper_django_template_base_Library_tag_) wrap_function_wrapper(module, 'Library.inclusion_tag', _nr_wrapper_django_template_base_Library_inclusion_tag_)
def instrument_django_template_base(module): global module_django_template_base module_django_template_base = module settings = global_settings() if 'django.instrumentation.inclusion-tags.r1' in settings.feature_flag: wrap_function_wrapper( module, 'generic_tag_compiler', _nr_wrapper_django_template_base_generic_tag_compiler_) wrap_function_wrapper(module, 'Library.tag', _nr_wrapper_django_template_base_Library_tag_) wrap_function_wrapper( module, 'Library.inclusion_tag', _nr_wrapper_django_template_base_Library_inclusion_tag_)
def instrument_tornado_ioloop(module): wrap_function_trace(module, 'IOLoop.add_handler') wrap_function_trace(module, 'IOLoop.add_timeout') wrap_function_wrapper(module, 'IOLoop.add_callback', _nr_wrapper_IOLoop_add_callback_) if hasattr(module.IOLoop, 'add_future'): wrap_function_wrapper(module, 'IOLoop.add_future', _nr_wrapper_IOLoop_add_future_) if hasattr(module, 'PollIOLoop'): wrap_function_trace(module, 'PollIOLoop.add_handler') wrap_function_trace(module, 'PollIOLoop.add_timeout') wrap_function_wrapper(module, 'PollIOLoop.add_callback', _nr_wrapper_IOLoop_add_callback_) wrap_function_trace(module, 'PollIOLoop.add_callback_from_signal')
def instrument(module): if hasattr(module, 'urlretrieve'): _nr_wrapper_urlretrieve_ = _nr_wrapper_factory(bind_params_urlretrieve, 'urllib') wrap_function_wrapper(module, 'urlretrieve', _nr_wrapper_urlretrieve_) if hasattr(module, 'URLopener'): _nr_wrapper_url_opener_open_ = _nr_wrapper_factory( bind_params_open, 'urllib') wrap_function_wrapper(module, 'URLopener.open', _nr_wrapper_url_opener_open_) if hasattr(module, 'OpenerDirector'): _nr_wrapper_opener_director_open_ = _nr_wrapper_factory( bind_params_open, 'urllib2') wrap_function_wrapper(module, 'OpenerDirector.open', _nr_wrapper_opener_director_open_)
def instrument(module): if hasattr(module, 'urlretrieve'): _nr_wrapper_urlretrieve_ = _nr_wrapper_factory( bind_params_urlretrieve, 'urllib') wrap_function_wrapper(module, 'urlretrieve', _nr_wrapper_urlretrieve_) if hasattr(module, 'URLopener'): _nr_wrapper_url_opener_open_ = _nr_wrapper_factory( bind_params_open, 'urllib') wrap_function_wrapper(module, 'URLopener.open', _nr_wrapper_url_opener_open_) if hasattr(module, 'OpenerDirector'): _nr_wrapper_opener_director_open_ = _nr_wrapper_factory( bind_params_open, 'urllib2') wrap_function_wrapper(module, 'OpenerDirector.open', _nr_wrapper_opener_director_open_)
def instrument_tornado_stack_context(module): wrap_function_wrapper(module, 'wrap', _nr_wrapper_stack_context_wrap_) wrap_function_wrapper(module, '_handle_exception', _nr_wrapper_handle_exception_)
def __call__(self, *args, **kwargs): agent.wrap_function_wrapper(kwargs['connection_class'], '_execute', self._execute_wrapper) return super(ConnectionFactory, self).__call__(*args, **kwargs)
def instrument_django_core_management_base(module): wrap_function_wrapper(module, 'BaseCommand.__init__', _nr_wrapper_BaseCommand___init___) wrap_function_wrapper(module, 'BaseCommand.run_from_argv', _nr_wrapper_BaseCommand_run_from_argv_)
def instrument_psycopg2_extensions(module): wrap_function_wrapper(module, 'register_type', wrapper_psycopg2_register_type)
def instrument_redis_connection(module): wrap_function_wrapper(module, 'Connection.send_command', _nr_Connection_send_command_wrapper_)
def instrument_cherrypy__cpdispatch(module): wrap_function_wrapper(module, 'Dispatcher.find_handler', wrapper_Dispatcher_find_handler) wrap_function_wrapper(module, 'RoutesDispatcher.find_handler', wrapper_RoutesDispatcher_find_handler)
def instrument_umemcache(module): wrap_function_wrapper(module, 'Client', _nr_umemcache_Client_wrapper_)