From b7ed98cfa6f3162577dc23b4e6f4a354e60cbdff Mon Sep 17 00:00:00 2001 From: Fabian Fett Date: Fri, 22 Sep 2023 12:11:09 +0200 Subject: [PATCH] Add docs for version 2.0 (#100) - Removed overly verbose issue and pr templates - Removed documentation from README - Readme now links to spi documentation page - Added docc documentation - Removed last usages of `TimeHistogram` Co-authored-by: Franz Busch Co-authored-by: hamzahrmalik --- .github/ISSUE_TEMPLATE/BUG_REPORT.md | 32 ---- .github/ISSUE_TEMPLATE/FEATURE_REQUEST.md | 23 --- .github/ISSUE_TEMPLATE/OTHER.md | 9 - .github/PULL_REQUEST_TEMPLATE.md | 16 -- README.md | 140 ++------------- Sources/Prometheus/Docs.docc/index.md | 68 ++++++- Sources/Prometheus/Docs.docc/swift-metrics.md | 170 ++++++++++++++++++ .../Prometheus/PrometheusMetricsFactory.swift | 30 ++-- .../PrometheusMetricsFactoryTests.swift | 28 +-- 9 files changed, 276 insertions(+), 240 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/BUG_REPORT.md delete mode 100644 .github/ISSUE_TEMPLATE/FEATURE_REQUEST.md delete mode 100644 .github/ISSUE_TEMPLATE/OTHER.md delete mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 Sources/Prometheus/Docs.docc/swift-metrics.md diff --git a/.github/ISSUE_TEMPLATE/BUG_REPORT.md b/.github/ISSUE_TEMPLATE/BUG_REPORT.md deleted file mode 100644 index 69ce72a..0000000 --- a/.github/ISSUE_TEMPLATE/BUG_REPORT.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -name: 🐛 Bug Report -about: If something isn't working as expected 🤔 - ---- - - - - - -### Steps to reproduce - - - - - -### Expected behavior - - - -### Actual behavior - - - -### Environment - - - -* OS version: -* Swift version: -* Serverside Swift Framework: -* Framework version: \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md b/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md deleted file mode 100644 index d04e206..0000000 --- a/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -name: 🚀 Feature Request -about: A suggestion for a new feature ✨ - ---- - - - -### Feature Request - - - -#### Motivation Behind Feature - - -#### Feature Description - - - - -#### Alternatives or Workarounds - - diff --git a/.github/ISSUE_TEMPLATE/OTHER.md b/.github/ISSUE_TEMPLATE/OTHER.md deleted file mode 100644 index cedb8e0..0000000 --- a/.github/ISSUE_TEMPLATE/OTHER.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -name: Other issues -about: If something else is on your mind - ---- - - - - diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index 83a9f2c..0000000 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,16 +0,0 @@ - - - - -### Checklist -- [ ] The provided tests still run. -- [ ] I've created new tests where needed. -- [ ] I've updated the documentation if necessary. - -### Motivation and Context - - - -### Description - - diff --git a/README.md b/README.md index 9c1f09c..7dbebc1 100644 --- a/README.md +++ b/README.md @@ -1,139 +1,23 @@ -[![Swift 5.2](https://img.shields.io/badge/swift-5.2-orange.svg?style=flat)](http://swift.org) +# Swift Prometheus -# SwiftPrometheus, Prometheus client for Swift +[![sswg:sandbox](https://img.shields.io/badge/sswg-sandbox-yellow.svg)][SSWG-Incubation] +[![Documentation](http://img.shields.io/badge/read_the-docs-2196f3.svg)][Documentation] -A prometheus client for Swift supporting counters, gauges, histograms, summaries and info. - -# Installation - -SwiftPrometheus is available through SPM. To include it in your project add the following dependency to your `Package.swift`: -```swift -.package(url: "https://github.com/swift-server-community/SwiftPrometheus.git", from: "1.0.2") -``` - -# Usage - -To see a working demo, see [PrometheusExample](./Sources/PrometheusExample/main.swift). - -First, we have to create an instance of our `PrometheusClient`: - -```swift -import Prometheus -let myProm = PrometheusClient() -``` - -## Usage with SwiftMetrics -_For more details about swift-metrics, please view [the GitHub repo](https://github.com/apple/swift-metrics)._ - -Starting with SwiftPrometheus [1.0.0-alpha.10](https://github.com/swift-server-community/SwiftPrometheus/releases/tag/1.0.0-alpha.10) `MetricsSystem` is no longer directly configured with a `PrometheusClient`. - -Instead, create a `PrometheusMetricsFactory` instance wrapping a `PrometheusClient`. - -```swift -let myProm = PrometheusClient() -MetricsSystem.bootstrap(PrometheusMetricsFactory(client: myProm)) -``` - -Along with a `PrometheusClient`, `PrometheusMetricsFactory` can take a `Configuration` object setting the following properties: -- A `LabelSanitizer` used to sanitize metric names to valid Prometheus values. A default implementation is provided. -- The Prometheus metric type to use for swift-metrics' `Timer`. Can be a `Histogram` or a `Summary`. Note that when using `Histogram`, `preferredDisplayUnit` will not be observed. -- Default buckets for use by aggregating swift-metrics `Recorder` instances. - -### Before Alpha 10 - -To use SwiftPrometheus with swift-metrics, you need to configure the backend inside the `MetricsSystem`: - -```swift -import Metrics -import Prometheus -let myProm = PrometheusClient() -MetricsSystem.bootstrap(myProm) -``` - -To use prometheus-specific features in a later stage of your program, or to get your metrics out of the system, there is a convenience method added to `MetricsSystem`: - -```swift -// This returns the same instance passed in to `.bootstrap()` earlier. -let promInstance = try MetricsSystem.prometheus() -print(promInstance.collect()) -``` - -You can then use the same APIs described in the rest of this README. - -## Counter - -Counters go up (they can only increase in value), and reset when the process restarts. - -```swift -let counter = myProm.createCounter(forType: Int.self, named: "my_counter") -counter.inc() // Increment by 1 -counter.inc(12) // Increment by given value -``` - -## Gauge - -Gauges can go up and down, they represent a "point-in-time" snapshot of a value. This is similar to the speedometer of a car. - -```swift -let gauge = myProm.createGauge(forType: Int.self, named: "my_gauge") -gauge.inc() // Increment by 1 -gauge.dec(19) // Decrement by given value -gauge.set(12) // Set to a given value -``` - -## Histogram - -Histograms track the size and number of events in buckets. This allows for aggregatable calculation of quantiles. - -```swift -let histogram = myProm.createHistogram(forType: Double.self, named: "my_histogram") -histogram.observe(4.7) // Observe the given value -``` - -## Summary - -Summaries track the size and number of events - -```swift -let summary = myProm.createSummary(forType: Double.self, named: "my_summary") -summary.observe(4.7) // Observe the given value -``` - -## Labels -All metric types support adding labels, allowing for grouping of related metrics. Labels are passed when recording values to your metric as an instance of `DimensionLabels`, or as an array of `(String, String)`. - -Example with a counter: - -```swift -let counter = myProm.createCounter(forType: Int.self, named: "my_counter", helpText: "Just a counter") - -let counter = prom.createCounter(forType: Int.self, named: "my_counter", helpText: "Just a counter") - -counter.inc(12, .init([("route", "/users")])) -// OR -counter.inc(12, [("route", "/users")]) -``` - -# Exporting - -Prometheus itself is designed to "pull" metrics from a destination. Following this pattern, SwiftPrometheus is designed to expose metrics, as opposed to submitted/exporting them directly to Prometheus itself. SwiftPrometheus produces a formatted string that Prometheus can parse, which can be integrated into your own application. - -By default, this should be accessible on your main serving port, at the `/metrics` endpoint. An example in [Vapor](https://vapor.codes) 4 syntax looks like: - -```swift -app.get("metrics") { req async throws -> String in - return try await MetricsSystem.prometheus().collect() -} -``` +A prometheus client for Swift supporting counters, gauges and histograms. Swift Prometheus +implements the Swift Metrics API. ## Security Please see [SECURITY.md](SECURITY.md) for details on the security process. -# Contributing +## Contributing All contributions are most welcome! -If you think of some cool new feature that should be included, please [create an issue](https://github.com/swift-server-community/SwiftPrometheus/issues/new/choose). Or, if you want to implement it yourself, [fork this repo](https://github.com/swift-server-community/SwiftPrometheus/fork) and submit a PR! +If you think of some cool new feature that should be included, please [create an issue](https://github.com/swift-server/swift-prometheus/issues/new). +Or, if you want to implement it yourself, [fork this repo](https://github.com/swift-server/swift-prometheus/fork) and submit a PR! + +If you find a bug or have issues, please [create an issue](https://github.com/swift-server-community/SwiftPrometheus/issues/new) explaining your problems. Please include as much information as possible, so it's easier for us to reproduce (Framework, OS, Swift version, terminal output, etc.) -If you find a bug or have issues, please [create an issue](https://github.com/swift-server-community/SwiftPrometheus/issues/new/choose) explaining your problems. Please include as much information as possible, so it's easier for me to reproduce (Framework, OS, Swift version, terminal output, etc.) +[Documentation]: https://swiftpackageindex.com/swift-server/swift-prometheus/documentation/prometheus +[SSWG-Incubation]: https://www.swift.org/sswg/incubation-process.html diff --git a/Sources/Prometheus/Docs.docc/index.md b/Sources/Prometheus/Docs.docc/index.md index b72b320..6444da3 100644 --- a/Sources/Prometheus/Docs.docc/index.md +++ b/Sources/Prometheus/Docs.docc/index.md @@ -5,15 +5,77 @@ A prometheus client library for Swift. ## Overview ``Prometheus`` supports creating ``Counter``s, ``Gauge``s and ``Histogram``s and exporting their -values in the Prometheus export format. +values in the Prometheus text format. + +``Prometheus`` integrates with [Swift Metrics](doc:swift-metrics). + +## Installation + +``Prometheus`` is available through Swift Package Manager. To include it in your project add the +following dependency to your `Package.swift`: + +```swift + .package(url: "https://github.com/swift-server/swift-prometheus.git", from: "2.0.0-alpha") +``` + +Next, add the dependency to your target: + +```swift + .target( + name: "MyTarget", + dependencies: [ + // your other dependencies + .product(name: "Prometheus", package: "swift-prometheus"), + ] + ), +``` + +## Usage + +In your Swift file you must first `import Prometheus`: + +```swift +import Prometheus +``` + +Next you need to create a ``PrometheusCollectorRegistry``, which you use to create ``Counter``s, +``Gauge``s and ``Histogram``s. + +```swift +let registry = PrometheusCollectorRegistry() + +let myCounter = registry.makeCounter(name: "my_counter") +myCounter.increment() + +let myGauge = registry.makeGauge(name: "my_gauge") +myGauge.increment() +myGauge.decrement() +``` + +Lastly, you can use your ``PrometheusCollectorRegistry`` to generate a Prometheus export in the +text representation: + +```swift +var buffer = [UInt8]() +buffer.reserveCapacity(1024) // potentially smart moves to reduce the number of reallocations +registry.emit(into: buffer) + +print(String(decoding: buffer, as: Unicode.UTF8.self)) +``` ## Topics -### Collectors +### Getting started + +- +- ``PrometheusCollectorRegistry`` +- ``PrometheusMetricsFactory`` + + +### Metrics - ``Counter`` - ``Gauge`` - ``Histogram`` - - ``Bucketable`` - ``DurationHistogram`` - ``ValueHistogram`` diff --git a/Sources/Prometheus/Docs.docc/swift-metrics.md b/Sources/Prometheus/Docs.docc/swift-metrics.md new file mode 100644 index 0000000..b4a8eba --- /dev/null +++ b/Sources/Prometheus/Docs.docc/swift-metrics.md @@ -0,0 +1,170 @@ +# Usage with SwiftMetrics + +In this article you will learn how Swift Prometheus integrates with Swift Metrics and how you can +use both libraries together. + +## Overview + +Swift ``Prometheus`` integrates with Swift Metrics v2. Swift Metrics provides an interface to allow +library authors and application developers to emit metrics without specifying a concrete metric +backend. + +### Adding the dependency + +First you need to add the `swift-metrics` and `swit-prometheus` dependency to your Package.swift +in the `dependencies` section: + +```swift + dependencies: [ + // your other dependencies + .package(url: "https://github.com/swift-server/swift-prometheus.git", from: "2.0.0"), + .package(url: "https://github.com/apple/swift-metrics.git", from: "2.4.1"), + ] +``` + +Next, add the dependencies to your target. + +```swift + .target( + name: "MyTarget", + dependencies: [ + .product(name: "Prometheus", package: "swift-prometheus"), + .product(name: "Metrics", package: "swift-metrics"), + ] + ), +``` + +### Setting up Prometheus to export to Swift Metrics + +At application startup you need to create a ``PrometheusMetricsFactory`` and register it as +the metrics backend for swift-metrics: + +```swift +import Metrics +import Prometheus + +func main() { + let factory = PrometheusMetricsFactory() + MetricSystem.bootstrap(factory) + + // the rest of your application code +} +``` + +## Modifying the Prometheus Export + +Now that we have setup the Prometheus export, lets discuss which configuration options there are to +modify the Swift Metrics export. + +### Using a specific Collector Registry as the Export Target + +If you create a `PrometheusMetricsFactory()` without specifying a ``PrometheusCollectorRegistry``, +it will use ``PrometheusMetricsFactory/defaultRegistry`` as the underlying collector registry. +To use a different collector registry pass your ``PrometheusCollectorRegistry`` when creating +``PrometheusMetricsFactory/init(registry:)``: + +```swift +let registry = PrometheusCollectorRegistry() +let factory = PrometheusMetricsFactory(registry: registry) +MetricSystem.bootstrap(factory) +``` + +You can also overwrite the ``PrometheusMetricsFactory/registry`` by setting it explicitly: + +```swift +let registry = PrometheusCollectorRegistry() +var factory = PrometheusMetricsFactory() +factory.registry = registry +MetricSystem.bootstrap(factory) +``` + +### Modifying Swift metrics names and labels + +When you create a ``PrometheusMetricsFactory``, you can also set the +``PrometheusMetricsFactory/nameAndLabelSanitizer`` to modify the metric names and labels: + +```swift +var factory = PrometheusMetricsFactory() +factory.nameAndLabelSanitizer = { (name, labels) + switch name { + case "my_counter": + return ("counter", labels) + default: + return (name, labels) + } +} +MetricSystem.bootstrap(factory) + +// somewhere else +Metrics.Counter(label: "my_counter") // will show up in Prometheus exports as `counter` +``` + +This can be particularly usefull, if you want to change the names and labels for metrics that are +generated in a third party library. + +### Defining Buckets for Histograms + +#### Default buckets + +Swift Metric ``Timer``s are backed by a Prometheus ``DurationHistogram`` and Swift Metric +``Recorder``s that aggregate are backed by a Prometheus ``ValueHistogram``. As a user, you can +specify which buckets shall be used within the backing ``Histogram``s. + +```swift +var factory = PrometheusMetricsFactory() + +factory.defaultDurationHistogramBuckets = [ + .milliseconds(5), + .milliseconds(10), + .milliseconds(25), + .milliseconds(50), + .milliseconds(100), +] + +factory.defaultValueHistogramBuckets = [ + 5, + 10, + 25, + 50, + 100, + 250, +] +MetricSystem.bootstrap(factory) + +// somewhere else +Timer(label: "my_timer") // will use the buckets specified in `defaultDurationHistogramBuckets` +Recorder(label: "my_recorder", aggregate: true) // will use the buckets specified in `defaultValueHistogramBuckets` +``` + +#### Buckets by name + +You can also specify the buckets by metric name: + +```swift +var factory = PrometheusMetricsFactory() + +factory.defaultDurationHistogramBuckets = [ + .milliseconds(5), + .milliseconds(10), + .milliseconds(25), + .milliseconds(50), + .milliseconds(100), +] + +factory.durationHistogramBuckets["long"] = [ + .seconds(5), + .seconds(10), + .seconds(25), + .seconds(50), + .seconds(100), +] +``` + +Now a `Timer` with the label "long" will use the buckets +`[.seconds(5), .seconds(10), .seconds(25), .seconds(50), .seconds(100),]`, whereas any other +`Timer` will use the default buckets +`[.milliseconds(5), .milliseconds(10), .milliseconds(25), .milliseconds(50), .milliseconds(100),]`. + +The same functionality is also available for ``ValueHistogram`` and aggregating `Recorder`s. + +[Swift Metrics]: https://github.com/apple/swift-metrics diff --git a/Sources/Prometheus/PrometheusMetricsFactory.swift b/Sources/Prometheus/PrometheusMetricsFactory.swift index ae89b1d..d6a31df 100644 --- a/Sources/Prometheus/PrometheusMetricsFactory.swift +++ b/Sources/Prometheus/PrometheusMetricsFactory.swift @@ -28,12 +28,12 @@ public struct PrometheusMetricsFactory: Sendable { public var registry: PrometheusCollectorRegistry /// The default histogram buckets for a ``TimeHistogram``. If there is no explicit overwrite - /// via ``timeHistogramBuckets``, the buckets provided here will be used for any new + /// via ``durationHistogramBuckets``, the buckets provided here will be used for any new /// Swift Metrics `Timer` type. - public var defaultTimeHistogramBuckets: [Duration] + public var defaultDurationHistogramBuckets: [Duration] /// The histogram buckets for a ``TimeHistogram`` per Timer label - public var timeHistogramBuckets: [String: [Duration]] + public var durationHistogramBuckets: [String: [Duration]] /// The default histogram buckets for a ``ValueHistogram``. If there is no explicit overwrite /// via ``valueHistogramBuckets``, the buckets provided here will be used for any new @@ -43,15 +43,15 @@ public struct PrometheusMetricsFactory: Sendable { /// The histogram buckets for a ``ValueHistogram`` per label public var valueHistogramBuckets: [String: [Double]] - /// A closure to modify the label and dimension names used in the Swift Metrics API. This allows users + /// A closure to modify the name and labels used in the Swift Metrics API. This allows users /// to overwrite the Metric names in third party packages. - public var labelAndDimensionSanitizer: @Sendable (_ label: String, _ dimensions: [(String, String)]) -> (String, [(String, String)]) + public var nameAndLabelSanitizer: @Sendable (_ name: String, _ labels: [(String, String)]) -> (String, [(String, String)]) - public init(client: PrometheusCollectorRegistry = Self.defaultRegistry) { - self.registry = client + public init(registry: PrometheusCollectorRegistry = Self.defaultRegistry) { + self.registry = registry - self.timeHistogramBuckets = [:] - self.defaultTimeHistogramBuckets = [ + self.durationHistogramBuckets = [:] + self.defaultDurationHistogramBuckets = [ .milliseconds(5), .milliseconds(10), .milliseconds(25), @@ -80,23 +80,23 @@ public struct PrometheusMetricsFactory: Sendable { 10000, ] - self.labelAndDimensionSanitizer = { ($0, $1) } + self.nameAndLabelSanitizer = { ($0, $1) } } } extension PrometheusMetricsFactory: CoreMetrics.MetricsFactory { public func makeCounter(label: String, dimensions: [(String, String)]) -> CoreMetrics.CounterHandler { - let (label, dimensions) = self.labelAndDimensionSanitizer(label, dimensions) + let (label, dimensions) = self.nameAndLabelSanitizer(label, dimensions) return self.registry.makeCounter(name: label, labels: dimensions) } public func makeFloatingPointCounter(label: String, dimensions: [(String, String)]) -> FloatingPointCounterHandler { - let (label, dimensions) = self.labelAndDimensionSanitizer(label, dimensions) + let (label, dimensions) = self.nameAndLabelSanitizer(label, dimensions) return self.registry.makeCounter(name: label, labels: dimensions) } public func makeRecorder(label: String, dimensions: [(String, String)], aggregate: Bool) -> CoreMetrics.RecorderHandler { - let (label, dimensions) = self.labelAndDimensionSanitizer(label, dimensions) + let (label, dimensions) = self.nameAndLabelSanitizer(label, dimensions) if aggregate { let buckets = self.valueHistogramBuckets[label] ?? self.defaultValueHistogramBuckets return self.registry.makeValueHistogram(name: label, labels: dimensions, buckets: buckets) @@ -110,8 +110,8 @@ extension PrometheusMetricsFactory: CoreMetrics.MetricsFactory { } public func makeTimer(label: String, dimensions: [(String, String)]) -> CoreMetrics.TimerHandler { - let (label, dimensions) = self.labelAndDimensionSanitizer(label, dimensions) - let buckets = self.timeHistogramBuckets[label] ?? self.defaultTimeHistogramBuckets + let (label, dimensions) = self.nameAndLabelSanitizer(label, dimensions) + let buckets = self.durationHistogramBuckets[label] ?? self.defaultDurationHistogramBuckets return self.registry.makeDurationHistogram(name: label, labels: dimensions, buckets: buckets) } diff --git a/Tests/PrometheusTests/PrometheusMetricsFactoryTests.swift b/Tests/PrometheusTests/PrometheusMetricsFactoryTests.swift index e5af486..c1592e2 100644 --- a/Tests/PrometheusTests/PrometheusMetricsFactoryTests.swift +++ b/Tests/PrometheusTests/PrometheusMetricsFactoryTests.swift @@ -17,16 +17,16 @@ import Prometheus final class PrometheusMetricsFactoryTests: XCTestCase { func testMakeTimers() { - let client = PrometheusCollectorRegistry() - let factory = PrometheusMetricsFactory(client: client) + let registry = PrometheusCollectorRegistry() + let factory = PrometheusMetricsFactory(registry: registry) let timer = factory.makeTimer(label: "foo", dimensions: [("bar", "baz")]) XCTAssertNotNil(timer as? Histogram) } func testMakeRecorders() { - let client = PrometheusCollectorRegistry() - let factory = PrometheusMetricsFactory(client: client) + let registry = PrometheusCollectorRegistry() + let factory = PrometheusMetricsFactory(registry: registry) let maybeGauge = factory.makeRecorder(label: "foo", dimensions: [("bar", "baz")], aggregate: false) XCTAssertNotNil(maybeGauge as? Gauge) @@ -36,8 +36,8 @@ final class PrometheusMetricsFactoryTests: XCTestCase { } func testMakeCounters() { - let client = PrometheusCollectorRegistry() - let factory = PrometheusMetricsFactory(client: client) + let registry = PrometheusCollectorRegistry() + let factory = PrometheusMetricsFactory(registry: registry) let maybeCounter = factory.makeCounter(label: "foo", dimensions: [("bar", "baz")]) XCTAssertNotNil(maybeCounter as? Counter) @@ -51,7 +51,7 @@ final class PrometheusMetricsFactoryTests: XCTestCase { maybeFloatingPointCounter.increment(by: 2.5) var buffer = [UInt8]() - client.emit(into: &buffer) + registry.emit(into: &buffer) XCTAssertEqual(String(decoding: buffer, as: Unicode.UTF8.self), """ # TYPE foo counter foo{bar="baz"} 3.5 @@ -61,7 +61,7 @@ final class PrometheusMetricsFactoryTests: XCTestCase { factory.destroyCounter(maybeCounter) buffer.removeAll(keepingCapacity: true) - client.emit(into: &buffer) + registry.emit(into: &buffer) XCTAssertEqual(String(decoding: buffer, as: Unicode.UTF8.self), """ # TYPE foo counter @@ -70,8 +70,8 @@ final class PrometheusMetricsFactoryTests: XCTestCase { } func testMakeMeters() { - let client = PrometheusCollectorRegistry() - let factory = PrometheusMetricsFactory(client: client) + let registry = PrometheusCollectorRegistry() + let factory = PrometheusMetricsFactory(registry: registry) let maybeGauge = factory.makeMeter(label: "foo", dimensions: [("bar", "baz")]) XCTAssertNotNil(maybeGauge as? Gauge) @@ -80,7 +80,7 @@ final class PrometheusMetricsFactoryTests: XCTestCase { maybeGauge.decrement(by: 7) var buffer = [UInt8]() - client.emit(into: &buffer) + registry.emit(into: &buffer) XCTAssertEqual(String(decoding: buffer, as: Unicode.UTF8.self), """ # TYPE foo gauge foo{bar="baz"} -6.0 @@ -91,7 +91,7 @@ final class PrometheusMetricsFactoryTests: XCTestCase { // set to double value maybeGauge.set(12.45) buffer.removeAll(keepingCapacity: true) - client.emit(into: &buffer) + registry.emit(into: &buffer) XCTAssertEqual(String(decoding: buffer, as: Unicode.UTF8.self), """ # TYPE foo gauge foo{bar="baz"} 12.45 @@ -102,7 +102,7 @@ final class PrometheusMetricsFactoryTests: XCTestCase { // set to int value maybeGauge.set(Int64(42)) // needs explicit cast... otherwise ambigious buffer.removeAll(keepingCapacity: true) - client.emit(into: &buffer) + registry.emit(into: &buffer) XCTAssertEqual(String(decoding: buffer, as: Unicode.UTF8.self), """ # TYPE foo gauge foo{bar="baz"} 42.0 @@ -112,7 +112,7 @@ final class PrometheusMetricsFactoryTests: XCTestCase { factory.destroyMeter(maybeGauge) buffer.removeAll(keepingCapacity: true) - client.emit(into: &buffer) + registry.emit(into: &buffer) XCTAssertEqual(String(decoding: buffer, as: Unicode.UTF8.self), """ # TYPE foo gauge