Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add config setting to toggle memory usage runtime metrics. #1122

Merged
merged 5 commits into from
Apr 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions newrelic/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,7 @@ def _process_configuration(section):
_process_setting(section, "transaction_name.naming_scheme", "get", None)
_process_setting(section, "gc_runtime_metrics.enabled", "getboolean", None)
_process_setting(section, "gc_runtime_metrics.top_object_count_limit", "getint", None)
_process_setting(section, "memory_runtime_pid_metrics.enabled", "getboolean", None)
_process_setting(section, "thread_profiler.enabled", "getboolean", None)
_process_setting(section, "transaction_tracer.enabled", "getboolean", None)
_process_setting(
Expand Down
7 changes: 7 additions & 0 deletions newrelic/core/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,10 @@ class GCRuntimeMetricsSettings(Settings):
enabled = False


class MemoryRuntimeMetricsSettings(Settings):
pass


class MachineLearningSettings(Settings):
pass

Expand Down Expand Up @@ -446,6 +450,7 @@ class EventHarvestConfigHarvestLimitSettings(Settings):
_settings.event_harvest_config.harvest_limits = EventHarvestConfigHarvestLimitSettings()
_settings.event_loop_visibility = EventLoopVisibilitySettings()
_settings.gc_runtime_metrics = GCRuntimeMetricsSettings()
_settings.memory_runtime_pid_metrics = MemoryRuntimeMetricsSettings()
_settings.heroku = HerokuSettings()
_settings.infinite_tracing = InfiniteTracingSettings()
_settings.instrumentation = InstrumentationSettings()
Expand Down Expand Up @@ -740,6 +745,8 @@ def default_otlp_host(host):
_settings.gc_runtime_metrics.enabled = False
_settings.gc_runtime_metrics.top_object_count_limit = 5

_settings.memory_runtime_pid_metrics.enabled = _environ_as_bool("NEW_RELIC_MEMORY_RUNTIME_METRICS_ENABLED", default=True)

_settings.transaction_events.enabled = True
_settings.transaction_events.attributes.enabled = True
_settings.transaction_events.attributes.exclude = []
Expand Down
10 changes: 7 additions & 3 deletions newrelic/samplers/memory_usage.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,15 @@
"""
import os

from newrelic.core.config import global_settings
from newrelic.common.system_info import physical_memory_used, total_physical_memory
from newrelic.samplers.decorators import data_source_generator


@data_source_generator(name="Memory Usage")
def memory_usage_data_source():
settings = global_settings()

memory = physical_memory_used()
total_memory = total_physical_memory()
pid = os.getpid()
Expand All @@ -32,7 +35,8 @@ def memory_usage_data_source():
memory_utilization = (memory / total_memory) if total_memory != 0 else 0

yield ("Memory/Physical", memory)
yield ("Memory/Physical/%d" % (pid), memory)

yield ("Memory/Physical/Utilization", memory_utilization)
yield ("Memory/Physical/Utilization/%d" % (pid), memory_utilization)

if settings.memory_runtime_pid_metrics.enabled:
yield ("Memory/Physical/%d" % (pid), memory)
yield ("Memory/Physical/Utilization/%d" % (pid), memory_utilization)
18 changes: 13 additions & 5 deletions tests/agent_unittests/test_sampler_metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,14 +152,22 @@ def test_cpu_metrics_collection(cpu_data_source):

EXPECTED_MEMORY_METRICS = (
"Memory/Physical",
"Memory/Physical/%d" % PID,
"Memory/Physical/Utilization",
"Memory/Physical/%d" % PID,
"Memory/Physical/Utilization/%d" % PID,
)


def test_memory_metrics_collection(memory_data_source):
metrics_table = set(m[0] for m in (memory_data_source() or ()))
@pytest.mark.parametrize("enabled", (True, False))
def test_memory_metrics_collection(memory_data_source, enabled):
@override_generic_settings(settings, {"memory_runtime_pid_metrics.enabled": enabled})
def _test():
metrics_table = set(m[0] for m in (memory_data_source() or ()))
if enabled:
for metric in EXPECTED_MEMORY_METRICS:
assert metric in metrics_table
else:
assert EXPECTED_MEMORY_METRICS[0] in metrics_table
assert EXPECTED_MEMORY_METRICS[1] in metrics_table

for metric in EXPECTED_MEMORY_METRICS:
assert metric in metrics_table
_test()
Loading