-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
187 additions
and
6 deletions.
There are no files selected for viewing
21 changes: 21 additions & 0 deletions
21
Benchmarks/OTelTraceIdRatioBasedSamplerBenchmark/OTelTraceIdRatioBasedSamplerBenchmark.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// Benchmark boilerplate generated by Benchmark | ||
|
||
import Benchmark | ||
import OTel | ||
|
||
let benchmarks = { | ||
Benchmark("OTelTraceIdRatioBasedSampler") { benchmark in | ||
|
||
let sampler = OTelTraceIdRatioBasedSampler(ratio: 0.5) | ||
for _ in benchmark.scaledIterations { | ||
_ = sampler.samplingResult( | ||
operationName: "some-op", | ||
kind: .internal, | ||
traceID: .random(), | ||
attributes: [:], | ||
links: [], | ||
parentContext: .topLevel) | ||
} | ||
} | ||
// Add additional benchmarks here | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
53 changes: 53 additions & 0 deletions
53
Sources/OTel/Tracing/Sampling/OTelTraceIdRatioBasedSampler.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import Tracing | ||
import W3CTraceContext | ||
|
||
/// An `OTelSampler` based on a given `TraceID` and `ratio`. | ||
/// [Spec](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/sdk.md#traceidratiobased) | ||
public struct OTelTraceIdRatioBasedSampler: OTelSampler, Equatable, Hashable, CustomStringConvertible { | ||
|
||
let idUpperBound : UInt64 | ||
public let ratio: Double | ||
|
||
public init(ratio: Double) { | ||
precondition(ratio >= 0.0 && ratio <= 1.0, "ratio must be between 0.0 and 1.0") | ||
|
||
self.ratio = ratio | ||
if ratio == 0.0 { | ||
self.idUpperBound = .min | ||
} else if ratio == 1.0 { | ||
self.idUpperBound = .max | ||
} else { | ||
self.idUpperBound = UInt64(ratio * Double(UInt64.max)) | ||
} | ||
} | ||
|
||
public func samplingResult( | ||
operationName: String, | ||
kind: SpanKind, | ||
traceID: TraceID, | ||
attributes: SpanAttributes, | ||
links: [SpanLink], | ||
parentContext: ServiceContext | ||
) -> OTelSamplingResult { | ||
|
||
let value = traceID.withUnsafeBytes { $0[8...].load(as: UInt64.self) } | ||
|
||
if value < idUpperBound { | ||
return .init(decision: .recordAndSample) | ||
} else { | ||
return .init(decision: .drop) | ||
} | ||
} | ||
|
||
public static func ==(lhs: Self, rhs: Self) -> Bool { | ||
lhs.idUpperBound == rhs.idUpperBound | ||
} | ||
|
||
public func hash(into hasher: inout Hasher) { | ||
hasher.combine(self.idUpperBound) | ||
} | ||
|
||
public var description: String { | ||
"TraceIdRatioBased{\(ratio)}" | ||
} | ||
} |
70 changes: 70 additions & 0 deletions
70
Tests/OTelTests/Tracing/Sampling/OTelTraceIdRatioBasedSamplerTests.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
@testable import OTel | ||
import XCTest | ||
import Tracing | ||
|
||
final class OTelTraceIdRatioBasedSamplerTests: XCTestCase { | ||
func test_zero_ratio_does_not_sample() { | ||
let sampler = OTelTraceIdRatioBasedSampler(ratio: 0.0) | ||
|
||
let result = sampler.samplingResult( | ||
operationName: "does-not-matter", | ||
kind: .internal, | ||
traceID: .allZeroes, | ||
attributes: [:], | ||
links: [], | ||
parentContext: .topLevel | ||
) | ||
|
||
XCTAssertEqual(result, OTelSamplingResult(decision: .drop, attributes: [:])) | ||
} | ||
|
||
func test_one_ratio_does_sample() { | ||
let sampler = OTelTraceIdRatioBasedSampler(ratio: 1.0) | ||
|
||
let result = sampler.samplingResult( | ||
operationName: "does-not-matter", | ||
kind: .internal, | ||
traceID: .allZeroes, | ||
attributes: [:], | ||
links: [], | ||
parentContext: .topLevel | ||
) | ||
|
||
XCTAssertEqual(result, OTelSamplingResult(decision: .recordAndSample, attributes: [:])) | ||
} | ||
|
||
|
||
func test_different_ratios() { | ||
|
||
let ratios = [0.0, 0.1, 0.25, 0.5, 0.75, 1.0] | ||
|
||
for ratio in ratios { | ||
|
||
let sampler = OTelTraceIdRatioBasedSampler(ratio: ratio) | ||
|
||
let N = 100_000 | ||
var sampled = 0 | ||
|
||
for _ in 0 ..< N { | ||
let result = sampler.samplingResult( | ||
operationName: "does-not-matter", | ||
kind: .internal, | ||
traceID: .random(), | ||
attributes: [:], | ||
links: [], | ||
parentContext: .topLevel | ||
) | ||
|
||
switch result.decision { | ||
case .recordAndSample: | ||
sampled += 1 | ||
default: break | ||
} | ||
} | ||
|
||
let observedRatio = Double(sampled) / Double(N) | ||
|
||
XCTAssertEqual(ratio, observedRatio, accuracy: 0.05, "Expected ratio \(ratio) but observed \(observedRatio)") | ||
} | ||
} | ||
} |