From 7d6da2c2326f38487e901ccd51c1d16b86fa8469 Mon Sep 17 00:00:00 2001 From: Lalleh Rafeei <84813886+lrafeei@users.noreply.github.com> Date: Tue, 15 Oct 2024 15:05:10 -0700 Subject: [PATCH] Azure init container setting flag (#1223) * Initial commit for azure sidecar * Merge changes from main * Change Azure init container env var name * Pin gRPC version supported in Python 3.7 * Update tox.ini Co-authored-by: Uma Annamalai * Clean up tox runners Co-authored-by: Uma Annamalai Co-authored-by: Timothy Pansino Co-authored-by: Hannah Stepanek --------- Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> Co-authored-by: Uma Annamalai Co-authored-by: Uma Annamalai Co-authored-by: Timothy Pansino Co-authored-by: Hannah Stepanek Co-authored-by: Timothy Pansino <11214426+TimPansino@users.noreply.github.com> --- newrelic/bootstrap/sitecustomize.py | 44 ++++++++++++++++------------- newrelic/config.py | 1 + newrelic/core/config.py | 15 +++++----- 3 files changed, 33 insertions(+), 27 deletions(-) diff --git a/newrelic/bootstrap/sitecustomize.py b/newrelic/bootstrap/sitecustomize.py index 2fed5fdc2..894d58539 100644 --- a/newrelic/bootstrap/sitecustomize.py +++ b/newrelic/bootstrap/sitecustomize.py @@ -15,7 +15,6 @@ import os import sys import time - from importlib.machinery import PathFinder # Define some debug logging routines to help sort out things when this @@ -108,12 +107,14 @@ def del_sys_path_entry(path): python_prefix_matches = expected_python_prefix == actual_python_prefix python_version_matches = expected_python_version == actual_python_version k8s_operator_enabled = os.environ.get("NEW_RELIC_K8S_OPERATOR_ENABLED", "off").lower() in ("on", "true", "1") +azure_operator_enabled = os.environ.get("NEW_RELIC_AZURE_OPERATOR_ENABLED", "off").lower() in ("on", "true", "1") log_message("python_prefix_matches = %r", python_prefix_matches) log_message("python_version_matches = %r", python_version_matches) log_message("k8s_operator_enabled = %r", k8s_operator_enabled) +log_message("azure_operator_enabled = %r", azure_operator_enabled) -if k8s_operator_enabled or (python_prefix_matches and python_version_matches): +if k8s_operator_enabled or azure_operator_enabled or (python_prefix_matches and python_version_matches): # We also need to skip agent initialisation if neither the license # key or config file environment variables are set. We do this as # some people like to use a common startup script which always uses @@ -129,24 +130,10 @@ def del_sys_path_entry(path): log_message("initialize_agent = %r", initialize_agent) if initialize_agent: - if not k8s_operator_enabled: - # When installed as an egg with buildout, the root directory for - # packages is not listed in sys.path and scripts instead set it - # after Python has started up. This will cause importing of - # 'newrelic' module to fail. What we do is see if the root - # directory where the package is held is in sys.path and if not - # insert it. For good measure we remove it after having imported - # 'newrelic' module to reduce chance that will cause any issues. - # If it is a buildout created script, it will replace the whole - # sys.path again later anyway. - root_directory = os.path.dirname(os.path.dirname(boot_directory)) - log_message("root_directory = %r", root_directory) - - new_relic_path = root_directory - do_insert_path = root_directory not in sys.path - else: - # When installed with the kubernetes operator, we need to attempt - # to find a distribution from our initcontainer that matches the + if k8s_operator_enabled or azure_operator_enabled: + # When installed with either the kubernetes operator or the + # azure operator functionality enabled, we need to attempt to + # find a distribution from our initcontainer that matches the # current environment. For wheels, this is platform dependent and we # rely on pip to identify the correct wheel to use. If no suitable # wheel can be found, we will fall back to the sdist and disable @@ -155,12 +142,29 @@ def del_sys_path_entry(path): # the 'newrelic' module later and use our APIs in their code. try: sys.path.insert(0, boot_directory) + # Will use the same file for k8s as well as Azure since the functionality + # will remain the same. File may be renamed in the near future. from newrelic_k8s_operator import find_supported_newrelic_distribution finally: del_sys_path_entry(boot_directory) new_relic_path = find_supported_newrelic_distribution() do_insert_path = True + else: + # When installed as an egg with buildout, the root directory for + # packages is not listed in sys.path and scripts instead set it + # after Python has started up. This will cause importing of + # 'newrelic' module to fail. What we do is see if the root + # directory where the package is held is in sys.path and if not + # insert it. For good measure we remove it after having imported + # 'newrelic' module to reduce chance that will cause any issues. + # If it is a buildout created script, it will replace the whole + # sys.path again later anyway. + root_directory = os.path.dirname(os.path.dirname(boot_directory)) + log_message("root_directory = %r", root_directory) + + new_relic_path = root_directory + do_insert_path = root_directory not in sys.path # Now that the appropriate location of the module has been identified, # either by the kubernetes operator or this script, we are ready to import diff --git a/newrelic/config.py b/newrelic/config.py index 7fd6f31b8..6a1ba2c69 100644 --- a/newrelic/config.py +++ b/newrelic/config.py @@ -554,6 +554,7 @@ def _process_configuration(section): _process_setting(section, "ai_monitoring.record_content.enabled", "getboolean", None) _process_setting(section, "ai_monitoring.streaming.enabled", "getboolean", None) _process_setting(section, "k8s_operator.enabled", "getboolean", None) + _process_setting(section, "azure_operator.enabled", "getboolean", None) _process_setting(section, "package_reporting.enabled", "getboolean", None) diff --git a/newrelic/core/config.py b/newrelic/core/config.py index fec4bf6a9..3f5f213ee 100644 --- a/newrelic/core/config.py +++ b/newrelic/core/config.py @@ -34,7 +34,6 @@ from newrelic.core.attribute import MAX_ATTRIBUTE_LENGTH from newrelic.core.attribute_filter import AttributeFilter - try: import grpc @@ -82,7 +81,7 @@ def emit(self, record): # sub categories we don't know about. -class Settings(): +class Settings: nested = False def __repr__(self): @@ -162,6 +161,10 @@ class K8sOperatorSettings(Settings): pass +class AzureOperatorSettings(Settings): + pass + + class PackageReportingSettings(Settings): pass @@ -431,6 +434,7 @@ class EventHarvestConfigHarvestLimitSettings(Settings): _settings.ai_monitoring.streaming = AIMonitoringStreamingSettings() _settings.ai_monitoring.record_content = AIMonitoringRecordContentSettings() _settings.k8s_operator = K8sOperatorSettings() +_settings.azure_operator = AzureOperatorSettings() _settings.package_reporting = PackageReportingSettings() _settings.attributes = AttributesSettings() _settings.browser_monitoring = BrowserMonitorSettings() @@ -957,6 +961,7 @@ def default_otlp_host(host): ) _settings.ai_monitoring._llm_token_count_callback = None _settings.k8s_operator.enabled = _environ_as_bool("NEW_RELIC_K8S_OPERATOR_ENABLED", default=False) +_settings.azure_operator.enabled = _environ_as_bool("NEW_RELIC_AZURE_OPERATOR_ENABLED", default=False) _settings.package_reporting.enabled = _environ_as_bool("NEW_RELIC_PACKAGE_REPORTING_ENABLED", default=True) _settings.ml_insights_events.enabled = _environ_as_bool("NEW_RELIC_ML_INSIGHTS_EVENTS_ENABLED", default=False) @@ -1091,11 +1096,7 @@ def global_settings_dump(settings_object=None, serializable=False): if not isinstance(key, str): del settings[key] - if ( - not isinstance(value, str) - and not isinstance(value, float) - and not isinstance(value, int) - ): + if not isinstance(value, str) and not isinstance(value, float) and not isinstance(value, int): settings[key] = repr(value) return settings