-
Notifications
You must be signed in to change notification settings - Fork 289
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
[Sampler.AWS] Part-2: Add rules cache and rule matching logic #1124
Conversation
12ec9b6
to
c775460
Compare
Codecov Report
Additional details and impacted files@@ Coverage Diff @@
## main #1124 +/- ##
==========================================
+ Coverage 72.53% 72.80% +0.27%
==========================================
Files 236 243 +7
Lines 8570 8781 +211
==========================================
+ Hits 6216 6393 +177
- Misses 2354 2388 +34
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will be great to review code also by AWS experienced guys.
Maybe @Oberon00?
namespace OpenTelemetry.Sampler.AWS; | ||
|
||
// A time keeper for the purpose of this sampler. | ||
internal sealed class Clock |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is a benefit for using this additional abstraction layer, instread of just using directly DateTime.UtcNow?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The sampler does quite a few things based on time, like the rules cache freshness and rate limited sampling (which would come in the next PR. The DateTime APIs can be used for such logic, but I think for testing the functionality, I need a mocked clock which can be passed in as a Clock
type.
[Fact] | ||
public void TestWildcardMatching() | ||
{ | ||
Assert.True(Matcher.WildcardMatch(null, "*")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure that null should match anything. I think it needs some documentation for this case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a null
input here would mean that the particular attribute is not set on the span, and so the *
should match any value of an attribute whether it is set or not.
Sorry, I don't have any experience with X-Ray, so this PR is out of my area of expertise. |
Assert.True(Matcher.WildcardMatch("HelloWorld", "HelloWorld")); | ||
Assert.True(Matcher.WildcardMatch("HelloWorld", "Hello*")); | ||
Assert.True(Matcher.WildcardMatch("HelloWorld", "*World")); | ||
Assert.True(Matcher.WildcardMatch("HelloWorld", "?ello*")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we add two more tests with '*' and '?' in the middle of the sting on the second variable, some with other regex special characters such as '.', and a few more complex ones as well.
I want to make sure we test that ToRegexPattern sufficiently. If we have a bug here, then a customer might accidentally depend on it. It would be painful for them if we fix the bug later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need really complex testing here since the sampling rule options only allow for *
and ?
for matching.
https://docs.aws.amazon.com/xray/latest/devguide/xray-console-sampling.html#xray-console-sampling-options
} | ||
|
||
public bool Expired() | ||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to lock here? We are not changing state and UpdatedAt cannot be changed back to null as far as I can tell.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we do need a lock here. The background thread can be writing the UpdatedAt
while the main thread could be reading the value when trying to sample a request. We don't want these two to happen concurrently.
This PR was marked stale due to lack of activity. It will be closed in 7 days. |
{ | ||
if (c == '*' || c == '?') | ||
{ | ||
return Regex.IsMatch(text, ToRegexPattern(globPattern)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do have concerns here about regex being slow. Especially since we are using a simplified version. I will leave it up to you on if we should keep it. Might be worth adding a performance test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. A performance benchmark would be a good idea. I can think of adding it once the sampler implementation is complete.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still have some doubts about public API. @utpilla, could you please review it?
Other parts LGTM.
.AddSource(serviceName) | ||
.SetResourceBuilder(resourceBuilder) | ||
.AddConsoleExporter() | ||
.SetSampler(AWSXRayRemoteSampler.Builder(resourceBuilder.Build()) // you must provide a resource |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a suggestion:
This setup looks quite verbose. I think you could extract this into an extension method. Something like: AddAWSXRayRemoteSampler(this TracerProviderBuilder, Action<AWSXRaySamplerOptions> configure)
.
That way you would only be exposing the required options and you could reduce the publicAPI surface by marking these methods as internal: AWSXRayRemoteSampler.Builder
, SetPollingInterval
, SetEndpoint
, Build
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had earlier of thought of doing the extension method similar to AddXRayTraceId()
we have for the custom trace id generator, but I think that is counterintuitive for adding a Sampler. Since the AWSXRayRemoteSampler
is just another implementation of Sampler
, it should follow the standard procedure of adding a sampler via the SetSampler
method.
Regarding the setting of the sampler being verbose, I agree. The customers of OTel Java and GoLang are already configuring the remote sampler in similar way, so I would like to keep the same behavior here as well.
this.rwLock.EnterReadLock(); | ||
try | ||
{ | ||
return this.UpdatedAt; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is locking around returning a variable needed?
Also, I don't think GetUpdatedAt is used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. Since the UpdatedAt
will be written by rule poller and read by target poller, we need this lock for safe reads.
The GetUpdatedAt
will be used in my next PR by the target poller: https://github.com/srprash/opentelemetry-dotnet-contrib/blob/xray_sampler_pr_3/src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSampler.cs#L173
This PR is a continuation of building the AWS X-Ray Remote Sampler.
See part 1 PR: #1091
Changes
Adding a Sampling Rules Cache.
Reservoir
and theStatistics
are preserved from the old set of rules. These stateful properties will be used in making the sampling decisions and keeping the sampling records respectively throughout the duration of the application. Note: TheReservoir
andStatistics
classes are very bare-bone right now, but will be developed in further PRs.Adding the sampling rule matching logic.
The sampler now requires an OpenTelemetry Resource object.
Resource
configured for the application.Resource
instance to the sampler themselves.