diff --git a/README.md b/README.md index fd1ce39..e5f9478 100644 --- a/README.md +++ b/README.md @@ -104,8 +104,8 @@ public protocol TimerHandler: AnyObject { ```swift public protocol RecorderHandler: AnyObject { - func record(_ value: DataType) - func record(_ value: DataType) + func record(_ value: Int64) + func record(_ value: Double) } ``` @@ -120,7 +120,7 @@ class SimpleMetricsLibrary: MetricsFactory { } func makeRecorder(label: String, dimensions: [(String, String)], aggregate: Bool) -> RecorderHandler { - let maker:(String, [(String, String)]) -> Recorder = aggregate ? ExampleRecorder.init : ExampleGauge.init + let maker: (String, [(String, String)]) -> RecorderHandler = aggregate ? ExampleRecorder.init : ExampleGauge.init return maker(label, dimensions) } @@ -133,9 +133,15 @@ class SimpleMetricsLibrary: MetricsFactory { let lock = NSLock() var value: Int64 = 0 - func increment(_ value: DataType) { + func increment(_ value: Int64) { self.lock.withLock { - self.value += Int64(value) + self.value += value + } + } + + func reset() { + self.lock.withLock { + self.value = 0 } } } @@ -145,20 +151,18 @@ class SimpleMetricsLibrary: MetricsFactory { private let lock = NSLock() var values = [(Int64, Double)]() - func record(_ value: DataType) { + func record(_ value: Int64) { self.record(Double(value)) } - func record(_ value: DataType) { - // this may loose precision, but good enough as an example - let v = Double(value) + func record(_ value: Double) { // TODO: sliding window lock.withLock { - values.append((Date().nanoSince1970, v)) + values.append((Date().nanoSince1970, value)) self._count += 1 - self._sum += v - if 0 == self._min || v < self._min { self._min = v } - if 0 == self._max || v > self._max { self._max = v } + self._sum += value + self._min = Swift.min(self._min, value) + self._max = Swift.max(self._max, value) } } @@ -188,13 +192,12 @@ class SimpleMetricsLibrary: MetricsFactory { let lock = NSLock() var _value: Double = 0 - func record(_ value: DataType) { + func record(_ value: Int64) { self.record(Double(value)) } - func record(_ value: DataType) { - // this may loose precision but good enough as an example - self.lock.withLock { _value = Double(value) } + func record(_ value: Double) { + self.lock.withLock { _value = value } } } diff --git a/Sources/CoreMetrics/Metrics.swift b/Sources/CoreMetrics/Metrics.swift index 2074685..ae0a9f6 100644 --- a/Sources/CoreMetrics/Metrics.swift +++ b/Sources/CoreMetrics/Metrics.swift @@ -14,7 +14,7 @@ /// This is the Counter protocol a metrics library implements. It must have reference semantics public protocol CounterHandler: AnyObject { - func increment(_ value: DataType) + func increment(_ value: Int64) func reset() } @@ -35,7 +35,7 @@ public class Counter { @inlinable public func increment(_ value: DataType) { - self.handler.increment(value) + self.handler.increment(Int64(value)) } @inlinable @@ -58,8 +58,8 @@ public extension Counter { /// This is the Recorder protocol a metrics library implements. It must have reference semantics public protocol RecorderHandler: AnyObject { - func record(_ value: DataType) - func record(_ value: DataType) + func record(_ value: Int64) + func record(_ value: Double) } // This is the user facing Recorder API. Its behavior depends on the `RecorderHandler` implementation @@ -81,12 +81,12 @@ public class Recorder { @inlinable public func record(_ value: DataType) { - self.handler.record(value) + self.handler.record(Int64(value)) } @inlinable public func record(_ value: DataType) { - self.handler.record(value) + self.handler.record(Double(value)) } } @@ -225,7 +225,7 @@ public final class MultiplexMetricsHandler: MetricsFactory { self.counters = factories.map { $0.makeCounter(label: label, dimensions: dimensions) } } - func increment(_ value: DataType) { + func increment(_ value: Int64) { self.counters.forEach { $0.increment(value) } } @@ -240,11 +240,11 @@ public final class MultiplexMetricsHandler: MetricsFactory { self.recorders = factories.map { $0.makeRecorder(label: label, dimensions: dimensions, aggregate: aggregate) } } - func record(_ value: DataType) { + func record(_ value: Int64) { self.recorders.forEach { $0.record(value) } } - func record(_ value: DataType) { + func record(_ value: Double) { self.recorders.forEach { $0.record(value) } } } @@ -278,9 +278,9 @@ public final class NOOPMetricsHandler: MetricsFactory, CounterHandler, RecorderH return self } - public func increment(_: DataType) {} + public func increment(_: Int64) {} public func reset() {} - public func record(_: DataType) {} - public func record(_: DataType) {} + public func record(_: Int64) {} + public func record(_: Double) {} public func recordNanoseconds(_: Int64) {} } diff --git a/Sources/Examples/ExampleMetricsLibrary.swift b/Sources/Examples/ExampleMetricsLibrary.swift index 66bb62d..421fb10 100644 --- a/Sources/Examples/ExampleMetricsLibrary.swift +++ b/Sources/Examples/ExampleMetricsLibrary.swift @@ -138,27 +138,25 @@ class ExampleRecorder: RecorderHandler, CustomStringConvertible { private let lock = NSLock() var values = [(Int64, Double)]() - func record(_ value: DataType) { + func record(_ value: Int64) { self.record(Double(value)) } - func record(_ value: DataType) { - // this may loose precision, but good enough as an example - let v = Double(value) + func record(_ value: Double) { // TODO: sliding window - lock.withLock { - values.append((Date().nanoSince1970, v)) + self.lock.withLock { + values.append((Date().nanoSince1970, value)) } - options.forEach { option in + self.options.forEach { option in switch option { case .count: self.count += 1 case .sum: - self.sum += v + self.sum += value case .min: - if 0 == self.min || v < self.min { self.min = v } + self.min = Swift.min(self.min, value) case .max: - if 0 == self.max || v > self.max { self.max = v } + self.max = Swift.max(self.max, value) case .quantiles(let items): self.computeQuantiles(items) } @@ -224,7 +222,7 @@ class ExampleRecorder: RecorderHandler, CustomStringConvertible { self.lock.withLock { self._quantiels.removeAll() items.forEach { item in - if let result = Sigma.quantiles.method1(self.values.map { Double($0.1) }, probability: Double(item)) { + if let result = Sigma.quantiles.method1(self.values.map { $0.1 }, probability: Double(item)) { self._quantiels[item] = result } } @@ -242,13 +240,12 @@ class ExampleGauge: RecorderHandler, CustomStringConvertible { let lock = NSLock() var _value: Double = 0 - func record(_ value: DataType) { + func record(_ value: Int64) { self.record(Double(value)) } - func record(_ value: DataType) { - // this may loose precision but good enough as an example - self.lock.withLock { _value = Double(value) } + func record(_ value: Double) { + self.lock.withLock { _value = value } } var description: String { diff --git a/Sources/Examples/SimpleMetricsLibrary.swift b/Sources/Examples/SimpleMetricsLibrary.swift index 0242773..1724e89 100644 --- a/Sources/Examples/SimpleMetricsLibrary.swift +++ b/Sources/Examples/SimpleMetricsLibrary.swift @@ -38,9 +38,9 @@ class SimpleMetricsLibrary: MetricsFactory { let lock = NSLock() var value: Int64 = 0 - func increment(_ value: DataType) { + func increment(_ value: Int64) { self.lock.withLock { - self.value += Int64(value) + self.value += value } } @@ -56,20 +56,18 @@ class SimpleMetricsLibrary: MetricsFactory { private let lock = NSLock() var values = [(Int64, Double)]() - func record(_ value: DataType) { + func record(_ value: Int64) { self.record(Double(value)) } - func record(_ value: DataType) { - // this may loose precision, but good enough as an example - let v = Double(value) + func record(_ value: Double) { // TODO: sliding window - lock.withLock { - values.append((Date().nanoSince1970, v)) + self.lock.withLock { + values.append((Date().nanoSince1970, value)) self._count += 1 - self._sum += v - self._min = Swift.min(self._min, v) - self._max = Swift.max(self._max, v) + self._sum += value + self._min = Swift.min(self._min, value) + self._max = Swift.max(self._max, value) } } @@ -99,13 +97,12 @@ class SimpleMetricsLibrary: MetricsFactory { let lock = NSLock() var _value: Double = 0 - func record(_ value: DataType) { + func record(_ value: Int64) { self.record(Double(value)) } - func record(_ value: DataType) { - // this may loose precision but good enough as an example - self.lock.withLock { _value = Double(value) } + func record(_ value: Double) { + self.lock.withLock { _value = value } } } diff --git a/Tests/MetricsTests/TestMetrics.swift b/Tests/MetricsTests/TestMetrics.swift index 8fabebd..b0c36db 100644 --- a/Tests/MetricsTests/TestMetrics.swift +++ b/Tests/MetricsTests/TestMetrics.swift @@ -60,9 +60,9 @@ internal class TestCounter: CounterHandler, Equatable { self.dimensions = dimensions } - func increment(_ value: DataType) { + func increment(_ value: Int64) { self.lock.withLock { - self.values.append((Date(), Int64(value))) + self.values.append((Date(), value)) } print("adding \(value) to \(self.label)") } @@ -71,6 +71,7 @@ internal class TestCounter: CounterHandler, Equatable { self.lock.withLock { self.values = [] } + print("reseting \(self.label)") } public static func == (lhs: TestCounter, rhs: TestCounter) -> Bool { @@ -94,11 +95,11 @@ internal class TestRecorder: RecorderHandler, Equatable { self.aggregate = aggregate } - func record(_ value: DataType) { + func record(_ value: Int64) { self.record(Double(value)) } - func record(_ value: DataType) { + func record(_ value: Double) { self.lock.withLock { // this may loose precision but good enough as an example values.append((Date(), Double(value)))