From 89203b067ef2e6c747f3d297bc98683b3f2328aa Mon Sep 17 00:00:00 2001 From: Lalleh Rafeei Date: Tue, 24 Feb 2026 17:14:14 -0800 Subject: [PATCH 01/10] Change loaded modules to go one at a time --- newrelic/core/application.py | 40 +++++++++++------------------------- 1 file changed, 12 insertions(+), 28 deletions(-) diff --git a/newrelic/core/application.py b/newrelic/core/application.py index 81839715ec..9c7c0bd965 100644 --- a/newrelic/core/application.py +++ b/newrelic/core/application.py @@ -1284,27 +1284,14 @@ def harvest(self, shutdown=False, flexible=False): data_sampler.name, ) - # Send environment plugin list - - stopwatch_start = time.time() - while ( - configuration - and configuration.package_reporting.enabled - and self._remaining_plugins - and ((time.time() - stopwatch_start) < MAX_PACKAGE_CAPTURE_TIME_PER_SLOW_HARVEST) - ): + # Send environment plugin. + # Send one per cycle to avoid time outs/ + # lost module info for larger module loading. + if self.configuration and self.configuration.package_reporting.enabled: try: - module_info = next(self.plugins) - self.modules.append(module_info) + self._active_session.send_loaded_modules(next(self.plugins)) except StopIteration: - self._remaining_plugins = False - - # Send the accumulated environment plugin list if not empty - if self.modules: - self._active_session.send_loaded_modules(self.modules) - - # Reset the modules list every harvest cycle - self.modules = [] + pass # Add a metric we can use to track how many harvest # periods have occurred. @@ -1745,15 +1732,12 @@ def internal_agent_shutdown(self, restart=False): # if this has not been completed during harvest # lifetime of the application - while self.configuration and self.configuration.package_reporting.enabled and self._remaining_plugins: - try: - module_info = next(self.plugins) - self.modules.append(module_info) - except StopIteration: - self._remaining_plugins = False - if self.modules: - self._active_session.send_loaded_modules(self.modules) - self.modules = [] + if self.configuration and self.configuration.package_reporting.enabled: + # Anything that was left in the plugins generator + # will be resolved here. + plugins_list = list(self.plugins) + if plugins_list: + self._active_session.send_loaded_modules(plugins_list) # Now shutdown the actual agent session. From 245406350cc95e20074f08d29496a35dd330fcee Mon Sep 17 00:00:00 2001 From: Lalleh Rafeei Date: Thu, 26 Feb 2026 12:26:17 -0800 Subject: [PATCH 02/10] Send individual plugin inside list --- newrelic/core/application.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/newrelic/core/application.py b/newrelic/core/application.py index 9c7c0bd965..3eaa40156b 100644 --- a/newrelic/core/application.py +++ b/newrelic/core/application.py @@ -1289,7 +1289,7 @@ def harvest(self, shutdown=False, flexible=False): # lost module info for larger module loading. if self.configuration and self.configuration.package_reporting.enabled: try: - self._active_session.send_loaded_modules(next(self.plugins)) + self._active_session.send_loaded_modules([next(self.plugins)]) except StopIteration: pass From b93898cbe4524d6e59fbdd70838f84eb13515c8f Mon Sep 17 00:00:00 2001 From: Lalleh Rafeei Date: Mon, 2 Mar 2026 17:58:24 -0800 Subject: [PATCH 03/10] Reset plugin generator for reconnect --- newrelic/core/application.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/newrelic/core/application.py b/newrelic/core/application.py index 3eaa40156b..b516d8bb36 100644 --- a/newrelic/core/application.py +++ b/newrelic/core/application.py @@ -1760,6 +1760,9 @@ def internal_agent_shutdown(self, restart=False): # as shutdown. if restart: + # Reset package/module generator + self.plugins = plugins() + self._agent_restart += 1 self.activate_session() From c99e785786ca536ec2f69fcd42a213e43e078716 Mon Sep 17 00:00:00 2001 From: lrafeei <84813886+lrafeei@users.noreply.github.com> Date: Tue, 3 Mar 2026 02:00:31 +0000 Subject: [PATCH 04/10] [MegaLinter] Apply linters fixes --- newrelic/core/application.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/newrelic/core/application.py b/newrelic/core/application.py index b516d8bb36..6c6c5fd095 100644 --- a/newrelic/core/application.py +++ b/newrelic/core/application.py @@ -1762,7 +1762,7 @@ def internal_agent_shutdown(self, restart=False): if restart: # Reset package/module generator self.plugins = plugins() - + self._agent_restart += 1 self.activate_session() From dd0cca6049ffc71183a02094bbcd4633dd4682fd Mon Sep 17 00:00:00 2001 From: Lalleh Rafeei Date: Tue, 3 Mar 2026 13:27:11 -0800 Subject: [PATCH 05/10] Clarify comment --- newrelic/core/application.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/newrelic/core/application.py b/newrelic/core/application.py index 6c6c5fd095..c11595eb05 100644 --- a/newrelic/core/application.py +++ b/newrelic/core/application.py @@ -1285,8 +1285,8 @@ def harvest(self, shutdown=False, flexible=False): ) # Send environment plugin. - # Send one per cycle to avoid time outs/ - # lost module info for larger module loading. + # Send one per cycle to avoid time outs/lost + # module info for longer module loading times. if self.configuration and self.configuration.package_reporting.enabled: try: self._active_session.send_loaded_modules([next(self.plugins)]) From 28993c2684c755b4cbd6a542cfb0492b8eb7442a Mon Sep 17 00:00:00 2001 From: Lalleh Rafeei Date: Mon, 9 Mar 2026 17:45:46 -0700 Subject: [PATCH 06/10] Revert to original logic (with bug fixes) --- newrelic/core/application.py | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/newrelic/core/application.py b/newrelic/core/application.py index c11595eb05..96d288a790 100644 --- a/newrelic/core/application.py +++ b/newrelic/core/application.py @@ -49,7 +49,7 @@ _logger = logging.getLogger(__name__) -MAX_PACKAGE_CAPTURE_TIME_PER_SLOW_HARVEST = 2.0 +MAX_PACKAGE_CAPTURE_TIME_PER_SLOW_HARVEST = 5.0 class Application: @@ -1285,13 +1285,20 @@ def harvest(self, shutdown=False, flexible=False): ) # Send environment plugin. - # Send one per cycle to avoid time outs/lost - # module info for longer module loading times. - if self.configuration and self.configuration.package_reporting.enabled: - try: - self._active_session.send_loaded_modules([next(self.plugins)]) - except StopIteration: - pass + # If a module takes less than 0.5 seconds to load, + # continue to upload. Do this until we reach 5.0 + # seconds or until a module has taken more than + # 0.5 seconds to upload. Then, wait for the next + # harvest cycle before resuming. + if self._remaining_plugins and self.configuration and self.configuration.package_reporting.enabled: + start = stopwatch_start = time.time() + while ((time.time() - stopwatch_start) < 0.5) and ((time.time() - start) < MAX_PACKAGE_CAPTURE_TIME_PER_SLOW_HARVEST): + try: + self._active_session.send_loaded_modules([next(self.plugins)]) + stopwatch_start = time.time() + except StopIteration: + self._remaining_plugins = False + break # Add a metric we can use to track how many harvest # periods have occurred. @@ -1732,7 +1739,7 @@ def internal_agent_shutdown(self, restart=False): # if this has not been completed during harvest # lifetime of the application - if self.configuration and self.configuration.package_reporting.enabled: + if self._remaining_plugins and self.configuration and self.configuration.package_reporting.enabled: # Anything that was left in the plugins generator # will be resolved here. plugins_list = list(self.plugins) @@ -1762,6 +1769,7 @@ def internal_agent_shutdown(self, restart=False): if restart: # Reset package/module generator self.plugins = plugins() + self._remaining_plugins = True self._agent_restart += 1 self.activate_session() From c2031f1fcee15e2fb5037061300c2e48053ac748 Mon Sep 17 00:00:00 2001 From: lrafeei <84813886+lrafeei@users.noreply.github.com> Date: Tue, 10 Mar 2026 00:47:32 +0000 Subject: [PATCH 07/10] [MegaLinter] Apply linters fixes --- newrelic/core/application.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/newrelic/core/application.py b/newrelic/core/application.py index 96d288a790..94eaf4ed26 100644 --- a/newrelic/core/application.py +++ b/newrelic/core/application.py @@ -1292,7 +1292,9 @@ def harvest(self, shutdown=False, flexible=False): # harvest cycle before resuming. if self._remaining_plugins and self.configuration and self.configuration.package_reporting.enabled: start = stopwatch_start = time.time() - while ((time.time() - stopwatch_start) < 0.5) and ((time.time() - start) < MAX_PACKAGE_CAPTURE_TIME_PER_SLOW_HARVEST): + while ((time.time() - stopwatch_start) < 0.5) and ( + (time.time() - start) < MAX_PACKAGE_CAPTURE_TIME_PER_SLOW_HARVEST + ): try: self._active_session.send_loaded_modules([next(self.plugins)]) stopwatch_start = time.time() From 8d380180f1cfee9e416aa9fbc66bce07876d42b8 Mon Sep 17 00:00:00 2001 From: Lalleh Rafeei Date: Thu, 12 Mar 2026 14:37:35 -0700 Subject: [PATCH 08/10] Tweak logic for package reporting --- newrelic/core/application.py | 31 +++++++++++-------------------- 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/newrelic/core/application.py b/newrelic/core/application.py index 94eaf4ed26..22ff8b9717 100644 --- a/newrelic/core/application.py +++ b/newrelic/core/application.py @@ -49,7 +49,7 @@ _logger = logging.getLogger(__name__) -MAX_PACKAGE_CAPTURE_TIME_PER_SLOW_HARVEST = 5.0 +MAX_PACKAGE_CAPTURE_TIME_PER_SLOW_HARVEST = 3.0 class Application: @@ -105,8 +105,6 @@ def __init__(self, app_name, linked_applications=None): self._data_samplers_lock = threading.Lock() self._data_samplers_started = False - self._remaining_plugins = True - self._agent_control_health_thread = threading.Thread( name="Agent-Control-Health-Session-Thread", target=agent_control_healthcheck_loop ) @@ -1290,16 +1288,13 @@ def harvest(self, shutdown=False, flexible=False): # seconds or until a module has taken more than # 0.5 seconds to upload. Then, wait for the next # harvest cycle before resuming. - if self._remaining_plugins and self.configuration and self.configuration.package_reporting.enabled: - start = stopwatch_start = time.time() - while ((time.time() - stopwatch_start) < 0.5) and ( - (time.time() - start) < MAX_PACKAGE_CAPTURE_TIME_PER_SLOW_HARVEST - ): + if self.plugins and self.configuration and self.configuration.package_reporting.enabled: + start = time.time() + while (time.time() - start) < MAX_PACKAGE_CAPTURE_TIME_PER_SLOW_HARVEST: try: self._active_session.send_loaded_modules([next(self.plugins)]) - stopwatch_start = time.time() except StopIteration: - self._remaining_plugins = False + self.plugins = False break # Add a metric we can use to track how many harvest @@ -1737,16 +1732,13 @@ def internal_agent_shutdown(self, restart=False): self.stop_data_samplers() - # Finishes collecting environment plugin information - # if this has not been completed during harvest - # lifetime of the application - - if self._remaining_plugins and self.configuration and self.configuration.package_reporting.enabled: - # Anything that was left in the plugins generator - # will be resolved here. + # Finishes collecting environment plugin information if this has + # not been completed during harvest lifetime of the application. + if self.plugins and self.configuration and self.configuration.package_reporting.enabled: + # Anything that was left in the plugins + # generator will be resolved here. plugins_list = list(self.plugins) - if plugins_list: - self._active_session.send_loaded_modules(plugins_list) + self._active_session.send_loaded_modules(plugins_list) # Now shutdown the actual agent session. @@ -1771,7 +1763,6 @@ def internal_agent_shutdown(self, restart=False): if restart: # Reset package/module generator self.plugins = plugins() - self._remaining_plugins = True self._agent_restart += 1 self.activate_session() From 53af78486c7d160f46a5aa34a64a3a1fabdb7664 Mon Sep 17 00:00:00 2001 From: Lalleh Rafeei Date: Mon, 16 Mar 2026 16:02:37 -0700 Subject: [PATCH 09/10] Remove time constraint completely for first iteration --- newrelic/core/application.py | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/newrelic/core/application.py b/newrelic/core/application.py index 22ff8b9717..157eb5264e 100644 --- a/newrelic/core/application.py +++ b/newrelic/core/application.py @@ -1283,18 +1283,11 @@ def harvest(self, shutdown=False, flexible=False): ) # Send environment plugin. - # If a module takes less than 0.5 seconds to load, - # continue to upload. Do this until we reach 5.0 - # seconds or until a module has taken more than - # 0.5 seconds to upload. Then, wait for the next - # harvest cycle before resuming. - if self.plugins and self.configuration and self.configuration.package_reporting.enabled: + if self.configuration and self.configuration.package_reporting.enabled: start = time.time() - while (time.time() - start) < MAX_PACKAGE_CAPTURE_TIME_PER_SLOW_HARVEST: - try: - self._active_session.send_loaded_modules([next(self.plugins)]) - except StopIteration: - self.plugins = False + while (package := next(self.plugins, False)): + self._active_session.send_loaded_modules([package]) + if (time.time() - start) < MAX_PACKAGE_CAPTURE_TIME_PER_SLOW_HARVEST: break # Add a metric we can use to track how many harvest @@ -1734,11 +1727,12 @@ def internal_agent_shutdown(self, restart=False): # Finishes collecting environment plugin information if this has # not been completed during harvest lifetime of the application. - if self.plugins and self.configuration and self.configuration.package_reporting.enabled: + if self.configuration and self.configuration.package_reporting.enabled: # Anything that was left in the plugins # generator will be resolved here. plugins_list = list(self.plugins) - self._active_session.send_loaded_modules(plugins_list) + if plugins_list: + self._active_session.send_loaded_modules(plugins_list) # Now shutdown the actual agent session. From 89594b4d19bdafddaa838144237c50d786ca4391 Mon Sep 17 00:00:00 2001 From: lrafeei <84813886+lrafeei@users.noreply.github.com> Date: Mon, 16 Mar 2026 23:04:39 +0000 Subject: [PATCH 10/10] [MegaLinter] Apply linters fixes --- newrelic/core/application.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/newrelic/core/application.py b/newrelic/core/application.py index 157eb5264e..16d61f0cad 100644 --- a/newrelic/core/application.py +++ b/newrelic/core/application.py @@ -1285,7 +1285,7 @@ def harvest(self, shutdown=False, flexible=False): # Send environment plugin. if self.configuration and self.configuration.package_reporting.enabled: start = time.time() - while (package := next(self.plugins, False)): + while package := next(self.plugins, False): self._active_session.send_loaded_modules([package]) if (time.time() - start) < MAX_PACKAGE_CAPTURE_TIME_PER_SLOW_HARVEST: break