diff --git a/Sources/Prometheus/Gauge.swift b/Sources/Prometheus/Gauge.swift index af63ef6..78a8346 100644 --- a/Sources/Prometheus/Gauge.swift +++ b/Sources/Prometheus/Gauge.swift @@ -80,6 +80,16 @@ extension Gauge: CoreMetrics.RecorderHandler { } } +extension Gauge: CoreMetrics.MeterHandler { + public func set(_ value: Double) { + self.set(to: value) + } + + public func set(_ value: Int64) { + self.set(to: Double(value)) + } +} + extension Gauge: PrometheusMetric { func emit(into buffer: inout [UInt8]) { let value = Double(bitPattern: self.atomic.load(ordering: .relaxed)) diff --git a/Sources/Prometheus/PrometheusMetricsFactory.swift b/Sources/Prometheus/PrometheusMetricsFactory.swift index 606ff8c..babeab6 100644 --- a/Sources/Prometheus/PrometheusMetricsFactory.swift +++ b/Sources/Prometheus/PrometheusMetricsFactory.swift @@ -97,6 +97,10 @@ extension PrometheusMetricsFactory: CoreMetrics.MetricsFactory { } } + public func makeMeter(label: String, dimensions: [(String, String)]) -> CoreMetrics.MeterHandler { + return self.client.makeGauge(name: label, labels: dimensions) + } + public func makeTimer(label: String, dimensions: [(String, String)]) -> CoreMetrics.TimerHandler { let (label, dimensions) = self.labelAndDimensionSanitizer(label, dimensions) let buckets = self.timeHistogramBuckets[label] ?? self.defaultTimeHistogramBuckets @@ -128,6 +132,13 @@ extension PrometheusMetricsFactory: CoreMetrics.MetricsFactory { } } + public func destroyMeter(_ handler: CoreMetrics.MeterHandler) { + guard let gauge = handler as? Gauge else { + return + } + self.client.destroyGauge(gauge) + } + public func destroyTimer(_ handler: CoreMetrics.TimerHandler) { guard let histogram = handler as? Histogram else { return diff --git a/Tests/PrometheusTests/PrometheusMetricsFactoryTests.swift b/Tests/PrometheusTests/PrometheusMetricsFactoryTests.swift index 0982e25..fc91938 100644 --- a/Tests/PrometheusTests/PrometheusMetricsFactoryTests.swift +++ b/Tests/PrometheusTests/PrometheusMetricsFactoryTests.swift @@ -68,4 +68,56 @@ final class PrometheusMetricsFactoryTests: XCTestCase { """ ) } + + func testMakeMeters() { + let client = PrometheusCollectorRegistry() + let factory = PrometheusMetricsFactory(client: client) + + let maybeGauge = factory.makeMeter(label: "foo", dimensions: [("bar", "baz")]) + XCTAssertNotNil(maybeGauge as? Gauge) + + maybeGauge.increment(by: 1) + maybeGauge.decrement(by: 7) + + var buffer = [UInt8]() + client.emit(into: &buffer) + XCTAssertEqual(String(decoding: buffer, as: Unicode.UTF8.self), """ + # TYPE foo gauge + foo{bar="baz"} -6.0 + + """ + ) + + // set to double value + maybeGauge.set(12.45) + buffer.removeAll(keepingCapacity: true) + client.emit(into: &buffer) + XCTAssertEqual(String(decoding: buffer, as: Unicode.UTF8.self), """ + # TYPE foo gauge + foo{bar="baz"} 12.45 + + """ + ) + + // set to int value + maybeGauge.set(Int64(42)) // needs explicit cast... otherwise ambigious + buffer.removeAll(keepingCapacity: true) + client.emit(into: &buffer) + XCTAssertEqual(String(decoding: buffer, as: Unicode.UTF8.self), """ + # TYPE foo gauge + foo{bar="baz"} 42.0 + + """ + ) + + factory.destroyMeter(maybeGauge) + buffer.removeAll(keepingCapacity: true) + client.emit(into: &buffer) + XCTAssertEqual(String(decoding: buffer, as: Unicode.UTF8.self), """ + # TYPE foo gauge + + """ + ) + } + }