Skip to content

Commit

Permalink
[repo/AWS.Sampler] Prepare to .NET9 (#2266)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kielek authored Oct 30, 2024
1 parent 0a89d81 commit 3fc1415
Show file tree
Hide file tree
Showing 19 changed files with 127 additions and 166 deletions.
22 changes: 11 additions & 11 deletions src/OpenTelemetry.Sampler.AWS/AWSXRayRemoteSampler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public sealed class AWSXRayRemoteSampler : Trace.Sampler, IDisposable
{
internal static readonly TimeSpan DefaultTargetInterval = TimeSpan.FromSeconds(10);

private static readonly Random Random = new Random();
private static readonly Random Random = new();
private bool isFallBackEventToWriteSwitch = true;

[SuppressMessage("Performance", "CA5394: Do not use insecure randomness", Justification = "Secure random is not required for jitters.")]
Expand Down Expand Up @@ -111,9 +111,9 @@ public void Dispose()
Justification = "using insecure random is fine here since clientId doesn't need to be secure.")]
private static string GenerateClientId()
{
char[] hex = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
char[] clientIdChars = new char[24];
for (int i = 0; i < clientIdChars.Length; i++)
char[] hex = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'];
var clientIdChars = new char[24];
for (var i = 0; i < clientIdChars.Length; i++)
{
clientIdChars[i] = hex[Random.Next(hex.Length)];
}
Expand All @@ -133,7 +133,7 @@ private void Dispose(bool disposing)

private async void GetAndUpdateRules(object? state)
{
List<SamplingRule> rules = await this.Client.GetSamplingRules().ConfigureAwait(false);
var rules = await this.Client.GetSamplingRules().ConfigureAwait(false);

this.RulesCache.UpdateRules(rules);

Expand All @@ -143,14 +143,14 @@ private async void GetAndUpdateRules(object? state)

private async void GetAndUpdateTargets(object? state)
{
List<SamplingStatisticsDocument> statistics = this.RulesCache.Snapshot(this.Clock.Now());
var statistics = this.RulesCache.Snapshot(this.Clock.Now());

GetSamplingTargetsRequest request = new GetSamplingTargetsRequest(statistics);
GetSamplingTargetsResponse? response = await this.Client.GetSamplingTargets(request).ConfigureAwait(false);
var request = new GetSamplingTargetsRequest(statistics);
var response = await this.Client.GetSamplingTargets(request).ConfigureAwait(false);
if (response != null)
{
Dictionary<string, SamplingTargetDocument> targets = new Dictionary<string, SamplingTargetDocument>();
foreach (SamplingTargetDocument target in response.SamplingTargetDocuments)
Dictionary<string, SamplingTargetDocument> targets = [];
foreach (var target in response.SamplingTargetDocuments)
{
if (target.RuleName != null)
{
Expand All @@ -174,7 +174,7 @@ private async void GetAndUpdateTargets(object? state)

// schedule next target poll
var nextTargetFetchTime = this.RulesCache.NextTargetFetchTime();
TimeSpan nextTargetFetchInterval = nextTargetFetchTime.Subtract(this.Clock.Now());
var nextTargetFetchInterval = nextTargetFetchTime.Subtract(this.Clock.Now());
if (nextTargetFetchInterval < TimeSpan.Zero)
{
nextTargetFetchInterval = DefaultTargetInterval;
Expand Down
6 changes: 3 additions & 3 deletions src/OpenTelemetry.Sampler.AWS/AWSXRaySamplerClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public AWSXRaySamplerClient(string host)

public async Task<List<SamplingRule>> GetSamplingRules()
{
List<SamplingRule> samplingRules = new List<SamplingRule>();
List<SamplingRule> samplingRules = [];

using (var request = new HttpRequestMessage(HttpMethod.Post, this.getSamplingRulesEndpoint)
{
Expand All @@ -37,7 +37,7 @@ public async Task<List<SamplingRule>> GetSamplingRules()

try
{
GetSamplingRulesResponse? getSamplingRulesResponse = JsonSerializer
var getSamplingRulesResponse = JsonSerializer
#if NET
.Deserialize(responseJson, SourceGenerationContext.Default.GetSamplingRulesResponse);
#else
Expand Down Expand Up @@ -89,7 +89,7 @@ public async Task<List<SamplingRule>> GetSamplingRules()

try
{
GetSamplingTargetsResponse? getSamplingTargetsResponse = JsonSerializer
var getSamplingTargetsResponse = JsonSerializer
#if NET
.Deserialize(responseJson, SourceGenerationContext.Default.GetSamplingTargetsResponse);
#else
Expand Down
11 changes: 2 additions & 9 deletions src/OpenTelemetry.Sampler.AWS/FallbackSampler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,16 @@ internal class FallbackSampler : Trace.Sampler
{
private readonly Trace.Sampler reservoirSampler;
private readonly Trace.Sampler fixedRateSampler;
private readonly Clock clock;

public FallbackSampler(Clock clock)
{
this.clock = clock;
this.reservoirSampler = new ParentBasedSampler(new RateLimitingSampler(1, clock));
this.fixedRateSampler = new ParentBasedSampler(new TraceIdRatioBasedSampler(0.05));
}

public override SamplingResult ShouldSample(in SamplingParameters samplingParameters)
{
SamplingResult result = this.reservoirSampler.ShouldSample(in samplingParameters);
if (result.Decision != SamplingDecision.Drop)
{
return result;
}

return this.fixedRateSampler.ShouldSample(in samplingParameters);
var result = this.reservoirSampler.ShouldSample(in samplingParameters);
return result.Decision != SamplingDecision.Drop ? result : this.fixedRateSampler.ShouldSample(in samplingParameters);
}
}
23 changes: 9 additions & 14 deletions src/OpenTelemetry.Sampler.AWS/Matcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ public static bool WildcardMatch(string? text, string? globPattern)

// it is faster to check if we need a regex comparison than
// doing always regex comparison, even where we may not need it.
foreach (char c in globPattern)
foreach (var c in globPattern)
{
if (c == '*' || c == '?')
if (c is '*' or '?')
{
return Regex.IsMatch(text, ToRegexPattern(globPattern));
}
Expand All @@ -59,7 +59,7 @@ public static bool AttributeMatch(IEnumerable<KeyValuePair<string, object?>>? ta
return false;
}

int matchedCount = 0;
var matchedCount = 0;

foreach (var tag in tags)
{
Expand All @@ -77,23 +77,18 @@ public static bool AttributeMatch(IEnumerable<KeyValuePair<string, object?>>? ta
}
}

if (matchedCount == ruleAttributes.Count)
{
return true;
}

return false;
return matchedCount == ruleAttributes.Count;
}

private static string ToRegexPattern(string globPattern)
{
int tokenStart = -1;
StringBuilder patternBuilder = new StringBuilder();
var tokenStart = -1;
var patternBuilder = new StringBuilder();

for (int i = 0; i < globPattern.Length; i++)
for (var i = 0; i < globPattern.Length; i++)
{
char c = globPattern[i];
if (c == '*' || c == '?')
var c = globPattern[i];
if (c is '*' or '?')
{
if (tokenStart != -1)
{
Expand Down
4 changes: 2 additions & 2 deletions src/OpenTelemetry.Sampler.AWS/RateLimiter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ internal RateLimiter(double creditsPerSecond, double maxBalance, Clock clock)

public bool TrySpend(double itemCost)
{
long cost = (long)(itemCost / this.creditsPerMillisecond);
var cost = (long)(itemCost / this.creditsPerMillisecond);
long currentMillis;
long currentBalanceMillis;
long availableBalanceAfterWithdrawal;
Expand All @@ -29,7 +29,7 @@ public bool TrySpend(double itemCost)
{
currentBalanceMillis = Interlocked.Read(ref this.currentBalance);
currentMillis = this.clock.NowInMilliSeconds();
long currentAvailableBalance = currentMillis - currentBalanceMillis;
var currentAvailableBalance = currentMillis - currentBalanceMillis;
if (currentAvailableBalance > this.maxBalance)
{
currentAvailableBalance = this.maxBalance;
Expand Down
17 changes: 6 additions & 11 deletions src/OpenTelemetry.Sampler.AWS/RulesCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public RulesCache(Clock clock, string clientId, Resource resource, Trace.Sampler
this.ClientId = clientId;
this.Resource = resource;
this.FallbackSampler = fallbackSampler;
this.RuleAppliers = new List<SamplingRuleApplier>();
this.RuleAppliers = [];
this.UpdatedAt = this.Clock.Now();
}

Expand Down Expand Up @@ -54,7 +54,7 @@ public void UpdateRules(List<SamplingRule> newRules)
// sort the new rules
newRules.Sort((x, y) => x.CompareTo(y));

List<SamplingRuleApplier> newRuleAppliers = new List<SamplingRuleApplier>();
List<SamplingRuleApplier> newRuleAppliers = [];
foreach (var rule in newRules)
{
// If the ruleApplier already exists in the current list of appliers, then we reuse it.
Expand Down Expand Up @@ -104,7 +104,7 @@ public SamplingResult ShouldSample(in SamplingParameters samplingParameters)

public List<SamplingStatisticsDocument> Snapshot(DateTimeOffset now)
{
List<SamplingStatisticsDocument> snapshots = new List<SamplingStatisticsDocument>();
List<SamplingStatisticsDocument> snapshots = [];
foreach (var ruleApplier in this.RuleAppliers)
{
snapshots.Add(ruleApplier.Snapshot(now));
Expand All @@ -115,10 +115,10 @@ public List<SamplingStatisticsDocument> Snapshot(DateTimeOffset now)

public void UpdateTargets(Dictionary<string, SamplingTargetDocument> targets)
{
List<SamplingRuleApplier> newRuleAppliers = new List<SamplingRuleApplier>();
List<SamplingRuleApplier> newRuleAppliers = [];
foreach (var ruleApplier in this.RuleAppliers)
{
targets.TryGetValue(ruleApplier.RuleName, out SamplingTargetDocument? target);
targets.TryGetValue(ruleApplier.RuleName, out var target);
if (target != null)
{
newRuleAppliers.Add(ruleApplier.WithTarget(target, this.Clock.Now()));
Expand Down Expand Up @@ -154,12 +154,7 @@ public DateTimeOffset NextTargetFetchTime()
.Select(r => r.NextSnapshotTime)
.Min();

if (minPollingTime < this.Clock.Now())
{
return defaultPollingTime;
}

return minPollingTime;
return minPollingTime < this.Clock.Now() ? defaultPollingTime : minPollingTime;
}

public void Dispose()
Expand Down
2 changes: 1 addition & 1 deletion src/OpenTelemetry.Sampler.AWS/SamplingRule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public SamplingRule(

public int CompareTo(SamplingRule? other)
{
int result = this.Priority.CompareTo(other?.Priority);
var result = this.Priority.CompareTo(other?.Priority);
if (result == 0)
{
result = string.Compare(this.RuleName, other?.RuleName, StringComparison.Ordinal);
Expand Down
58 changes: 21 additions & 37 deletions src/OpenTelemetry.Sampler.AWS/SamplingRuleApplier.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,25 +116,18 @@ public bool Matches(SamplingParameters samplingParameters, Resource resource)
// URL path may be in either http.target or http.url
if (httpTarget == null && httpUrl != null)
{
int schemeEndIndex = httpUrl.IndexOf("://", StringComparison.Ordinal);
var schemeEndIndex = httpUrl.IndexOf("://", StringComparison.Ordinal);

// Per spec, http.url is always populated with scheme://host/target. If scheme doesn't
// match, assume it's bad instrumentation and ignore.
if (schemeEndIndex > 0)
{
int pathIndex = httpUrl.IndexOf('/', schemeEndIndex + "://".Length);
if (pathIndex < 0)
{
httpTarget = "/";
}
else
{
httpTarget = httpUrl.Substring(pathIndex);
}
var pathIndex = httpUrl.IndexOf('/', schemeEndIndex + "://".Length);
httpTarget = pathIndex < 0 ? "/" : httpUrl.Substring(pathIndex);
}
}

string serviceName = (string)resource.Attributes.FirstOrDefault(kvp =>
var serviceName = (string)resource.Attributes.FirstOrDefault(kvp =>
kvp.Key.Equals("service.name", StringComparison.Ordinal)).Value;

return Matcher.AttributeMatch(samplingParameters.Tags, this.Rule.Attributes) &&
Expand All @@ -149,8 +142,8 @@ public bool Matches(SamplingParameters samplingParameters, Resource resource)
public SamplingResult ShouldSample(in SamplingParameters samplingParameters)
{
Interlocked.Increment(ref this.Statistics.RequestCount);
bool reservoirExpired = this.Clock.Now() >= this.ReservoirEndTime;
SamplingResult result = !reservoirExpired
var reservoirExpired = this.Clock.Now() >= this.ReservoirEndTime;
var result = !reservoirExpired
? this.ReservoirSampler.ShouldSample(in samplingParameters)
: new SamplingResult(SamplingDecision.Drop);

Expand Down Expand Up @@ -178,13 +171,13 @@ public SamplingResult ShouldSample(in SamplingParameters samplingParameters)
// take the snapshot and reset the statistics.
public SamplingStatisticsDocument Snapshot(DateTimeOffset now)
{
double timestamp = this.Clock.ToDouble(now);
var timestamp = this.Clock.ToDouble(now);

long matchedRequests = Interlocked.Exchange(ref this.Statistics.RequestCount, 0L);
long sampledRequests = Interlocked.Exchange(ref this.Statistics.SampleCount, 0L);
long borrowedRequests = Interlocked.Exchange(ref this.Statistics.BorrowCount, 0L);
var matchedRequests = Interlocked.Exchange(ref this.Statistics.RequestCount, 0L);
var sampledRequests = Interlocked.Exchange(ref this.Statistics.SampleCount, 0L);
var borrowedRequests = Interlocked.Exchange(ref this.Statistics.BorrowCount, 0L);

SamplingStatisticsDocument statiscticsDocument = new SamplingStatisticsDocument(
var statiscticsDocument = new SamplingStatisticsDocument(
this.ClientId,
this.RuleName,
matchedRequests,
Expand All @@ -197,27 +190,22 @@ public SamplingStatisticsDocument Snapshot(DateTimeOffset now)

public SamplingRuleApplier WithTarget(SamplingTargetDocument target, DateTimeOffset now)
{
Trace.Sampler newFixedRateSampler = target.FixedRate != null
var newFixedRateSampler = target.FixedRate != null
? new ParentBasedSampler(new TraceIdRatioBasedSampler(target.FixedRate.Value))
: this.FixedRateSampler;

Trace.Sampler newReservoirSampler = new AlwaysOffSampler();
DateTimeOffset newReservoirEndTime = DateTimeOffset.MaxValue;
var newReservoirEndTime = DateTimeOffset.MaxValue;
if (target.ReservoirQuota != null && target.ReservoirQuotaTTL != null)
{
if (target.ReservoirQuota > 0)
{
newReservoirSampler = new ParentBasedSampler(new RateLimitingSampler(target.ReservoirQuota.Value, this.Clock));
}
else
{
newReservoirSampler = new AlwaysOffSampler();
}
newReservoirSampler = target.ReservoirQuota > 0
? new ParentBasedSampler(new RateLimitingSampler(target.ReservoirQuota.Value, this.Clock))
: new AlwaysOffSampler();

newReservoirEndTime = this.Clock.ToDateTime(target.ReservoirQuotaTTL.Value);
}

DateTimeOffset newNextSnapshotTime = target.Interval != null
var newNextSnapshotTime = target.Interval != null
? now.AddSeconds(target.Interval.Value)
: now.Add(AWSXRayRemoteSampler.DefaultTargetInterval);

Expand All @@ -235,21 +223,17 @@ public SamplingRuleApplier WithTarget(SamplingTargetDocument target, DateTimeOff

private static string GetServiceType(Resource resource)
{
string cloudPlatform = (string)resource.Attributes.FirstOrDefault(kvp =>
var cloudPlatform = (string)resource.Attributes.FirstOrDefault(kvp =>
kvp.Key.Equals("cloud.platform", StringComparison.Ordinal)).Value;

if (cloudPlatform == null)
{
return string.Empty;
}

return Matcher.XRayCloudPlatform.TryGetValue(cloudPlatform, out string? value) ? value : string.Empty;
return cloudPlatform == null ? string.Empty :
Matcher.XRayCloudPlatform.TryGetValue(cloudPlatform, out var value) ? value : string.Empty;
}

private static string GetArn(in SamplingParameters samplingParameters, Resource resource)
{
// currently the aws resource detectors only capture ARNs for ECS and Lambda environments.
string? arn = (string?)resource.Attributes.FirstOrDefault(kvp =>
var arn = (string?)resource.Attributes.FirstOrDefault(kvp =>
kvp.Key.Equals("aws.ecs.container.arn", StringComparison.Ordinal)).Value;

if (arn != null)
Expand Down
4 changes: 2 additions & 2 deletions src/OpenTelemetry.Sampler.AWS/SystemClock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace OpenTelemetry.Sampler.AWS;
// A clock based on System time.
internal class SystemClock : Clock
{
private static readonly SystemClock Instance = new SystemClock();
private static readonly SystemClock Instance = new();

private static readonly DateTimeOffset EpochStart = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);

Expand Down Expand Up @@ -37,7 +37,7 @@ public override DateTimeOffset ToDateTime(double seconds)
public override double ToDouble(DateTimeOffset dateTime)
{
var current = new TimeSpan(dateTime.ToUniversalTime().Ticks - EpochStart.Ticks);
double timestamp = Math.Round(current.TotalMilliseconds, 0) / 1000.0;
var timestamp = Math.Round(current.TotalMilliseconds, 0) / 1000.0;
return timestamp;
}
}
9 changes: 3 additions & 6 deletions src/Shared/Guard.cs
Original file line number Diff line number Diff line change
Expand Up @@ -174,12 +174,9 @@ public static void ThrowIfOutOfRange(double value, [CallerArgumentExpression(nam
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static T ThrowIfNotOfType<T>([NotNull] object? value, [CallerArgumentExpression(nameof(value))] string? paramName = null)
{
if (value is not T result)
{
throw new InvalidCastException($"Cannot cast '{paramName}' from '{value?.GetType().ToString() ?? "null"}' to '{typeof(T)}'");
}

return result;
return value is not T result
? throw new InvalidCastException($"Cannot cast '{paramName}' from '{value?.GetType().ToString() ?? "null"}' to '{typeof(T)}'")
: result;
}

[DebuggerHidden]
Expand Down
Loading

0 comments on commit 3fc1415

Please sign in to comment.