From bc4d19a990c6c2291f1a465b8767b99f1a152855 Mon Sep 17 00:00:00 2001 From: Fabian Fett Date: Fri, 22 Sep 2023 13:27:13 +0200 Subject: [PATCH] Document how to use labels (#101) Co-authored-by: hamzahrmalik --- Sources/Prometheus/Docs.docc/index.md | 5 ++ Sources/Prometheus/Docs.docc/labels.md | 84 +++++++++++++++++++ Sources/Prometheus/Docs.docc/swift-metrics.md | 11 ++- 3 files changed, 97 insertions(+), 3 deletions(-) create mode 100644 Sources/Prometheus/Docs.docc/labels.md diff --git a/Sources/Prometheus/Docs.docc/index.md b/Sources/Prometheus/Docs.docc/index.md index 6444da3..19329c2 100644 --- a/Sources/Prometheus/Docs.docc/index.md +++ b/Sources/Prometheus/Docs.docc/index.md @@ -9,6 +9,8 @@ values in the Prometheus text format. ``Prometheus`` integrates with [Swift Metrics](doc:swift-metrics). +For general advice on how to use `Prometheus` make sure to also read the [Prometheus documentation][prometheus-docs]. + ## Installation ``Prometheus`` is available through Swift Package Manager. To include it in your project add the @@ -68,6 +70,7 @@ print(String(decoding: buffer, as: Unicode.UTF8.self)) ### Getting started - +- - ``PrometheusCollectorRegistry`` - ``PrometheusMetricsFactory`` @@ -79,3 +82,5 @@ print(String(decoding: buffer, as: Unicode.UTF8.self)) - ``Histogram`` - ``DurationHistogram`` - ``ValueHistogram`` + +[prometheus-docs]: https://prometheus.io/docs/introduction/overview/ diff --git a/Sources/Prometheus/Docs.docc/labels.md b/Sources/Prometheus/Docs.docc/labels.md new file mode 100644 index 0000000..94e674a --- /dev/null +++ b/Sources/Prometheus/Docs.docc/labels.md @@ -0,0 +1,84 @@ +# Use Labels in Swift Prometheus + +Learn how to use Labels in Prometheus, the benefits of doing so, and how to avoid common mistakes. + +## Overview + +Prometheus Collectors have a name and they may have labels. Labels specify the metrics further. For +example you might have a ``Counter`` with the name `http_responses_total`. You may now add a label +`code` that specifies the http status response code. This way you are able to query how many http +responses were sent. But you can also filter this by response code. + +Read more about the benefits of using Labels in the [Prometheus best practices documentation][prometheus-use-labels]. + +> Note: The naming between Prometheus and Swift-Metrics is a bit confusing. Swift Metrics calls a +> metric's name its label and they call a metric's labels dimensions. In this article, when we +> refer to labels, we mean the additional properties that can be added to a metrics name. +> +> | Framework | Metric name | Additional infos | +> |---------------|-------------|------------------| +> | swift-metrics | `label` | `dimensions` | +> | Prometheus | `name` | `labels` | + +Please be aware that the ``PrometheusCollectorRegistry`` will create a seperate metric for each +unique label pair, even though the metric name might be the same. This means that in the example +below, we will have two independent metrics: + +```swift +let counter200 = registry.makeCounter(name: "http_responses_total", labels: ["code": "200"]) +let counter400 = registry.makeCounter(name: "http_responses_total", labels: ["code": "400"]) + +// handling response code +swift responseCode { +case .ok: + counter200.increment() +case .badRequest: + counter400.increment() +default: + break +} +``` + +> Important: Please note, that all metrics with the same name, **must** use the same label names. + +Prometheus requires that for the same metric name all labels names must be the same. Swift +Prometheus enforces this by crashing if the label names or the metric type does not match a +previously registered metric with the same name. + +#### Examples: + +The example below crashes as we try to create a ``Counter`` named `"http_responses_total"` with a +label `"code"` after a ``Counter`` with the same name without labels was created earlier. + +```swift +let counter = registry.makeCounter(name: "http_responses_total") +let counter200 = registry.makeCounter( // 💥 crash + name: "http_responses_total", + labels: ["code": "200"] +) +``` + +The example below crashes as we try to create a ``Counter`` named `"http_responses_total"` with a +label `"version"` after a ``Counter`` with the same name but different label name `"code"` was +created earlier. + +```swift +let counter200 = registry.makeCounter( + name: "http_responses_total", + labels: ["code": "200"] +) +let counterHTTPVersion1 = registry.makeCounter( // 💥 crash + name: "http_responses_total", + labels: ["version": "1.1"] +) +``` + +The example below crashes as we try to create a ``Gauge`` named `http_responses_total` with the +same name as a previously created ``Counter``. + +```swift +let counter = registry.makeCounter(name: "http_responses_total") +let gauge = registry.makeGauge(name: "http_responses_total") // 💥 crash +``` + +[prometheus-use-labels]: https://prometheus.io/docs/practices/instrumentation/#use-labels diff --git a/Sources/Prometheus/Docs.docc/swift-metrics.md b/Sources/Prometheus/Docs.docc/swift-metrics.md index b4a8eba..b9c9d5d 100644 --- a/Sources/Prometheus/Docs.docc/swift-metrics.md +++ b/Sources/Prometheus/Docs.docc/swift-metrics.md @@ -1,7 +1,7 @@ -# Usage with SwiftMetrics +# Emit metrics collected by Swift Metrics -In this article you will learn how Swift Prometheus integrates with Swift Metrics and how you can -use both libraries together. +Learn how Swift Prometheus integrates with Swift Metrics – an abstract API that is widely used in +the swift-server ecosystem. ## Overview @@ -102,6 +102,11 @@ Metrics.Counter(label: "my_counter") // will show up in Prometheus exports as `c This can be particularly usefull, if you want to change the names and labels for metrics that are generated in a third party library. +> Important: Please note, that all Prometheus metrics with the same name, **must** use the same +> label names. +> Use the ``PrometheusMetricsFactory/nameAndLabelSanitizer`` to ensure this remains true metrics +> that are created in third party libraries. See for more information about this. + ### Defining Buckets for Histograms #### Default buckets