diff --git a/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/sampler/README.md b/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/sampler/README.md deleted file mode 100644 index b66fb6c02..000000000 --- a/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/sampler/README.md +++ /dev/null @@ -1,14 +0,0 @@ - - - - -Usage: -``` - -from amazon.opentelemetry.distro.sampler.aws_xray_remote_sampler import AwsXRayRemoteSampler - -trace.set_tracer_provider(TracerProvider(sampler=ParentBased(xray_sampler))) -tracer = trace.get_tracer(__name__) - - -``` \ No newline at end of file diff --git a/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/sampler/_fallback_sampler.py b/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/sampler/_fallback_sampler.py index 63289f11c..3dd43166e 100644 --- a/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/sampler/_fallback_sampler.py +++ b/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/sampler/_fallback_sampler.py @@ -1,16 +1,9 @@ # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0 -import time from typing import Optional, Sequence from opentelemetry.context import Context -from opentelemetry.sdk.trace.sampling import ( - Decision, - Sampler, - SamplingResult, - TraceIdRatioBased, - _get_parent_trace_state, -) +from opentelemetry.sdk.trace.sampling import ALWAYS_ON, Sampler, SamplingResult, TraceIdRatioBased from opentelemetry.trace import Link, SpanKind from opentelemetry.trace.span import TraceState from opentelemetry.util.types import Attributes @@ -18,11 +11,8 @@ class _FallbackSampler(Sampler): def __init__(self): - # Override default log level - self.__default_sampler = TraceIdRatioBased(0.05) - self.__last_take = -1 - - # Add Reservoir and Ratio samplers + # TODO: Add Reservoir sampler + self.__fixed_rate_sampler = TraceIdRatioBased(0.05) # pylint: disable=no-self-use def should_sample( @@ -35,13 +25,8 @@ def should_sample( links: Sequence[Link] = None, trace_state: TraceState = None, ) -> SamplingResult: - # TODO: add sampling functionality - current_time = time.process_time() - if current_time - self.__last_take >= 1.0: - res = SamplingResult(Decision.RECORD_AND_SAMPLE, trace_state=_get_parent_trace_state(parent_context)) - self.__last_take = time.process_time() - return res - return self.__default_sampler.should_sample( + # TODO: add reservoir + fixed rate sampling + return ALWAYS_ON.should_sample( parent_context, trace_id, name, kind=kind, attributes=attributes, links=links, trace_state=trace_state ) diff --git a/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/sampler/_reservoir_sampler.py b/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/sampler/_reservoir_sampler.py deleted file mode 100644 index 7c3cee577..000000000 --- a/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/sampler/_reservoir_sampler.py +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. -# SPDX-License-Identifier: Apache-2.0 -from typing import Optional, Sequence - -from opentelemetry.context import Context -from opentelemetry.sdk.trace.sampling import Sampler, SamplingResult -from opentelemetry.trace import Link, SpanKind -from opentelemetry.trace.span import TraceState -from opentelemetry.util.types import Attributes - -DEFAULT_RULES_POLLING_INTERVAL = 300 -DEFAULT_TARGET_POLLING_INTERVAL = 10 -DEFAULT_SAMPLING_PROXY_ENDPOINT = "http://127.0.0.1:2000" - - -class _ReservoirSampler(Sampler): - def __init__( - self, - quota=None, - ): - self.quota = quota - self.quota_balance = 0 - - # pylint: disable=no-self-use - def should_sample( - self, - parent_context: Optional[Context], - trace_id: int, - name: str, - kind: SpanKind = None, - attributes: Attributes = None, - links: Sequence[Link] = None, - trace_state: TraceState = None, - ) -> SamplingResult: - # TODO: add sampling functionality - pass diff --git a/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/sampler/_rule.py b/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/sampler/_rule.py index ec283fe65..2084d83be 100644 --- a/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/sampler/_rule.py +++ b/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/sampler/_rule.py @@ -18,12 +18,12 @@ class _Rule: def __init__(self, sampling_rule): self.sampling_rule = sampling_rule - # self.fixed_rate_sampler = None self.statistics = _SamplingStatisticsDocument(0, 0, 0) self.next_target_fetch_time = time.process_time() - # TODO change to rate limiter given rate, add fallback sampler, no need parent based - self.rervoir_sampler = ALWAYS_ON + # TODO change to rate limiter given rate, add fixed rate sampler + self.reservoir_sampler = ALWAYS_ON + # self.fixed_rate_sampler = None def should_sample( self, @@ -35,40 +35,25 @@ def should_sample( links: Sequence[Link] = None, trace_state: TraceState = None, ) -> SamplingResult: - return self.rervoir_sampler.should_sample( + return self.reservoir_sampler.should_sample( parent_context, trace_id, name, kind=kind, attributes=attributes, links=links, trace_state=trace_state ) - # res = SamplingResult(Decision.RECORD_AND_SAMPLE, trace_state=_get_parent_trace_state(parent_context)) - # return res - # pass def matches(self, resource: Resource, attributes: Attributes): - http_target = None # - http_url = None # - http_method = None # - http_host = None # - service_name = None # - - # URL_PATH or URL_QUERY - # HTTP_REQUEST_METHOD - # URL_FULL - # SERVER_ADDRESS or SERVER_PORT - # PEER_SERVICE - - print( - "%s %s %s %s ", - SpanAttributes.HTTP_TARGET, - SpanAttributes.HTTP_METHOD, - SpanAttributes.HTTP_URL, - SpanAttributes.HTTP_HOST, - ) + http_target = None + http_url = None + http_method = None + http_host = None + service_name = None if attributes is not None: - print("attributes is not None") http_target = attributes.get(SpanAttributes.HTTP_TARGET, None) http_method = attributes.get(SpanAttributes.HTTP_METHOD, None) http_url = attributes.get(SpanAttributes.HTTP_URL, None) http_host = attributes.get(SpanAttributes.HTTP_HOST, None) + # NOTE: The above span attribute keys are deprecated in favor of: + # URL_PATH/URL_QUERY, HTTP_REQUEST_METHOD, URL_FULL, SERVER_ADDRESS/SERVER_PORT + # For now, the old attribut keys are kept for consistency with other centralized samplers service_name = resource.attributes.get(ResourceAttributes.SERVICE_NAME, "") @@ -84,49 +69,6 @@ def matches(self, resource: Resource, attributes: Attributes): else: http_target = http_url[path_index:] - print( - "%s %s %s", - _Matcher.attribute_match(attributes, self.sampling_rule.Attributes), - attributes, - " - ", - self.sampling_rule.Attributes, - ) - print( - "%s %s %s", - _Matcher.wild_card_match(http_target, self.sampling_rule.URLPath), - http_target, - " - ", - self.sampling_rule.URLPath, - ) - print( - "%s %s %s", - _Matcher.wild_card_match(http_method, self.sampling_rule.HTTPMethod), - http_method, - " - ", - self.sampling_rule.HTTPMethod, - ) - print( - "%s %s %s", - _Matcher.wild_card_match(http_host, self.sampling_rule.Host), - http_host, - " - ", - self.sampling_rule.Host, - ) - print( - "%s %s %s", - _Matcher.wild_card_match(service_name, self.sampling_rule.ServiceName), - service_name, - " - ", - self.sampling_rule.ServiceName, - ) - print( - "%s %s %s", - _Matcher.wild_card_match(self.get_service_type(resource), self.sampling_rule.ServiceType), - self.get_service_type(resource), - " - ", - self.sampling_rule.ServiceType, - ) - return ( _Matcher.attribute_match(attributes, self.sampling_rule.Attributes) and _Matcher.wild_card_match(http_target, self.sampling_rule.URLPath) @@ -134,7 +76,6 @@ def matches(self, resource: Resource, attributes: Attributes): and _Matcher.wild_card_match(http_host, self.sampling_rule.Host) and _Matcher.wild_card_match(service_name, self.sampling_rule.ServiceName) and _Matcher.wild_card_match(self.get_service_type(resource), self.sampling_rule.ServiceType) - # _Matcher.wild_card_match(self.get_arn(attributes, resource), self.sampling_rule.ResourceARN) # no support ) # pylint: disable=no-self-use diff --git a/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/sampler/_rule_cache.py b/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/sampler/_rule_cache.py index d19245967..74722f210 100644 --- a/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/sampler/_rule_cache.py +++ b/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/sampler/_rule_cache.py @@ -26,7 +26,6 @@ def __init__(self, resource: Resource, fallback_sampler: _FallbackSampler, lock: self.resource = resource self._fallback_sampler = fallback_sampler self._last_modified = datetime.datetime.now() - print(self._last_modified.timestamp()) def should_sample( self, @@ -39,10 +38,7 @@ def should_sample( trace_state: TraceState = None, ): for rule in self.rules: - print("Trying: %s", rule.sampling_rule.RuleName) if rule.matches(self.resource, attributes): - - print("Matched with: %s", rule.sampling_rule.RuleName) return rule.should_sample( parent_context, trace_id, @@ -74,6 +70,7 @@ def update_sampling_rules(self, new_sampling_rules): # map list of rules by each rule's sampling_rule name rule_map = {rule.sampling_rule.RuleName: rule for rule in self.rules} + # If a sampling rule has not changed, keep its respective rule in the cache. for index, new_rule in enumerate(temp_rules): rule_name_to_check = new_rule.sampling_rule.RuleName if rule_name_to_check in rule_map: diff --git a/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/sampler/_sampling_rule.py b/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/sampler/_sampling_rule.py index 075299d1b..b088a14c8 100644 --- a/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/sampler/_sampling_rule.py +++ b/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/sampler/_sampling_rule.py @@ -38,7 +38,7 @@ def __init__( def __lt__(self, other): if self.Priority == other.Priority: # String order priority example: - # "A","Abc","ab","abc","abcdef" + # "A","Abc","a","ab","abc","abcdef" return self.RuleName < other.RuleName return self.Priority < other.Priority diff --git a/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/sampler/_sampling_statistics_document.py b/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/sampler/_sampling_statistics_document.py deleted file mode 100644 index 350f19192..000000000 --- a/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/sampler/_sampling_statistics_document.py +++ /dev/null @@ -1,11 +0,0 @@ -# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. -# SPDX-License-Identifier: Apache-2.0 - - -# Disable snake_case naming style so this class can match the statistics document response from X-Ray -# pylint: disable=invalid-name -class _SamplingStatisticsDocument: - def __init__(self, RequestCount, BorrowCount, SampleCount): - self.RequestCount = RequestCount - self.BorrowCount = BorrowCount - self.SampleCount = SampleCount diff --git a/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/sampler/aws_xray_remote_sampler.py b/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/sampler/aws_xray_remote_sampler.py index c99383e41..42655a822 100644 --- a/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/sampler/aws_xray_remote_sampler.py +++ b/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/sampler/aws_xray_remote_sampler.py @@ -1,5 +1,6 @@ # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0 +import random from logging import getLogger from threading import Lock, Timer from typing import Optional, Sequence @@ -34,7 +35,6 @@ class AwsXRayRemoteSampler(Sampler): log_level: custom log level configuration for remote sampler (Optional) """ - # __resource: Resource __polling_interval: int __xray_client: _AwsXRaySamplingClient @@ -50,7 +50,7 @@ def __init__( _logger.setLevel(log_level) self.__xray_client = _AwsXRaySamplingClient(endpoint, log_level=log_level) - self.__rule_polling_jitter = 0 # random.uniform(0.0, 5.0) + self.__rule_polling_jitter = random.uniform(0.0, 5.0) self.__polling_interval = polling_interval self.__fallback_sampler = _FallbackSampler() @@ -83,6 +83,7 @@ def should_sample( ) -> SamplingResult: if self.__rule_cache.expired(): + _logger.info("Rule cache is expired so using fallback sampling strategy") return self.__fallback_sampler.should_sample( parent_context, trace_id, name, kind=kind, attributes=attributes, links=links, trace_state=trace_state )