Skip to content

Commit 3a4df8b

Browse files
committed
Add support for *.adaptive.sampling_target
1 parent acce187 commit 3a4df8b

File tree

5 files changed

+339
-28
lines changed

5 files changed

+339
-28
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: 60 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -338,10 +338,44 @@ class DistributedTracingSamplerSettings(Settings):
338338

339339

340340
class DistributedTracingSamplerFullGranularitySettings(Settings):
341+
_remote_parent_sampled = "default"
342+
_remote_parent_not_sampled = "default"
343+
344+
345+
class DistributedTracingSamplerFullGranularityRemoteParentSampledSettings:
346+
pass
347+
348+
349+
class DistributedTracingSamplerFullGranularityRemoteParentSampledAdaptiveSettings:
350+
pass
351+
352+
353+
class DistributedTracingSamplerFullGranularityRemoteParentNotSampledSettings:
354+
pass
355+
356+
357+
class DistributedTracingSamplerFullGranularityRemoteParentNotSampledAdaptiveSettings:
341358
pass
342359

343360

344361
class DistributedTracingSamplerPartialGranularitySettings(Settings):
362+
_remote_parent_sampled = "default"
363+
_remote_parent_not_sampled = "default"
364+
365+
366+
class DistributedTracingSamplerPartialGranularityRemoteParentSampledSettings:
367+
pass
368+
369+
370+
class DistributedTracingSamplerPartialGranularityRemoteParentSampledAdaptiveSettings:
371+
pass
372+
373+
374+
class DistributedTracingSamplerPartialGranularityRemoteParentNotSampledSettings:
375+
pass
376+
377+
378+
class DistributedTracingSamplerPartialGranularityRemoteParentNotSampledAdaptiveSettings:
345379
pass
346380

347381

@@ -516,7 +550,15 @@ class EventHarvestConfigHarvestLimitSettings(Settings):
516550
_settings.distributed_tracing = DistributedTracingSettings()
517551
_settings.distributed_tracing.sampler = DistributedTracingSamplerSettings()
518552
_settings.distributed_tracing.sampler.full_granularity = DistributedTracingSamplerFullGranularitySettings()
553+
_settings.distributed_tracing.sampler.full_granularity.remote_parent_sampled = DistributedTracingSamplerFullGranularityRemoteParentSampledSettings()
554+
_settings.distributed_tracing.sampler.full_granularity.remote_parent_sampled.adaptive = DistributedTracingSamplerFullGranularityRemoteParentSampledAdaptiveSettings()
555+
_settings.distributed_tracing.sampler.full_granularity.remote_parent_not_sampled = DistributedTracingSamplerFullGranularityRemoteParentNotSampledSettings()
556+
_settings.distributed_tracing.sampler.full_granularity.remote_parent_not_sampled.adaptive = DistributedTracingSamplerFullGranularityRemoteParentNotSampledAdaptiveSettings()
519557
_settings.distributed_tracing.sampler.partial_granularity = DistributedTracingSamplerPartialGranularitySettings()
558+
_settings.distributed_tracing.sampler.partial_granularity.remote_parent_sampled = DistributedTracingSamplerPartialGranularityRemoteParentSampledSettings()
559+
_settings.distributed_tracing.sampler.partial_granularity.remote_parent_sampled.adaptive = DistributedTracingSamplerPartialGranularityRemoteParentSampledAdaptiveSettings()
560+
_settings.distributed_tracing.sampler.partial_granularity.remote_parent_not_sampled = DistributedTracingSamplerPartialGranularityRemoteParentNotSampledSettings()
561+
_settings.distributed_tracing.sampler.partial_granularity.remote_parent_not_sampled.adaptive = DistributedTracingSamplerPartialGranularityRemoteParentNotSampledAdaptiveSettings()
520562
_settings.error_collector = ErrorCollectorSettings()
521563
_settings.error_collector.attributes = ErrorCollectorAttributesSettings()
522564
_settings.event_harvest_config = EventHarvestConfigSettings()
@@ -561,6 +603,8 @@ class EventHarvestConfigHarvestLimitSettings(Settings):
561603
def _environ_as_int(name, default=0):
562604
val = os.environ.get(name, default)
563605
try:
606+
if default is None and val is None:
607+
return None
564608
return int(val)
565609
except ValueError:
566610
return default
@@ -858,24 +902,36 @@ def default_otlp_host(host):
858902
_settings.distributed_tracing.sampler.full_granularity.enabled = _environ_as_bool(
859903
"NEW_RELIC_DISTRIBUTED_TRACING_SAMPLER_FULL_GRANULARITY_ENABLED", default=True
860904
)
861-
_settings.distributed_tracing.sampler.full_granularity.remote_parent_sampled = os.environ.get(
905+
_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(
862906
"NEW_RELIC_DISTRIBUTED_TRACING_SAMPLER_FULL_GRANULARITY_REMOTE_PARENT_SAMPLED", None
863907
) 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(
908+
_settings.distributed_tracing.sampler.full_granularity.remote_parent_sampled.adaptive.sampling_target = _environ_as_int(
909+
"NEW_RELIC_DISTRIBUTED_TRACING_SAMPLER_FULL_GRANULARITY_REMOTE_PARENT_SAMPLED_ADAPTIVE_SAMPLING_TARGET", None
910+
)
911+
_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(
865912
"NEW_RELIC_DISTRIBUTED_TRACING_SAMPLER_FULL_GRANULARITY_REMOTE_PARENT_NOT_SAMPLED", None
866913
) or os.environ.get("NEW_RELIC_DISTRIBUTED_TRACING_SAMPLER_REMOTE_PARENT_NOT_SAMPLED", "default")
914+
_settings.distributed_tracing.sampler.full_granularity.remote_parent_not_sampled.adaptive.sampling_target = _environ_as_int(
915+
"NEW_RELIC_DISTRIBUTED_TRACING_SAMPLER_FULL_GRANULARITY_REMOTE_PARENT_NOT_SAMPLED_ADAPTIVE_SAMPLING_TARGET", None
916+
)
867917
_settings.distributed_tracing.sampler.partial_granularity.enabled = _environ_as_bool(
868918
"NEW_RELIC_DISTRIBUTED_TRACING_SAMPLER_PARTIAL_GRANULARITY_ENABLED", default=False
869919
)
870920
_settings.distributed_tracing.sampler.partial_granularity.type = os.environ.get(
871921
"NEW_RELIC_DISTRIBUTED_TRACING_SAMPLER_PARTIAL_GRANULARITY_TYPE", "essential"
872922
)
873-
_settings.distributed_tracing.sampler.partial_granularity.remote_parent_sampled = os.environ.get(
923+
_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(
874924
"NEW_RELIC_DISTRIBUTED_TRACING_SAMPLER_PARTIAL_GRANULARITY_REMOTE_PARENT_SAMPLED", "default"
875925
)
876-
_settings.distributed_tracing.sampler.partial_granularity.remote_parent_not_sampled = os.environ.get(
926+
_settings.distributed_tracing.sampler.partial_granularity.remote_parent_sampled.adaptive.sampling_target = _environ_as_int(
927+
"NEW_RELIC_DISTRIBUTED_TRACING_SAMPLER_PARTIAL_GRANULARITY_REMOTE_PARENT_SAMPLED_ADAPTIVE_SAMPLING_TARGET", None
928+
)
929+
_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(
877930
"NEW_RELIC_DISTRIBUTED_TRACING_SAMPLER_PARTIAL_GRANULARITY_REMOTE_PARENT_NOT_SAMPLED", "default"
878931
)
932+
_settings.distributed_tracing.sampler.partial_granularity.remote_parent_not_sampled.adaptive.sampling_target = _environ_as_int(
933+
"NEW_RELIC_DISTRIBUTED_TRACING_SAMPLER_PARTIAL_GRANULARITY_REMOTE_PARENT_NOT_SAMPLED_ADAPTIVE_SAMPLING_TARGET", None
934+
)
879935
_settings.distributed_tracing.exclude_newrelic_header = False
880936
_settings.span_events.enabled = _environ_as_bool("NEW_RELIC_SPAN_EVENTS_ENABLED", default=True)
881937
_settings.event_harvest_config.harvest_limits.span_event_data = _environ_as_int(

tests/agent_features/test_distributed_tracing.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -586,8 +586,8 @@ def test_distributed_trace_remote_parent_sampling_decision_full_granularity(
586586
test_settings = _override_settings.copy()
587587
test_settings.update(
588588
{
589-
"distributed_tracing.sampler.full_granularity.remote_parent_sampled": remote_parent_sampled_setting,
590-
"distributed_tracing.sampler.full_granularity.remote_parent_not_sampled": remote_parent_not_sampled_setting,
589+
"distributed_tracing.sampler.full_granularity._remote_parent_sampled": remote_parent_sampled_setting,
590+
"distributed_tracing.sampler.full_granularity._remote_parent_not_sampled": remote_parent_not_sampled_setting,
591591
"span_events.enabled": True,
592592
}
593593
)
@@ -677,8 +677,8 @@ def test_distributed_trace_remote_parent_sampling_decision_partial_granularity(
677677
{
678678
"distributed_tracing.sampler.full_granularity.enabled": False,
679679
"distributed_tracing.sampler.partial_granularity.enabled": True,
680-
"distributed_tracing.sampler.partial_granularity.remote_parent_sampled": remote_parent_sampled_setting,
681-
"distributed_tracing.sampler.partial_granularity.remote_parent_not_sampled": remote_parent_not_sampled_setting,
680+
"distributed_tracing.sampler.partial_granularity._remote_parent_sampled": remote_parent_sampled_setting,
681+
"distributed_tracing.sampler.partial_granularity._remote_parent_not_sampled": remote_parent_not_sampled_setting,
682682
"span_events.enabled": True,
683683
}
684684
)
@@ -745,8 +745,8 @@ def test_distributed_trace_remote_parent_sampling_decision_between_full_and_part
745745
{
746746
"distributed_tracing.sampler.full_granularity.enabled": full_granularity_enabled,
747747
"distributed_tracing.sampler.partial_granularity.enabled": partial_granularity_enabled,
748-
"distributed_tracing.sampler.full_granularity.remote_parent_sampled": full_granularity_remote_parent_sampled_setting,
749-
"distributed_tracing.sampler.partial_granularity.remote_parent_sampled": partial_granularity_remote_parent_sampled_setting,
748+
"distributed_tracing.sampler.full_granularity._remote_parent_sampled": full_granularity_remote_parent_sampled_setting,
749+
"distributed_tracing.sampler.partial_granularity._remote_parent_sampled": partial_granularity_remote_parent_sampled_setting,
750750
"span_events.enabled": True,
751751
}
752752
)
@@ -815,7 +815,7 @@ def _test():
815815
"distributed_tracing.sampler.full_granularity.enabled": False,
816816
"distributed_tracing.sampler.partial_granularity.enabled": True,
817817
"distributed_tracing.sampler.partial_granularity.type": "compact",
818-
"distributed_tracing.sampler.partial_granularity.remote_parent_sampled": "always_on",
818+
"distributed_tracing.sampler.partial_granularity._remote_parent_sampled": "always_on",
819819
"span_events.enabled": True,
820820
}
821821
)(_test)
@@ -868,7 +868,7 @@ def _test():
868868
"distributed_tracing.sampler.full_granularity.enabled": False,
869869
"distributed_tracing.sampler.partial_granularity.enabled": True,
870870
"distributed_tracing.sampler.partial_granularity.type": "compact",
871-
"distributed_tracing.sampler.partial_granularity.remote_parent_sampled": "always_on",
871+
"distributed_tracing.sampler.partial_granularity._remote_parent_sampled": "always_on",
872872
"span_events.enabled": True,
873873
}
874874
)(_test)
@@ -918,7 +918,7 @@ def _test():
918918
"distributed_tracing.sampler.full_granularity.enabled": False,
919919
"distributed_tracing.sampler.partial_granularity.enabled": True,
920920
"distributed_tracing.sampler.partial_granularity.type": "compact",
921-
"distributed_tracing.sampler.partial_granularity.remote_parent_sampled": "always_on",
921+
"distributed_tracing.sampler.partial_granularity._remote_parent_sampled": "always_on",
922922
"span_events.enabled": True,
923923
}
924924
)(_test)
@@ -972,7 +972,7 @@ def _test():
972972
"distributed_tracing.sampler.full_granularity.enabled": False,
973973
"distributed_tracing.sampler.partial_granularity.enabled": True,
974974
"distributed_tracing.sampler.partial_granularity.type": "reduced",
975-
"distributed_tracing.sampler.partial_granularity.remote_parent_sampled": "always_on",
975+
"distributed_tracing.sampler.partial_granularity._remote_parent_sampled": "always_on",
976976
"span_events.enabled": True,
977977
}
978978
)(_test)
@@ -1026,7 +1026,7 @@ def _test():
10261026
"distributed_tracing.sampler.full_granularity.enabled": False,
10271027
"distributed_tracing.sampler.partial_granularity.enabled": True,
10281028
"distributed_tracing.sampler.partial_granularity.type": "essential",
1029-
"distributed_tracing.sampler.partial_granularity.remote_parent_sampled": "always_on",
1029+
"distributed_tracing.sampler.partial_granularity._remote_parent_sampled": "always_on",
10301030
"span_events.enabled": True,
10311031
}
10321032
)(_test)

0 commit comments

Comments
 (0)