From c201bf192915ef45c957f5662722761b91f96e97 Mon Sep 17 00:00:00 2001 From: Hannah Stepanek Date: Thu, 15 Aug 2024 15:41:43 -0700 Subject: [PATCH] Capture pymemcache,aiomcache,bmemcached host&port --- newrelic/hooks/datastore_aiomcache.py | 20 ++++++++++++++++- newrelic/hooks/datastore_bmemcached.py | 24 ++++++++++++++++++++- newrelic/hooks/datastore_pymemcache.py | 20 ++++++++++++++++- tests/datastore_aiomcache/test_aiomcache.py | 7 +++--- tests/datastore_bmemcached/test_memcache.py | 5 +++-- tests/datastore_pymemcache/test_memcache.py | 4 ++-- 6 files changed, 70 insertions(+), 10 deletions(-) diff --git a/newrelic/hooks/datastore_aiomcache.py b/newrelic/hooks/datastore_aiomcache.py index fb770b8192..7a0275269c 100644 --- a/newrelic/hooks/datastore_aiomcache.py +++ b/newrelic/hooks/datastore_aiomcache.py @@ -18,7 +18,25 @@ ) +def capture_host(self, *args, **kwargs): + if hasattr(self, "_pool") and hasattr(self._pool, "_host"): + return self._pool._host + + +def capture_port(self, *args, **kwargs): + if hasattr(self, "_pool") and hasattr(self._pool, "_port"): + return self._pool._port + + def instrument_aiomcache_client(module): for name in _memcache_client_methods: if hasattr(module.Client, name): - wrap_datastore_trace(module, "Client.%s" % name, product="Memcached", target=None, operation=name) + wrap_datastore_trace( + module, + "Client.%s" % name, + product="Memcached", + target=None, + operation=name, + host=capture_host, + port_path_or_id=capture_port, + ) diff --git a/newrelic/hooks/datastore_bmemcached.py b/newrelic/hooks/datastore_bmemcached.py index 3091f0992b..ecb20e7b4b 100644 --- a/newrelic/hooks/datastore_bmemcached.py +++ b/newrelic/hooks/datastore_bmemcached.py @@ -32,7 +32,29 @@ ) +def capture_host(self, *args, **kwargs): + if hasattr(self, "servers"): + for s in self.servers: + if hasattr(s, "host"): + return s.host + + +def capture_port(self, *args, **kwargs): + if hasattr(self, "servers"): + for s in self.servers: + if hasattr(s, "port"): + return s.port + + def instrument_bmemcached_client(module): for name in _memcache_client_methods: if hasattr(module.Client, name): - wrap_datastore_trace(module, "Client.%s" % name, product="Memcached", target=None, operation=name) + wrap_datastore_trace( + module, + "Client.%s" % name, + product="Memcached", + target=None, + operation=name, + host=capture_host, + port_path_or_id=capture_port, + ) diff --git a/newrelic/hooks/datastore_pymemcache.py b/newrelic/hooks/datastore_pymemcache.py index 690e95d616..7bcc3c8e7b 100644 --- a/newrelic/hooks/datastore_pymemcache.py +++ b/newrelic/hooks/datastore_pymemcache.py @@ -37,7 +37,25 @@ ) +def capture_host(self, *args, **kwargs): + if hasattr(self, "server") and self.server and len(self.server) >= 2: + return self.server[0] + + +def capture_port(self, *args, **kwargs): + if hasattr(self, "server") and self.server and len(self.server) >= 2: + return self.server[1] + + def instrument_pymemcache_client(module): for name in _memcache_client_methods: if hasattr(module.Client, name): - wrap_datastore_trace(module, "Client.%s" % name, product="Memcached", target=None, operation=name) + wrap_datastore_trace( + module, + "Client.%s" % name, + product="Memcached", + target=None, + operation=name, + host=capture_host, + port_path_or_id=capture_port, + ) diff --git a/tests/datastore_aiomcache/test_aiomcache.py b/tests/datastore_aiomcache/test_aiomcache.py index 15f3f8d49a..c2cfed66fe 100644 --- a/tests/datastore_aiomcache/test_aiomcache.py +++ b/tests/datastore_aiomcache/test_aiomcache.py @@ -16,6 +16,7 @@ import aiomcache from testing_support.db_settings import memcached_settings +from testing_support.fixture.event_loop import event_loop as loop from testing_support.validators.validate_transaction_metrics import ( validate_transaction_metrics, ) @@ -23,14 +24,12 @@ from newrelic.api.background_task import background_task from newrelic.api.transaction import set_background_task -from testing_support.validators.validate_transaction_metrics import validate_transaction_metrics -from testing_support.fixture.event_loop import event_loop as loop - DB_SETTINGS = memcached_settings()[0] MEMCACHED_HOST = DB_SETTINGS["host"] MEMCACHED_PORT = DB_SETTINGS["port"] MEMCACHED_NAMESPACE = str(os.getpid()) +INSTANCE_METRIC_NAME = "Datastore/instance/Memcached/%s/%s" % (MEMCACHED_HOST, MEMCACHED_PORT) _test_bt_set_get_delete_scoped_metrics = [ ("Datastore/operation/Memcached/set", 1), @@ -43,6 +42,7 @@ ("Datastore/allOther", 3), ("Datastore/Memcached/all", 3), ("Datastore/Memcached/allOther", 3), + (INSTANCE_METRIC_NAME, 3), ("Datastore/operation/Memcached/set", 1), ("Datastore/operation/Memcached/get", 1), ("Datastore/operation/Memcached/delete", 1), @@ -81,6 +81,7 @@ def test_bt_set_get_delete(loop): ("Datastore/allWeb", 3), ("Datastore/Memcached/all", 3), ("Datastore/Memcached/allWeb", 3), + (INSTANCE_METRIC_NAME, 3), ("Datastore/operation/Memcached/set", 1), ("Datastore/operation/Memcached/get", 1), ("Datastore/operation/Memcached/delete", 1), diff --git a/tests/datastore_bmemcached/test_memcache.py b/tests/datastore_bmemcached/test_memcache.py index 2f87da113d..820bd6cb8a 100644 --- a/tests/datastore_bmemcached/test_memcache.py +++ b/tests/datastore_bmemcached/test_memcache.py @@ -23,14 +23,13 @@ from newrelic.api.background_task import background_task from newrelic.api.transaction import set_background_task -from testing_support.validators.validate_transaction_metrics import validate_transaction_metrics - DB_SETTINGS = memcached_settings()[0] MEMCACHED_HOST = DB_SETTINGS["host"] MEMCACHED_PORT = DB_SETTINGS["port"] MEMCACHED_NAMESPACE = str(os.getpid()) MEMCACHED_ADDR = "%s:%s" % (MEMCACHED_HOST, MEMCACHED_PORT) +INSTANCE_METRIC_NAME = "Datastore/instance/Memcached/%s/%s" % (MEMCACHED_HOST, MEMCACHED_PORT) _test_bt_set_get_delete_scoped_metrics = [ ("Datastore/operation/Memcached/set", 1), @@ -43,6 +42,7 @@ ("Datastore/allOther", 3), ("Datastore/Memcached/all", 3), ("Datastore/Memcached/allOther", 3), + (INSTANCE_METRIC_NAME, 3), ("Datastore/operation/Memcached/set", 1), ("Datastore/operation/Memcached/get", 1), ("Datastore/operation/Memcached/delete", 1), @@ -80,6 +80,7 @@ def test_bt_set_get_delete(): ("Datastore/allWeb", 3), ("Datastore/Memcached/all", 3), ("Datastore/Memcached/allWeb", 3), + (INSTANCE_METRIC_NAME, 3), ("Datastore/operation/Memcached/set", 1), ("Datastore/operation/Memcached/get", 1), ("Datastore/operation/Memcached/delete", 1), diff --git a/tests/datastore_pymemcache/test_memcache.py b/tests/datastore_pymemcache/test_memcache.py index 3100db5b7f..76bd955dd7 100644 --- a/tests/datastore_pymemcache/test_memcache.py +++ b/tests/datastore_pymemcache/test_memcache.py @@ -12,8 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -import os - import pymemcache.client from testing_support.db_settings import memcached_settings from testing_support.validators.validate_transaction_metrics import ( @@ -45,6 +43,7 @@ ("Datastore/operation/Memcached/set", 1), ("Datastore/operation/Memcached/get", 1), ("Datastore/operation/Memcached/delete", 1), + ("Datastore/instance/Memcached/%s/%s" % (MEMCACHED_HOST, MEMCACHED_PORT), 3), ] @@ -82,6 +81,7 @@ def test_bt_set_get_delete(): ("Datastore/operation/Memcached/set", 1), ("Datastore/operation/Memcached/get", 1), ("Datastore/operation/Memcached/delete", 1), + ("Datastore/instance/Memcached/%s/%s" % (MEMCACHED_HOST, MEMCACHED_PORT), 3), ]