generated from honeycombio/.github
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(samplers): Add deterministic sampler (#17)
## Short description of the changes Adds a deterministic sampler modeled off the deterministic sampler in honeycombs other distros. ## How to verify that this has the expected result unit tests
- Loading branch information
Showing
2 changed files
with
113 additions
and
0 deletions.
There are no files selected for viewing
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,60 @@ | ||
import Foundation | ||
import OpenTelemetryApi | ||
import OpenTelemetrySdk | ||
|
||
class HoneycombDeterministicSampler: Sampler { | ||
private let inner: Sampler | ||
private let rate: [String: AttributeValue] | ||
|
||
init(sampleRate: Int) { | ||
var inner: Sampler | ||
|
||
switch sampleRate { | ||
case Int.min..<1: | ||
inner = Samplers.alwaysOff | ||
case 1: | ||
inner = Samplers.alwaysOn | ||
default: | ||
inner = Samplers.traceIdRatio(ratio: 1.0 / Double(sampleRate)) | ||
} | ||
|
||
self.inner = inner | ||
self.rate = ["SampleRate": AttributeValue(sampleRate)] | ||
} | ||
|
||
func shouldSample( | ||
parentContext: SpanContext?, | ||
traceId: TraceId, | ||
name: String, | ||
kind: SpanKind, | ||
attributes: [String: AttributeValue], | ||
parentLinks: [SpanData.Link] | ||
) -> any Decision { | ||
var result = self.inner.shouldSample( | ||
parentContext: parentContext, | ||
traceId: traceId, | ||
name: name, | ||
kind: kind, | ||
attributes: attributes, | ||
parentLinks: parentLinks | ||
) | ||
|
||
if result.isSampled { | ||
let attrs = result.attributes.merging( | ||
rate, | ||
uniquingKeysWith: { (_, new) in new } | ||
) | ||
result = HoneycombDecision(isSampled: result.isSampled, attributes: attrs) | ||
} | ||
|
||
return result | ||
} | ||
|
||
var description: String = "DeterministicSampler" | ||
} | ||
|
||
private struct HoneycombDecision: Decision { | ||
let isSampled: Bool | ||
|
||
let attributes: [String: AttributeValue] | ||
} |
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 OpenTelemetryApi | ||
import OpenTelemetrySdk | ||
import XCTest | ||
|
||
@testable import Honeycomb | ||
|
||
class HoneycombDeterministicSamplerTests: XCTestCase { | ||
func testSampler() { | ||
let testCases = [ | ||
(rate: 0, sampled: false), | ||
(rate: 1, sampled: true), | ||
(rate: 10, sampled: true), | ||
(rate: 100, sampled: true), | ||
] | ||
|
||
// static trace id to ensure the inner traceIdRatio | ||
// sampler always samples. | ||
let traceID = TraceId.init(idHi: 10, idLo: 10) | ||
let spanID = SpanId.random() | ||
let parentContext = SpanContext.create( | ||
traceId: traceID, | ||
spanId: spanID, | ||
traceFlags: TraceFlags.init(), | ||
traceState: TraceState.init() | ||
) | ||
|
||
for (rate, sampled) in testCases { | ||
XCTContext.runActivity( | ||
named: "", | ||
block: { activity in | ||
let sampler = HoneycombDeterministicSampler(sampleRate: rate) | ||
let result = sampler.shouldSample( | ||
parentContext: parentContext, | ||
traceId: traceID, | ||
name: "test", | ||
kind: SpanKind.client, | ||
attributes: [:], | ||
parentLinks: [] | ||
) | ||
XCTAssertEqual(result.isSampled, sampled) | ||
|
||
if sampled { | ||
guard let r = result.attributes["SampleRate"] else { | ||
XCTFail("sample rate attribute not found") | ||
return | ||
} | ||
XCTAssertEqual(AttributeValue.int(rate), r) | ||
} | ||
} | ||
) | ||
} | ||
} | ||
} |