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

NH-65067 Remove support for experimental flag #308

Merged
merged 6 commits into from
Feb 9, 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
31 changes: 0 additions & 31 deletions solarwinds_apm/apm_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,6 @@ class SolarWindsApmConfig:

_CONFIG_FILE_DEFAULT = "./solarwinds-apm-config.json"
_DELIMITER = "."
_EXP_KEYS = ["otel_collector"]
_EXP_PREFIX = "experimental_"
_KEY_MASK = "{}...{}:{}"
_KEY_MASK_BAD_FORMAT = "{}...<invalid_format>"
_KEY_MASK_BAD_FORMAT_SHORT = "{}<invalid_format>"
Expand Down Expand Up @@ -114,7 +112,6 @@ def __init__(
"reporter_file_single": 0,
"proxy": "",
"transaction_filters": [],
"experimental": {},
"transaction_name": None,
}
self.is_lambda = self.calculate_is_lambda()
Expand Down Expand Up @@ -771,11 +768,6 @@ def update_with_env_var(self) -> None:
if key == "transaction":
# we do not allow complex config options to be set via environment variables
continue
# TODO Add experimental trace flag, clean up
# https://swicloud.atlassian.net/browse/NH-65067
if key == "experimental":
# but we do allow flat SW_APM_EXPERIMENTAL_OTEL_COLLECTOR setting to match js
key = self._EXP_PREFIX + "otel_collector"
env = (self._SW_PREFIX + key).upper()
val = os.environ.get(env)
if val is not None:
Expand Down Expand Up @@ -870,29 +862,6 @@ def _set_config_value(self, keys_str: str, val: Any) -> Any:
if not apm_logging.ApmLoggingLevel.is_valid_level(val):
raise ValueError
self.__config[key] = val
# TODO Add experimental trace flag, clean up
# https://swicloud.atlassian.net/browse/NH-65067
elif keys == ["experimental"]:
for exp_k, exp_v in val.items():
if exp_k in self._EXP_KEYS:
exp_v = self.convert_to_bool(exp_v)
if exp_v is None:
logger.warning(
"Ignore invalid config of experimental %s",
exp_k,
)
else:
self.__config["experimental"][exp_k] = exp_v
# TODO Add experimental trace flag, clean up
# https://swicloud.atlassian.net/browse/NH-65067
elif keys == ["experimental_otel_collector"]:
val = self.convert_to_bool(val)
if val is None:
logger.warning(
"Ignore invalid config of experimental otel_collector"
)
else:
self.__config["experimental"]["otel_collector"] = val
elif keys == ["transaction_name"]:
self.__config[key] = val
elif isinstance(sub_dict, dict) and keys[-1] in sub_dict:
Expand Down
39 changes: 21 additions & 18 deletions solarwinds_apm/configurator.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,11 @@ def _configure_otel_components(
if apm_config.agent_enabled:
# set MeterProvider first via metrics_exporter config
self._configure_metrics_exporter(apm_config)
# This processor only defines on_start
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added this and other comments because I keep forgetting the reasons for the processors registration order.

self._configure_service_entry_id_span_processor()

# The txnname calculator span processor must be registered
# before the rest of the processors with defined on_end
self._configure_txnname_calculator_span_processor(
apm_txname_manager,
)
Expand All @@ -129,9 +133,12 @@ def _configure_otel_components(
apm_config,
oboe_api,
)
# The txnname cleanup span processor must be registered
# after the rest of the processors with defined on_end
self._configure_txnname_cleanup_span_processor(
apm_txname_manager,
)

self._configure_traces_exporter(
reporter,
apm_txname_manager,
Expand Down Expand Up @@ -247,12 +254,16 @@ def _configure_otlp_metrics_span_processors(
apm_config: SolarWindsApmConfig,
oboe_api: "OboeAPI",
) -> None:
"""Configure SolarWindsOTLPMetricsSpanProcessor and ForceFlushSpanProcessor."""
# TODO Add experimental trace flag, clean up
# https://swicloud.atlassian.net/browse/NH-65067
if not apm_config.get("experimental").get("otel_collector") is True:
"""Configure SolarWindsOTLPMetricsSpanProcessor (including OTLP meters)
and ForceFlushSpanProcessor, if metrics exporters are configured and set up
i.e. by _configure_metrics_exporter"""
# SolarWindsDistro._configure does setdefault before this is called
environ_exporter = os.environ.get(
OTEL_METRICS_EXPORTER,
)
if not environ_exporter:
logger.debug(
"Experimental otel_collector flag not configured. Not configuring OTLP metrics span processor."
"No OTEL_METRICS_EXPORTER set, skipping init of metrics processors"
)
return

Expand Down Expand Up @@ -341,24 +352,16 @@ def _configure_metrics_exporter(
self,
apm_config: SolarWindsApmConfig,
) -> None:
"""Configure SolarWinds OTel metrics exporters, environment
configured if any, or none if agent disabled."""
if not apm_config.agent_enabled:
logger.error("Tracing disabled. Cannot set metrics exporter.")
return
Comment on lines -346 to -348
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've removed this check because the caller is already doing the enabled check (_configure_otel_components further up)


if not apm_config.get("experimental").get("otel_collector") is True:
logger.debug(
"Experimental otel_collector flag not configured. Not setting metrics exporter."
)
return

"""Configure SolarWinds OTel metrics exporters if any configured.
Links them to new metric readers and global MeterProvider."""
# SolarWindsDistro._configure does setdefault before this is called
environ_exporter = os.environ.get(
OTEL_METRICS_EXPORTER,
)
if not environ_exporter:
logger.debug("No OTEL_METRICS_EXPORTER set, skipping init")
logger.debug(
"No OTEL_METRICS_EXPORTER set, skipping init of metrics exporters"
)
return
environ_exporter_names = environ_exporter.split(",")

Expand Down
2 changes: 1 addition & 1 deletion solarwinds_apm/distro.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def _configure(self, **kwargs):
OTEL_TRACES_EXPORTER, INTL_SWO_DEFAULT_TRACES_EXPORTER_LAMBDA
)
else:
# If experimental flag set, users need to specify OTEL_METRICS_EXPORTER
# Users need to specify OTEL_METRICS_EXPORTER
# or none will be loaded.
environ.setdefault(
OTEL_TRACES_EXPORTER, INTL_SWO_DEFAULT_TRACES_EXPORTER
Expand Down
8 changes: 3 additions & 5 deletions solarwinds_apm/sampler.py
Original file line number Diff line number Diff line change
Expand Up @@ -496,13 +496,11 @@ def calculate_attributes(
f"{decision['bucket_rate']}"
)

# If `experimental` and `otel_collector`,
# If is_lambda,
# always (root or is_remote) set sw.transaction
# TODO Clean up use of experimental trace flag
# https://swicloud.atlassian.net/browse/NH-65067
if self.apm_config.get("experimental").get("otel_collector") is True:
if self.apm_config.is_lambda is True:
logger.debug(
"Experimental otel_collector flag configured. Setting sw.transaction on span."
"APM Python running in lambda. Setting sw.transaction on span."
)
new_attributes[INTL_SWO_TRANSACTION_ATTR_KEY] = (
self.calculate_otlp_transaction_name(span_name)
Expand Down
19 changes: 4 additions & 15 deletions solarwinds_apm/trace/otlp_metrics_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
INTL_SWO_TRANSACTION_ATTR_MAX,
)
from solarwinds_apm.apm_meter_manager import SolarWindsMeterManager
from solarwinds_apm.apm_noop import SolarWindsMeterManager as NoopMeterManager
from solarwinds_apm.trace.base_metrics_processor import _SwBaseMetricsProcessor

if TYPE_CHECKING:
Expand Down Expand Up @@ -42,20 +41,10 @@ def __init__(
# SW_APM_TRANSACTION_NAME and AWS_LAMBDA_FUNCTION_NAME
self.env_transaction_name = apm_config.get("transaction_name")
self.lambda_function_name = apm_config.lambda_function_name

# TODO Add experimental trace flag, clean up
# https://swicloud.atlassian.net/browse/NH-65067
#
if not apm_config.get("experimental").get("otel_collector") is True:
logger.debug(
"Experimental otel_collector flag not configured. Creating meter manager as no-op."
)
self.apm_meters = NoopMeterManager()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is no longer necessary because this processor will not be initialized at all if no OTEL_METRICS_EXPORTER. Keeping the no-op class for now in case new config features/refactor later on.

else:
self.apm_meters = SolarWindsMeterManager(
apm_config,
oboe_api,
)
self.apm_meters = SolarWindsMeterManager(
apm_config,
oboe_api,
)

def calculate_otlp_transaction_name(
self,
Expand Down
98 changes: 0 additions & 98 deletions tests/unit/test_apm_config/test_apm_config_experimental.py

This file was deleted.

53 changes: 1 addition & 52 deletions tests/unit/test_configurator/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,25 +109,9 @@ def mock_meterprovider(mocker):
def get_apmconfig_mocks(
mocker,
enabled=True,
exp_otel_col=True,
is_lambda=False,
md_is_valid=True,
):
mock_get_otelcol = mocker.Mock()
if exp_otel_col == True:
mock_get_otelcol.configure_mock(return_value=True)
else:
mock_get_otelcol.configure_mock(return_value=False)

mock_get_exp = mocker.Mock()
mock_get_exp.configure_mock(
return_value=mocker.Mock(
**{
"get": mock_get_otelcol
}
)
)

# mock the extension that is linked to ApmConfig
mock_ext_config = mocker.Mock()
mock_ext_config.configure_mock(
Expand Down Expand Up @@ -179,7 +163,7 @@ def get_apmconfig_mocks(
mock_apmconfig.configure_mock(
**{
"agent_enabled": enabled,
"get": mock_get_exp,
"get": mocker.Mock(),
"service_name": "foo-service",
"is_lambda": is_lambda,
"extension": mock_ext,
Expand All @@ -195,7 +179,6 @@ def mock_apmconfig_disabled(mocker):
get_apmconfig_mocks(
mocker,
enabled=False,
exp_otel_col=False,
)
)

Expand All @@ -205,7 +188,6 @@ def mock_apmconfig_enabled(mocker):
"solarwinds_apm.configurator.SolarWindsApmConfig",
get_apmconfig_mocks(
mocker,
exp_otel_col=False,
)
)

Expand All @@ -215,18 +197,10 @@ def mock_apmconfig_enabled_md_invalid(mocker):
"solarwinds_apm.configurator.SolarWindsApmConfig",
get_apmconfig_mocks(
mocker,
exp_otel_col=False,
md_is_valid=False,
)
)

@pytest.fixture(name="mock_apmconfig_enabled_expt")
def mock_apmconfig_enabled_expt(mocker):
return mocker.patch(
"solarwinds_apm.configurator.SolarWindsApmConfig",
get_apmconfig_mocks(mocker)
)

@pytest.fixture(name="mock_apmconfig_enabled_is_lambda")
def mock_apmconfig_enabled_is_lambda(mocker):
return mocker.patch(
Expand Down Expand Up @@ -260,31 +234,6 @@ def mock_apmconfig_enabled_reporter_settings(mocker):
)
return mock_apmconfig


@pytest.fixture(name="mock_apmconfig_experimental_otelcol_init")
def mock_apmconfig_experimental_otelcol_init(mocker):
mock_get_inner = mocker.Mock(return_value=True)
mock_inner = mocker.Mock()
mock_inner.configure_mock(
**{
"get": mock_get_inner,
}
)
mock_get_outer = mocker.Mock(return_value=mock_inner)

mock_apmconfig_obj = mocker.Mock()
mock_apmconfig_obj.configure_mock(
**{
"get": mock_get_outer,
"oboe_api": mocker.Mock(),
}
)
mock_apmconfig = mocker.patch(
"solarwinds_apm.configurator.SolarWindsApmConfig",
return_value=mock_apmconfig_obj,
)
return mock_apmconfig

# ==================================================================
# Configurator APM Python extension mocks
# ==================================================================
Expand Down
Loading