diff --git a/Package.resolved b/Package.resolved index 4032576..8d2ae6c 100644 --- a/Package.resolved +++ b/Package.resolved @@ -42,8 +42,8 @@ "repositoryURL": "https://github.com/slashmo/swift-w3c-trace-context.git", "state": { "branch": null, - "revision": "8502b4cd58abe48220e6ef383eceb5694253081f", - "version": "0.5.0" + "revision": "9913eb786060af7c5699af86857e2292fe32acf8", + "version": "0.6.0" } } ] diff --git a/Package.swift b/Package.swift index c3e6fbc..0185758 100644 --- a/Package.swift +++ b/Package.swift @@ -10,7 +10,7 @@ let package = Package( dependencies: [ .package(name: "swift-context", url: "https://github.com/slashmo/gsoc-swift-baggage-context", from: "0.5.0"), .package(url: "https://github.com/slashmo/gsoc-swift-tracing.git", .branch("main")), - .package(url: "https://github.com/slashmo/swift-w3c-trace-context.git", from: "0.5.0"), + .package(url: "https://github.com/slashmo/swift-w3c-trace-context.git", from: "0.6.0"), .package(url: "https://github.com/slashmo/swift-nio.git", .branch("feature/baggage-context")), ], targets: [ diff --git a/Sources/Jaeger/Sampling/ConstantSampler.swift b/Sources/Jaeger/Sampling/ConstantSampler.swift index ee90a3a..5675340 100644 --- a/Sources/Jaeger/Sampling/ConstantSampler.swift +++ b/Sources/Jaeger/Sampling/ConstantSampler.swift @@ -11,6 +11,8 @@ // //===----------------------------------------------------------------------===// +import W3CTraceContext + public struct ConstantSampler: Sampler { private let samples: Bool @@ -18,7 +20,7 @@ public struct ConstantSampler: Sampler { self.samples = samples } - public func sample(operationName: String, traceID: String) -> SamplingStatus { + public func sample(operationName: String, traceID: TraceID) -> SamplingStatus { SamplingStatus(isSampled: self.samples, attributes: [ "sampler.type": "const", "sampler.param": self.samples ? "true" : "false", diff --git a/Sources/Jaeger/Sampling/ProbabilisticSampler.swift b/Sources/Jaeger/Sampling/ProbabilisticSampler.swift new file mode 100644 index 0000000..eb632a1 --- /dev/null +++ b/Sources/Jaeger/Sampling/ProbabilisticSampler.swift @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Jaeger Client Swift open source project +// +// Copyright (c) 2020 Moritz Lang and the Jaeger Client Swift project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import W3CTraceContext + +public struct ProbabilisticSampler: Sampler { + private let samplingRate: Double + private let lowUpperBound: UInt64 + + public init(samplingRate: Double = 0.001) { + precondition( + samplingRate > 0 && samplingRate < 1, + "The sampling rate must be greater than 0.0 and less than 1.0. Please use ConstantSampler instead." + ) + self.samplingRate = samplingRate + self.lowUpperBound = UInt64(samplingRate * Double(UInt64.max)) + } + + public func sample(operationName: String, traceID: TraceID) -> SamplingStatus { + SamplingStatus(isSampled: traceID.low < self.lowUpperBound, attributes: [ + "sampler.type": "probabilistic", + "sampler.param": .double(self.samplingRate), + ]) + } +} diff --git a/Sources/Jaeger/Sampling/Sampler.swift b/Sources/Jaeger/Sampling/Sampler.swift index 10f7679..ebf2cee 100644 --- a/Sources/Jaeger/Sampling/Sampler.swift +++ b/Sources/Jaeger/Sampling/Sampler.swift @@ -12,12 +12,13 @@ //===----------------------------------------------------------------------===// import Tracing +import W3CTraceContext public struct SamplingStatus { - var isSampled: Bool - var attributes: SpanAttributes + public let isSampled: Bool + public let attributes: SpanAttributes } public protocol Sampler { - func sample(operationName: String, traceID: String) -> SamplingStatus + func sample(operationName: String, traceID: TraceID) -> SamplingStatus } diff --git a/Sources/ZipkinReporting/Span+ZipkinRepresentation.swift b/Sources/ZipkinReporting/Span+ZipkinRepresentation.swift index 1e93921..054e4e7 100644 --- a/Sources/ZipkinReporting/Span+ZipkinRepresentation.swift +++ b/Sources/ZipkinReporting/Span+ZipkinRepresentation.swift @@ -44,7 +44,7 @@ extension JaegerSpan { return ZipkinRepresentation( id: traceContext.parent.parentID, - traceID: traceContext.parent.traceID, + traceID: String(describing: traceContext.parent.traceID), parentID: self.links.first?.baggage.traceContext?.parent.parentID, name: self.operationName, timestamp: self.startTimestamp.microsSinceEpoch, diff --git a/Tests/JaegerTests/Sampling/ProbabilisticSamplerTests.swift b/Tests/JaegerTests/Sampling/ProbabilisticSamplerTests.swift new file mode 100644 index 0000000..335b187 --- /dev/null +++ b/Tests/JaegerTests/Sampling/ProbabilisticSamplerTests.swift @@ -0,0 +1,45 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Jaeger Client Swift open source project +// +// Copyright (c) 2020 Moritz Lang and the Jaeger Client Swift project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import Jaeger +import W3CTraceContext +import XCTest + +final class ProbabilisticSamplerTests: XCTestCase { + func test_sample_comparesLowIDPartToUpperBound() { + let samplingRate = Double.random(in: Double.leastNonzeroMagnitude ..< 1.0) + let upperBound = UInt64(samplingRate * Double(UInt64.max)) + let sampler = ProbabilisticSampler(samplingRate: samplingRate) + + do { + let traceID = TraceID(high: 0, low: upperBound) + let samplingStatus = sampler.sample(operationName: "test", traceID: traceID) + XCTAssertFalse(samplingStatus.isSampled) + } + + do { + let traceID = TraceID(high: 0, low: upperBound - 1) + let samplingStatus = sampler.sample(operationName: "test", traceID: traceID) + XCTAssert(samplingStatus.isSampled) + } + } + + func test_sample_returnsSamplingStatus_withAttributes() { + let sampler = ProbabilisticSampler(samplingRate: 0.1) + + let samplingStatus = sampler.sample(operationName: "test", traceID: .random()) + + XCTAssertEqual(samplingStatus.attributes["sampler.type"], "probabilistic") + XCTAssertEqual(samplingStatus.attributes["sampler.param"], 0.1) + } +} diff --git a/Tests/ZipkinReportingTests/ZipkinSpanRepresentationTests.swift b/Tests/ZipkinReportingTests/ZipkinSpanRepresentationTests.swift index 1d4f069..72694b1 100644 --- a/Tests/ZipkinReportingTests/ZipkinSpanRepresentationTests.swift +++ b/Tests/ZipkinReportingTests/ZipkinSpanRepresentationTests.swift @@ -44,7 +44,7 @@ final class ZipkinSpanRepresentationTests: XCTestCase { XCTAssertNotNil(zipkinRepresentation) XCTAssertEqual(zipkinRepresentation?.id, child.baggage.traceContext?.parent.parentID) - XCTAssertEqual(zipkinRepresentation?.traceID, child.baggage.traceContext?.parent.traceID) + XCTAssertEqual(zipkinRepresentation?.traceID, child.baggage.traceContext?.parent.traceID.description) XCTAssertNotNil(zipkinRepresentation?.parentID) XCTAssertEqual(zipkinRepresentation?.parentID, parent.baggage.traceContext?.parent.parentID) XCTAssertEqual(zipkinRepresentation?.name, "child")