Skip to content

feat(opentelemetry-sampler-aws-xray): Add Rules Caching and Rules Matching Logic #2824

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

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

jj22ee
Copy link
Contributor

@jj22ee jj22ee commented May 13, 2025

Which problem is this PR solving?

Short description of the changes

This PR is a followup to #2750

  • Add Sampling RuleCache
    • Caches a list of SamplingRuleAppliers, ordered by rule priority then rule name. Each Rule Applier corresponds to the Sampling Rule from GetSamplingRules. Each call to GetSamplingRules will only update the Rules that have changed properties, to preserve the state of unchanged rules. This means when Reservoir and Statistics are implemented (later) in the Rules, they will persist for unchanged rules.
    • The RuleCache will determine which Rule that a span matches (via the set of {ResourceAttributes,SpanAttributes}) that has highest priority.
  • Update SamplingRuleApplier to perform Fixed Rate Sampling, and to include a method to apply matching logic against a set of {ResourceAttributes,SpanAttributes} by using the wild card and attribute matching from Utils
  • Initial class for FallbackSampler
  • Update X-Ray Remote Sampler to depend on the SamplingRuleApplier from RuleCache and the FallBack Sampler to perform shouldSample

@jj22ee jj22ee requested a review from a team as a code owner May 13, 2025 23:13
@github-actions github-actions bot requested a review from yiyuan-he May 13, 2025 23:13
Copy link

codecov bot commented May 13, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 89.64%. Comparing base (e0858f9) to head (a79cfd5).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #2824   +/-   ##
=======================================
  Coverage   89.64%   89.64%           
=======================================
  Files         184      184           
  Lines        9032     9032           
  Branches     1852     1852           
=======================================
  Hits         8097     8097           
  Misses        935      935           
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@jj22ee
Copy link
Contributor Author

jj22ee commented May 14, 2025

cc @lukeina2z for review who is familiar with Sampling. Currently everything is implemented except for Updating Sampling Targets and the Rate Limiting (Reservoir) Sampler.

}

public toString(): string {
return 'FallbackSampler{fallback sampling with sampling config of 1 req/sec and 5% of additional requests';

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: what does '{' mean in the string?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, I forgot to the } at the end of the string. This method intends to return a description of this sampler, in the format of FallbackSampler{ <description> }.

}

public updateRules(newRuleAppliers: SamplingRuleApplier[]): void {
const oldRuleAppliersMap: { [key: string]: SamplingRuleApplier } = {};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: You could use a Map<string, SamplingRuleApplier> instead of a plain object here for better perf.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I Incorporated your suggestion.

attributes: Attributes
): SamplingRuleApplier | undefined {
return this.ruleAppliers.find(
rule =>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this, in some cases, find the default rule before a higher priority rule? Will this matter?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This use of find() here relies on the this.ruleAppliers list being always sorted by priority (ascending integers), where the default rule is always hardcoded to be the last priority by AWS X-Ray. This sorting is assumed because it is sorted here whenever the Sampling rules are updated. This assumption is important, I've added a comment.

// If scheme is not present, assume it's bad instrumentation and ignore.
if (schemeEndIndex > -1) {
// urlparse("scheme://netloc/path;parameters?query#fragment")
httpTarget = new URL(httpUrl).pathname;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure that this will never receive a malformed httpUrl as it will throw if it does.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch, I chose to rely on a try...catch to handle this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants