Skip to content

Commit c5c315b

Browse files
committed
Add support for *.adaptive.sampling_target
1 parent 1c01dc5 commit c5c315b

File tree

5 files changed

+364
-27
lines changed

5 files changed

+364
-27
lines changed

newrelic/api/transaction.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1084,8 +1084,8 @@ def _make_sampling_decision(self):
10841084
priority,
10851085
sampled,
10861086
full_granularity=True,
1087-
remote_parent_sampled_setting=self.settings.distributed_tracing.sampler.full_granularity.remote_parent_sampled,
1088-
remote_parent_not_sampled_setting=self.settings.distributed_tracing.sampler.full_granularity.remote_parent_not_sampled,
1087+
remote_parent_sampled_setting=self.settings.distributed_tracing.sampler.full_granularity._remote_parent_sampled,
1088+
remote_parent_not_sampled_setting=self.settings.distributed_tracing.sampler.full_granularity._remote_parent_not_sampled,
10891089
)
10901090
_logger.debug("Full granularity sampling decision was %s with priority=%s.", sampled, priority)
10911091
if computed_sampled or not self.settings.distributed_tracing.sampler.partial_granularity.enabled:
@@ -1101,8 +1101,8 @@ def _make_sampling_decision(self):
11011101
priority,
11021102
sampled,
11031103
full_granularity=False,
1104-
remote_parent_sampled_setting=self.settings.distributed_tracing.sampler.partial_granularity.remote_parent_sampled,
1105-
remote_parent_not_sampled_setting=self.settings.distributed_tracing.sampler.partial_granularity.remote_parent_not_sampled,
1104+
remote_parent_sampled_setting=self.settings.distributed_tracing.sampler.partial_granularity._remote_parent_sampled,
1105+
remote_parent_not_sampled_setting=self.settings.distributed_tracing.sampler.partial_granularity._remote_parent_not_sampled,
11061106
)
11071107
_logger.debug(
11081108
"Partial granularity sampling decision was %s with priority=%s.", self._sampled, self._priority

newrelic/config.py

Lines changed: 111 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,11 @@ def _process_dt_setting(section, option_p1, option_p2, getter):
337337
while True:
338338
if len(fields) == 1:
339339
value = value1 or value2 or "default"
340-
setattr(target, fields[0], value)
340+
# Store the value at the underscored location so if option_p1 is
341+
# distributed_tracing.sampler.full_granularity.remote_parent_sampled
342+
# store it at location
343+
# distributed_tracing.sampler.full_granularity._remote_parent_sampled
344+
setattr(target, f"_{fields[0]}", value)
341345
break
342346
target = getattr(target, fields[0])
343347
fields = fields[1].split(".", 1)
@@ -360,6 +364,90 @@ def _process_dt_setting(section, option_p1, option_p2, getter):
360364
_raise_configuration_error(section, option_p1)
361365

362366

367+
def _process_dt_hidden_setting(section, option, getter):
368+
try:
369+
# The type of a value is dictated by the getter
370+
# function supplied.
371+
372+
value = getattr(_config_object, getter)(section, option)
373+
374+
# Now need to apply the option from the
375+
# configuration file to the internal settings
376+
# object. Walk the object path and assign it.
377+
378+
target = _settings
379+
fields = option.split(".", 1)
380+
381+
while True:
382+
if len(fields) == 1:
383+
value = value or "default"
384+
# Store the value at the underscored location so if option is
385+
# distributed_tracing.sampler.full_granularity.remote_parent_sampled
386+
# store it at location
387+
# distributed_tracing.sampler.full_granularity._remote_parent_sampled
388+
setattr(target, f"_{fields[0]}", value)
389+
break
390+
target = getattr(target, fields[0])
391+
fields = fields[1].split(".", 1)
392+
393+
# Cache the configuration so can be dumped out to
394+
# log file when whole main configuration has been
395+
# processed. This ensures that the log file and log
396+
# level entries have been set.
397+
398+
_cache_object.append((option, value))
399+
400+
except configparser.NoSectionError:
401+
pass
402+
403+
except configparser.NoOptionError:
404+
pass
405+
406+
except Exception:
407+
_raise_configuration_error(section, option_p1)
408+
409+
def _process_dt_sampler_setting(section, option, getter):
410+
try:
411+
# The type of a value is dictated by the getter
412+
# function supplied.
413+
414+
value = getattr(_config_object, getter)(section, option)
415+
416+
# Now need to apply the option from the
417+
# configuration file to the internal settings
418+
# object. Walk the object path and assign it.
419+
420+
target = _settings
421+
fields = option.split(".", 1)
422+
423+
while True:
424+
if len(fields) == 1:
425+
setattr(target, f"{fields[0]}", value)
426+
break
427+
elif fields[0] in ("root", "remote_parent_sampled", "remote_parent_not_sampled"):
428+
sampler = fields[1].split(".", 1)[0]
429+
setattr(target, f"_{fields[0]}", sampler)
430+
target = getattr(target, fields[0])
431+
fields = fields[1].split(".", 1)
432+
433+
434+
# Cache the configuration so can be dumped out to
435+
# log file when whole main configuration has been
436+
# processed. This ensures that the log file and log
437+
# level entries have been set.
438+
439+
_cache_object.append((option, value))
440+
441+
except configparser.NoSectionError:
442+
pass
443+
444+
except configparser.NoOptionError:
445+
pass
446+
447+
except Exception:
448+
_raise_configuration_error(section, option)
449+
450+
363451
# Processing of all the settings for specified section except
364452
# for log file and log level which are applied separately to
365453
# ensure they are set as soon as possible.
@@ -452,17 +540,37 @@ def _process_configuration(section):
452540
"distributed_tracing.sampler.remote_parent_sampled",
453541
"get",
454542
)
543+
_process_dt_sampler_setting(
544+
section,
545+
"distributed_tracing.sampler.full_granularity.remote_parent_sampled.adaptive.sampling_target",
546+
"getint",
547+
)
455548
_process_dt_setting(
456549
section,
457550
"distributed_tracing.sampler.full_granularity.remote_parent_not_sampled",
458551
"distributed_tracing.sampler.remote_parent_not_sampled",
459552
"get",
460553
)
554+
_process_dt_sampler_setting(
555+
section,
556+
"distributed_tracing.sampler.full_granularity.remote_parent_not_sampled.adaptive.sampling_target",
557+
"getint",
558+
)
461559
_process_setting(section, "distributed_tracing.sampler.full_granularity.enabled", "getboolean", None)
462560
_process_setting(section, "distributed_tracing.sampler.partial_granularity.enabled", "getboolean", None)
463561
_process_setting(section, "distributed_tracing.sampler.partial_granularity.type", "get", None)
464-
_process_setting(section, "distributed_tracing.sampler.partial_granularity.remote_parent_sampled", "get", None)
465-
_process_setting(section, "distributed_tracing.sampler.partial_granularity.remote_parent_not_sampled", "get", None)
562+
_process_dt_hidden_setting(section, "distributed_tracing.sampler.partial_granularity.remote_parent_sampled", "get")
563+
_process_dt_sampler_setting(
564+
section,
565+
"distributed_tracing.sampler.partial_granularity.remote_parent_sampled.adaptive.sampling_target",
566+
"getint",
567+
)
568+
_process_dt_hidden_setting(section, "distributed_tracing.sampler.partial_granularity.remote_parent_not_sampled", "get")
569+
_process_dt_sampler_setting(
570+
section,
571+
"distributed_tracing.sampler.partial_granularity.remote_parent_not_sampled.adaptive.sampling_target",
572+
"getint",
573+
)
466574
_process_setting(section, "span_events.enabled", "getboolean", None)
467575
_process_setting(section, "span_events.max_samples_stored", "getint", None)
468576
_process_setting(section, "span_events.attributes.enabled", "getboolean", None)

newrelic/core/config.py

Lines changed: 102 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -336,12 +336,87 @@ class DistributedTracingSettings(Settings):
336336
class DistributedTracingSamplerSettings(Settings):
337337
pass
338338

339-
340339
class DistributedTracingSamplerFullGranularitySettings(Settings):
340+
_remote_parent_sampled = "default"
341+
_remote_parent_not_sampled = "default"
342+
#@property
343+
#def remote_parent_sampled(self):
344+
# return self._remote_parent_sampled
345+
346+
#@remote_parent_sampled.setter
347+
#def remote_parent_sampled(self, value):
348+
# if isinstance(value, str):
349+
# self._remote_parent_sampled._sampler = value
350+
# else:
351+
# self._remote_parent_sampled = value
352+
353+
#@property
354+
#def remote_parent_not_sampled(self):
355+
# return self._remote_parent_not_sampled
356+
357+
#@remote_parent_not_sampled.setter
358+
#def remote_parent_not_sampled(self, value):
359+
# if isinstance(value, str):
360+
# self._remote_parent_not_sampled._sampler = value
361+
# else:
362+
# self._remote_parent_not_sampled = value
363+
364+
365+
class DistributedTracingSamplerFullGranularityRemoteParentSampledSettings:
366+
pass
367+
368+
369+
class DistributedTracingSamplerFullGranularityRemoteParentSampledAdaptiveSettings:
370+
pass
371+
372+
373+
class DistributedTracingSamplerFullGranularityRemoteParentNotSampledSettings:
374+
pass
375+
376+
377+
class DistributedTracingSamplerFullGranularityRemoteParentNotSampledAdaptiveSettings:
341378
pass
342379

343380

344381
class DistributedTracingSamplerPartialGranularitySettings(Settings):
382+
_remote_parent_sampled = "default"
383+
_remote_parent_not_sampled = "default"
384+
#@property
385+
#def remote_parent_sampled(self):
386+
# return self._remote_parent_sampled
387+
388+
#@remote_parent_sampled.setter
389+
#def remote_parent_sampled(self, value):
390+
# if isinstance(value, str):
391+
# self._remote_parent_sampled._sampler = value
392+
# else:
393+
# self._remote_parent_sampled = value
394+
395+
#@property
396+
#def remote_parent_not_sampled(self):
397+
# return self._remote_parent_not_sampled
398+
399+
#@remote_parent_not_sampled.setter
400+
#def remote_parent_not_sampled(self, value):
401+
# if isinstance(value, str):
402+
# self._remote_parent_not_sampled._sampler = value
403+
# else:
404+
# self._remote_parent_not_sampled = value
405+
406+
407+
class DistributedTracingSamplerPartialGranularityRemoteParentSampledSettings:
408+
pass #_sampler = None
409+
410+
411+
class DistributedTracingSamplerPartialGranularityRemoteParentSampledAdaptiveSettings:
412+
pass
413+
414+
415+
class DistributedTracingSamplerPartialGranularityRemoteParentNotSampledSettings:
416+
pass #_sampler = None
417+
418+
419+
class DistributedTracingSamplerPartialGranularityRemoteParentNotSampledAdaptiveSettings:
345420
pass
346421

347422

@@ -516,7 +591,15 @@ class EventHarvestConfigHarvestLimitSettings(Settings):
516591
_settings.distributed_tracing = DistributedTracingSettings()
517592
_settings.distributed_tracing.sampler = DistributedTracingSamplerSettings()
518593
_settings.distributed_tracing.sampler.full_granularity = DistributedTracingSamplerFullGranularitySettings()
594+
_settings.distributed_tracing.sampler.full_granularity.remote_parent_sampled = DistributedTracingSamplerFullGranularityRemoteParentSampledSettings()
595+
_settings.distributed_tracing.sampler.full_granularity.remote_parent_sampled.adaptive = DistributedTracingSamplerFullGranularityRemoteParentSampledAdaptiveSettings()
596+
_settings.distributed_tracing.sampler.full_granularity.remote_parent_not_sampled = DistributedTracingSamplerFullGranularityRemoteParentNotSampledSettings()
597+
_settings.distributed_tracing.sampler.full_granularity.remote_parent_not_sampled.adaptive = DistributedTracingSamplerFullGranularityRemoteParentNotSampledAdaptiveSettings()
519598
_settings.distributed_tracing.sampler.partial_granularity = DistributedTracingSamplerPartialGranularitySettings()
599+
_settings.distributed_tracing.sampler.partial_granularity.remote_parent_sampled = DistributedTracingSamplerPartialGranularityRemoteParentSampledSettings()
600+
_settings.distributed_tracing.sampler.partial_granularity.remote_parent_sampled.adaptive = DistributedTracingSamplerPartialGranularityRemoteParentSampledAdaptiveSettings()
601+
_settings.distributed_tracing.sampler.partial_granularity.remote_parent_not_sampled = DistributedTracingSamplerPartialGranularityRemoteParentNotSampledSettings()
602+
_settings.distributed_tracing.sampler.partial_granularity.remote_parent_not_sampled.adaptive = DistributedTracingSamplerPartialGranularityRemoteParentNotSampledAdaptiveSettings()
520603
_settings.error_collector = ErrorCollectorSettings()
521604
_settings.error_collector.attributes = ErrorCollectorAttributesSettings()
522605
_settings.event_harvest_config = EventHarvestConfigSettings()
@@ -561,6 +644,8 @@ class EventHarvestConfigHarvestLimitSettings(Settings):
561644
def _environ_as_int(name, default=0):
562645
val = os.environ.get(name, default)
563646
try:
647+
if default is None and val is None:
648+
return None
564649
return int(val)
565650
except ValueError:
566651
return default
@@ -858,24 +943,36 @@ def default_otlp_host(host):
858943
_settings.distributed_tracing.sampler.full_granularity.enabled = _environ_as_bool(
859944
"NEW_RELIC_DISTRIBUTED_TRACING_SAMPLER_FULL_GRANULARITY_ENABLED", default=True
860945
)
861-
_settings.distributed_tracing.sampler.full_granularity.remote_parent_sampled = os.environ.get(
946+
_settings.distributed_tracing.sampler.full_granularity._remote_parent_sampled = ("adaptive" if os.environ.get("NEW_RELIC_DISTRIBUTED_TRACING_SAMPLER_FULL_GRANULARITY_REMOTE_PARENT_SAMPLED_ADAPTIVE_SAMPLING_TARGET", None) else None) or os.environ.get(
862947
"NEW_RELIC_DISTRIBUTED_TRACING_SAMPLER_FULL_GRANULARITY_REMOTE_PARENT_SAMPLED", None
863948
) or os.environ.get("NEW_RELIC_DISTRIBUTED_TRACING_SAMPLER_REMOTE_PARENT_SAMPLED", "default")
864-
_settings.distributed_tracing.sampler.full_granularity.remote_parent_not_sampled = os.environ.get(
949+
_settings.distributed_tracing.sampler.full_granularity.remote_parent_sampled.adaptive.sampling_target = _environ_as_int(
950+
"NEW_RELIC_DISTRIBUTED_TRACING_SAMPLER_FULL_GRANULARITY_REMOTE_PARENT_SAMPLED_ADAPTIVE_SAMPLING_TARGET", None
951+
)
952+
_settings.distributed_tracing.sampler.full_granularity._remote_parent_not_sampled = ("adaptive" if os.environ.get("NEW_RELIC_DISTRIBUTED_TRACING_SAMPLER_FULL_GRANULARITY_REMOTE_PARENT_NOT_SAMPLED_ADAPTIVE_SAMPLING_TARGET", None) else None) or os.environ.get(
865953
"NEW_RELIC_DISTRIBUTED_TRACING_SAMPLER_FULL_GRANULARITY_REMOTE_PARENT_NOT_SAMPLED", None
866954
) or os.environ.get("NEW_RELIC_DISTRIBUTED_TRACING_SAMPLER_REMOTE_PARENT_NOT_SAMPLED", "default")
955+
_settings.distributed_tracing.sampler.full_granularity.remote_parent_not_sampled.adaptive.sampling_target = _environ_as_int(
956+
"NEW_RELIC_DISTRIBUTED_TRACING_SAMPLER_FULL_GRANULARITY_REMOTE_PARENT_NOT_SAMPLED_ADAPTIVE_SAMPLING_TARGET", None
957+
)
867958
_settings.distributed_tracing.sampler.partial_granularity.enabled = _environ_as_bool(
868959
"NEW_RELIC_DISTRIBUTED_TRACING_SAMPLER_PARTIAL_GRANULARITY_ENABLED", default=False
869960
)
870961
_settings.distributed_tracing.sampler.partial_granularity.type = os.environ.get(
871962
"NEW_RELIC_DISTRIBUTED_TRACING_SAMPLER_PARTIAL_GRANULARITY_TYPE", "essential"
872963
)
873-
_settings.distributed_tracing.sampler.partial_granularity.remote_parent_sampled = os.environ.get(
964+
_settings.distributed_tracing.sampler.partial_granularity._remote_parent_sampled = ("adaptive" if os.environ.get("NEW_RELIC_DISTRIBUTED_TRACING_SAMPLER_PARTIAL_GRANULARITY_REMOTE_PARENT_SAMPLED_ADAPTIVE_SAMPLING_TARGET", None) else None) or os.environ.get(
874965
"NEW_RELIC_DISTRIBUTED_TRACING_SAMPLER_PARTIAL_GRANULARITY_REMOTE_PARENT_SAMPLED", "default"
875966
)
876-
_settings.distributed_tracing.sampler.partial_granularity.remote_parent_not_sampled = os.environ.get(
967+
_settings.distributed_tracing.sampler.partial_granularity.remote_parent_sampled.adaptive.sampling_target = _environ_as_int(
968+
"NEW_RELIC_DISTRIBUTED_TRACING_SAMPLER_PARTIAL_GRANULARITY_REMOTE_PARENT_SAMPLED_ADAPTIVE_SAMPLING_TARGET", None
969+
)
970+
_settings.distributed_tracing.sampler.partial_granularity._remote_parent_not_sampled = ("adaptive" if os.environ.get("NEW_RELIC_DISTRIBUTED_TRACING_SAMPLER_PARTIAL_GRANULARITY_REMOTE_PARENT_NOT_SAMPLED_ADAPTIVE_SAMPLING_TARGET", None) else None) or os.environ.get(
877971
"NEW_RELIC_DISTRIBUTED_TRACING_SAMPLER_PARTIAL_GRANULARITY_REMOTE_PARENT_NOT_SAMPLED", "default"
878972
)
973+
_settings.distributed_tracing.sampler.partial_granularity.remote_parent_not_sampled.adaptive.sampling_target = _environ_as_int(
974+
"NEW_RELIC_DISTRIBUTED_TRACING_SAMPLER_PARTIAL_GRANULARITY_REMOTE_PARENT_NOT_SAMPLED_ADAPTIVE_SAMPLING_TARGET", None
975+
)
879976
_settings.distributed_tracing.exclude_newrelic_header = False
880977
_settings.span_events.enabled = _environ_as_bool("NEW_RELIC_SPAN_EVENTS_ENABLED", default=True)
881978
_settings.event_harvest_config.harvest_limits.span_event_data = _environ_as_int(

0 commit comments

Comments
 (0)