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-11236 sampler creates Service Entry Internal KVs #12

Merged
Merged
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
41 changes: 38 additions & 3 deletions opentelemetry_distro_solarwinds/sampler.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,12 @@
class _SwSampler(Sampler):
"""SolarWinds custom opentelemetry sampler which obeys configuration options provided by the NH/AO Backend."""

_INTERNAL_BUCKET_CAPACITY = "BucketCapacity"
_INTERNAL_BUCKET_RATE = "BucketRate"
_INTERNAL_SAMPLE_RATE = "SampleRate"
_INTERNAL_SAMPLE_SOURCE = "SampleSource"
_INTERNAL_SW_KEYS = "SWKeys"
_LIBOBOE_CONTINUED = -1
_SW_TRACESTATE_CAPTURE_KEY = "sw.w3c.tracestate"
_SW_TRACESTATE_ROOT_KEY = "sw.tracestate_parent_id"
_XTRACEOPTIONS_RESP_AUTH = "auth"
Expand Down Expand Up @@ -119,6 +124,21 @@ def calculate_liboboe_decision(
logger.debug("Got liboboe decision outputs: {}".format(decision))
return decision

def is_decision_continued(
self,
liboboe_decision: Dict
) -> bool:
"""Returns True if liboboe decision is a continued one, else False"""
for val in [
liboboe_decision["rate"],
liboboe_decision["source"],
liboboe_decision["bucket_rate"],
liboboe_decision["bucket_cap"]
]:
if val != self._LIBOBOE_CONTINUED:
return False
return True

def otel_decision_from_liboboe(
self,
liboboe_decision: Dict
Expand Down Expand Up @@ -280,12 +300,23 @@ def calculate_attributes(
if self.otel_decision_from_liboboe(decision) == Decision.DROP:
logger.debug("Trace decision is to drop - not setting attributes")
return None

new_attributes = {}

# Always (root or is_remote) set _INTERNAL_SW_KEYS if injected
internal_sw_keys = xtraceoptions.sw_keys
if internal_sw_keys:
new_attributes[self._INTERNAL_SW_KEYS] = internal_sw_keys

# If not a liboboe continued trace, set service entry internal KVs
if not self.is_decision_continued(decision):
new_attributes[self._INTERNAL_BUCKET_CAPACITY] = "{}".format(decision["bucket_cap"])
new_attributes[self._INTERNAL_BUCKET_RATE] = "{}".format(decision["bucket_rate"])
new_attributes[self._INTERNAL_SAMPLE_RATE] = decision["rate"]
new_attributes[self._INTERNAL_SAMPLE_SOURCE] = decision["source"]
logger.debug(
"Set attributes with service entry internal KVs: {}".format(new_attributes)
)

# Trace's root span has no valid traceparent nor tracestate
# so we can't calculate remaining attributes
Expand All @@ -294,8 +325,12 @@ def calculate_attributes(
"No valid traceparent or no tracestate - returning attributes: {}"
.format(new_attributes)
)
# attributes must be immutable for SamplingResult
return MappingProxyType(new_attributes)

if new_attributes:
# attributes must be immutable for SamplingResult
return MappingProxyType(new_attributes)
else:
return None

if not attributes:
# _SW_TRACESTATE_ROOT_KEY is set once per trace, if possible
Expand Down