Skip to content

Commit

Permalink
chore(telemetry): track remote config values (#6681)
Browse files Browse the repository at this point in the history
- Adds the Remote Config Enabled configuration to the global config
object.
- Ensures ddtrace components use the global config object instead of
directly accessing environment variables.
- Updates tests to use the _remote_config_enabled configuration instead
of directly setting/mocking environment variables.
- Tracks the remote config enabled configuration on application start up

## Checklist

- [x] Change(s) are motivated and described in the PR description.
- [x] Testing strategy is described if automated tests are not included
in the PR.
- [x] Risk is outlined (performance impact, potential for breakage,
maintainability, etc).
- [x] Change is maintainable (easy to change, telemetry, documentation).
- [x] [Library release note
guidelines](https://ddtrace.readthedocs.io/en/stable/releasenotes.html)
are followed. If no release note is required, add label
`changelog/no-changelog`.
- [x] Documentation is included (in-code, generated user docs, [public
corp docs](https://github.com/DataDog/documentation/)).
- [x] Backport labels are set (if
[applicable](https://ddtrace.readthedocs.io/en/latest/contributing.html#backporting))

## Reviewer Checklist

- [ ] Title is accurate.
- [ ] No unnecessary changes are introduced.
- [ ] Description motivates each change.
- [ ] Avoids breaking
[API](https://ddtrace.readthedocs.io/en/stable/versioning.html#interfaces)
changes unless absolutely necessary.
- [ ] Testing strategy adequately addresses listed risk(s).
- [ ] Change is maintainable (easy to change, telemetry, documentation).
- [ ] Release note makes sense to a user of the library.
- [ ] Reviewer has explicitly acknowledged and discussed the performance
implications of this PR as reported in the benchmarks PR comment.
- [ ] Backport labels are set in a manner that is consistent with the
[release branch maintenance
policy](https://ddtrace.readthedocs.io/en/latest/contributing.html#backporting)
  • Loading branch information
mabdinur authored Sep 1, 2023
1 parent f14211c commit cb9e78e
Show file tree
Hide file tree
Showing 20 changed files with 314 additions and 290 deletions.
4 changes: 2 additions & 2 deletions ddtrace/appsec/_capabilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
from typing import Optional

from ddtrace import Tracer
from ddtrace import config as ddconfig
from ddtrace.appsec.utils import _appsec_rc_features_is_enabled
from ddtrace.internal.compat import to_bytes_py2
from ddtrace.internal.utils.formats import asbool


def _appsec_rc_file_is_not_static():
Expand Down Expand Up @@ -37,7 +37,7 @@ def _appsec_rc_capabilities(test_tracer=None):

value = 0b0
result = ""
if asbool(os.environ.get("DD_REMOTE_CONFIGURATION_ENABLED", "true")):
if ddconfig._remote_config_enabled:
if _appsec_rc_features_is_enabled():
value |= 1 << 1 # Enable ASM_ACTIVATION
if tracer._appsec_processor and _appsec_rc_file_is_not_static():
Expand Down
4 changes: 2 additions & 2 deletions ddtrace/appsec/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
from ddtrace.constants import APPSEC_ENV
from ddtrace.internal.compat import parse
from ddtrace.internal.logger import get_logger
from ddtrace.internal.utils.formats import asbool
from ddtrace.internal.utils.http import _get_blocked_template # noqa
from ddtrace.settings import _config as config


if TYPE_CHECKING: # pragma: no cover
Expand Down Expand Up @@ -124,6 +124,6 @@ def access_body(bd):

def _appsec_rc_features_is_enabled():
# type: () -> bool
if asbool(os.environ.get("DD_REMOTE_CONFIGURATION_ENABLED", "true")):
if config._remote_config_enabled:
return APPSEC_ENV not in os.environ
return False
7 changes: 2 additions & 5 deletions ddtrace/bootstrap/sitecustomize.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,15 +243,12 @@ def _(threading):
else:
log.debug("additional sitecustomize found in: %s", sys.path)

if asbool(os.environ.get("DD_REMOTE_CONFIGURATION_ENABLED", "true")):
if config._remote_config_enabled:
from ddtrace.internal.remoteconfig.worker import remoteconfig_poller

remoteconfig_poller.enable()

should_start_appsec_remoteconfig = config._appsec_enabled or asbool(
os.environ.get("DD_REMOTE_CONFIGURATION_ENABLED", "true")
)
if should_start_appsec_remoteconfig:
if config._appsec_enabled or config._remote_config_enabled:
from ddtrace.appsec._remoteconfiguration import enable_appsec_rc

enable_appsec_rc()
Expand Down
6 changes: 3 additions & 3 deletions ddtrace/debugging/_debugger.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from six import PY3

import ddtrace
from ddtrace import config as ddconfig
from ddtrace.debugging._config import di_config
from ddtrace.debugging._config import ed_config
from ddtrace.debugging._encoding import BatchJsonEncoder
Expand Down Expand Up @@ -66,7 +67,6 @@
from ddtrace.internal.remoteconfig.worker import remoteconfig_poller
from ddtrace.internal.safety import _isinstance
from ddtrace.internal.service import Service
from ddtrace.internal.utils.formats import asbool
from ddtrace.internal.wrapping import Wrapper


Expand Down Expand Up @@ -279,8 +279,8 @@ def __init__(self, tracer=None):
if di_config.enabled:
# TODO: this is only temporary and will be reverted once the DD_REMOTE_CONFIGURATION_ENABLED variable
# has been removed
if asbool(os.environ.get("DD_REMOTE_CONFIGURATION_ENABLED", True)) is False:
os.environ["DD_REMOTE_CONFIGURATION_ENABLED"] = "true"
if ddconfig._remote_config_enabled is False:
ddconfig._remote_config_enabled = True
log.info("Disabled Remote Configuration enabled by Dynamic Instrumentation.")

# Register the debugger with the RCM client.
Expand Down
2 changes: 1 addition & 1 deletion ddtrace/internal/debug.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ def collect(tracer):
asm_enabled=ddtrace.config._appsec_enabled,
iast_enabled=ddtrace.config._iast_enabled,
waf_timeout=ddtrace.config._waf_timeout,
remote_config_enabled=os.getenv("DD_REMOTE_CONFIGURATION_ENABLED", "true"),
remote_config_enabled=ddtrace.config._remote_config_enabled,
)


Expand Down
11 changes: 2 additions & 9 deletions ddtrace/internal/remoteconfig/utils.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import os

from ddtrace import config
from ddtrace.vendor.debtcollector import deprecate


DEFAULT_REMOTECONFIG_POLL_SECONDS = 5.0 # seconds


def get_poll_interval_seconds():
# type:() -> float
if os.getenv("DD_REMOTECONFIG_POLL_SECONDS"):
Expand All @@ -14,9 +12,4 @@ def get_poll_interval_seconds():
message="Please use DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS instead.",
removal_version="2.0.0",
)
return float(
os.getenv(
"DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS",
default=os.getenv("DD_REMOTECONFIG_POLL_SECONDS", default=DEFAULT_REMOTECONFIG_POLL_SECONDS),
)
)
return config._remote_config_poll_interval
6 changes: 3 additions & 3 deletions ddtrace/internal/remoteconfig/worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
from ddtrace.internal.remoteconfig.constants import REMOTE_CONFIG_AGENT_ENDPOINT
from ddtrace.internal.remoteconfig.utils import get_poll_interval_seconds
from ddtrace.internal.service import ServiceStatus
from ddtrace.internal.utils.formats import asbool
from ddtrace.internal.utils.time import StopWatch
from ddtrace.settings import _config as ddconfig


log = get_logger(__name__)
Expand Down Expand Up @@ -50,7 +50,7 @@ def _agent_check(self):
self._state = self._online
return

if asbool(os.environ.get("DD_TRACE_DEBUG")) or "DD_REMOTE_CONFIGURATION_ENABLED" in os.environ:
if ddconfig._debug_mode or ddconfig._remote_config_enabled:
LOG_LEVEL = logging.WARNING
else:
LOG_LEVEL = logging.DEBUG
Expand Down Expand Up @@ -86,7 +86,7 @@ def periodic(self):
def enable(self):
# type: () -> bool
# TODO: this is only temporary. DD_REMOTE_CONFIGURATION_ENABLED variable will be deprecated
rc_env_enabled = asbool(os.environ.get("DD_REMOTE_CONFIGURATION_ENABLED", "true"))
rc_env_enabled = ddconfig._remote_config_enabled
if rc_env_enabled and self._enable:
if self.status == ServiceStatus.RUNNING:
return True
Expand Down
1 change: 1 addition & 0 deletions ddtrace/internal/telemetry/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
TELEMETRY_ENABLED = "DD_INSTRUMENTATION_TELEMETRY_ENABLED"
TELEMETRY_RUNTIMEMETRICS_ENABLED = "DD_RUNTIME_METRICS_ENABLED"
TELEMETRY_REMOTE_CONFIGURATION_ENABLED = "DD_REMOTE_CONFIGURATION_ENABLED"
TELEMETRY_REMOTE_CONFIGURATION_INTERVAL = "DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS"
TELEMETRY_SERVICE_MAPPING = "DD_SERVICE_MAPPING"
TELEMETRY_SPAN_SAMPLING_RULES = "DD_SPAN_SAMPLING_RULES"
TELEMETRY_SPAN_SAMPLING_RULES_FILE = "DD_SPAN_SAMPLING_RULES_FILE"
Expand Down
4 changes: 4 additions & 0 deletions ddtrace/internal/telemetry/writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@
from .constants import TELEMETRY_PROFILING_ENABLED
from .constants import TELEMETRY_PROPAGATION_STYLE_EXTRACT
from .constants import TELEMETRY_PROPAGATION_STYLE_INJECT
from .constants import TELEMETRY_REMOTE_CONFIGURATION_ENABLED
from .constants import TELEMETRY_REMOTE_CONFIGURATION_INTERVAL
from .constants import TELEMETRY_RUNTIMEMETRICS_ENABLED
from .constants import TELEMETRY_SERVICE_MAPPING
from .constants import TELEMETRY_SPAN_SAMPLING_RULES
Expand Down Expand Up @@ -322,6 +324,8 @@ def _app_started_event(self):
(TELEMETRY_OTEL_ENABLED, config._otel_enabled, "unknown"),
(TELEMETRY_TRACE_HEALTH_METRICS_ENABLED, config.health_metrics_enabled, "unknown"),
(TELEMETRY_RUNTIMEMETRICS_ENABLED, config._runtime_metrics_enabled, "unknown"),
(TELEMETRY_REMOTE_CONFIGURATION_ENABLED, config._remote_config_enabled, "unknown"),
(TELEMETRY_REMOTE_CONFIGURATION_INTERVAL, config._remote_config_poll_interval, "unknown"),
(TELEMETRY_TRACE_SAMPLING_RATE, config._trace_sample_rate, "unknown"),
(TELEMETRY_TRACE_SAMPLING_LIMIT, config._trace_rate_limit, "unknown"),
(TELEMETRY_SPAN_SAMPLING_RULES, config._sampling_rules, "unknown"),
Expand Down
3 changes: 1 addition & 2 deletions ddtrace/internal/writer/writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
from .. import service
from ...constants import KEEP_SPANS_RATE_KEY
from ...internal.telemetry import telemetry_writer
from ...internal.utils.formats import asbool
from ...internal.utils.formats import parse_tags_str
from ...internal.utils.http import Response
from ...internal.utils.time import StopWatch
Expand Down Expand Up @@ -644,7 +643,7 @@ def start(self):
# appsec remote config should be enabled/started after the global tracer and configs
# are initialized
if os.getenv("AWS_LAMBDA_FUNCTION_NAME") is None and (
config._appsec_enabled or asbool(os.getenv("DD_REMOTE_CONFIGURATION_ENABLED", "true"))
config._appsec_enabled or config._remote_config_enabled
):
from ddtrace.appsec._remoteconfiguration import enable_appsec_rc

Expand Down
6 changes: 6 additions & 0 deletions ddtrace/settings/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,12 @@ def __init__(self):
header_tags = parse_tags_str(os.getenv("DD_TRACE_HEADER_TAGS", ""))
self.http = HttpConfig(header_tags=header_tags)
self._tracing_enabled = asbool(os.getenv("DD_TRACE_ENABLED", default=True))
self._remote_config_enabled = asbool(os.getenv("DD_REMOTE_CONFIGURATION_ENABLED", default=True))
self._remote_config_poll_interval = float(
os.getenv(
"DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS", default=os.getenv("DD_REMOTECONFIG_POLL_SECONDS", default=5.0)
)
)
self._trace_api = os.getenv("DD_TRACE_API_VERSION")
self._trace_writer_buffer_size = int(
os.getenv("DD_TRACE_WRITER_BUFFER_SIZE_BYTES", default=DEFAULT_BUFFER_SIZE)
Expand Down
Loading

0 comments on commit cb9e78e

Please sign in to comment.