From dc8a75fb686a1a6d19d5cc14d2ab55318f414f11 Mon Sep 17 00:00:00 2001 From: MrLotU Date: Tue, 4 May 2021 08:54:53 +0200 Subject: [PATCH] Add fix and test for MetricsSystem.prometheus() --- Sources/Prometheus/PrometheusMetrics.swift | 16 ++++++++++++---- .../PrometheusMetricsTests.swift | 7 +++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/Sources/Prometheus/PrometheusMetrics.swift b/Sources/Prometheus/PrometheusMetrics.swift index cad5338..98c38c0 100644 --- a/Sources/Prometheus/PrometheusMetrics.swift +++ b/Sources/Prometheus/PrometheusMetrics.swift @@ -139,13 +139,21 @@ public struct PrometheusLabelSanitizer: LabelSanitizer { } } +/// Defines the base for a bridge between PrometheusClient and swift-metrics. +/// Used by `SwiftMetrics.prometheus()` to get an instance of `PromtheusClient` from `MetricsSystem` +/// +/// Any custom implementation of `MetricsFactory` using `PrometheusClient` should conform to this implementation. +public protocol PrometheusWrappedMetricsFactory: MetricsFactory { + var client: PrometheusClient { get } +} + /// A bridge between PrometheusClient and swift-metrics. Prometheus types don't map perfectly on swift-metrics API, /// which makes bridge implementation non trivial. This class defines how exactly swift-metrics types should be backed /// with Prometheus types, e.g. how to sanitize labels, what buckets/quantiles to use for recorder/timer, etc. -public struct PrometheusMetricsFactory: MetricsFactory { +public struct PrometheusMetricsFactory: PrometheusWrappedMetricsFactory { /// Prometheus client to bridge swift-metrics API to. - private let client: PrometheusClient + public let client: PrometheusClient /// Bridge configuration. private let configuration: Configuration @@ -262,10 +270,10 @@ public extension MetricsSystem { /// - Throws: `PrometheusError.PrometheusFactoryNotBootstrapped` /// if no `PrometheusClient` was used to bootstrap `MetricsSystem` static func prometheus() throws -> PrometheusClient { - guard let prom = self.factory as? PrometheusClient else { + guard let prom = self.factory as? PrometheusWrappedMetricsFactory else { throw PrometheusError.prometheusFactoryNotBootstrapped(bootstrappedWith: "\(self.factory)") } - return prom + return prom.client } } diff --git a/Tests/SwiftPrometheusTests/PrometheusMetricsTests.swift b/Tests/SwiftPrometheusTests/PrometheusMetricsTests.swift index 9226c59..24f7217 100644 --- a/Tests/SwiftPrometheusTests/PrometheusMetricsTests.swift +++ b/Tests/SwiftPrometheusTests/PrometheusMetricsTests.swift @@ -21,6 +21,13 @@ final class PrometheusMetricsTests: XCTestCase { self.prom = nil try! self.group.syncShutdownGracefully() } + + func testGetPrometheus() { + MetricsSystem.bootstrapInternal(NOOPMetricsHandler.instance) + XCTAssertThrowsError(try MetricsSystem.prometheus()) + MetricsSystem.bootstrapInternal(PrometheusMetricsFactory(client: self.prom)) + XCTAssertNoThrow(try MetricsSystem.prometheus()) + } func testCounter() { let counter = Counter(label: "my_counter")