Skip to content

Commit 18d0d7a

Browse files
committed
Wrap most functionality
1 parent ec3d756 commit 18d0d7a

File tree

5 files changed

+121
-33
lines changed

5 files changed

+121
-33
lines changed

Sources/Prometheus/MetricTypes/Histogram.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
private var defaultBuckets = [0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1.0, 2.5, 5.0, 7.5, 10.0, Double.greatestFiniteMagnitude]
1+
public var defaultBuckets = [0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1.0, 2.5, 5.0, 7.5, 10.0, Double.greatestFiniteMagnitude]
22

33
public protocol HistogramLabels: MetricLabels {
44
var le: String { get set }

Sources/Prometheus/MetricTypes/Summary.swift

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,31 @@ public class Summary<NumType: DoubleRepresentable, Labels: SummaryLabels>: Metri
6767
self.values.append(value)
6868
}
6969
}
70+
71+
func calculateQuantiles(quantiles: [Double], values: [Double]) -> [Double: Double] {
72+
let values = values.sorted()
73+
var quantilesMap: [Double: Double] = [:]
74+
quantiles.forEach { (q) in
75+
quantilesMap[q] = quantile(q, values)
76+
}
77+
return quantilesMap
78+
}
79+
80+
func quantile(_ q: Double, _ values: [Double]) -> Double {
81+
if values.count == 1 {
82+
return values[0]
83+
}
84+
85+
let n = Double(values.count)
86+
if let pos = Int(exactly: n*q) {
87+
if pos < 2 {
88+
return values[0]
89+
} else if pos == values.count {
90+
return values[pos - 1]
91+
}
92+
return (values[pos - 1] + values[pos]) / 2.0
93+
} else {
94+
let pos = Int((n*q).rounded(.up))
95+
return values[pos - 1]
96+
}
97+
}

Sources/Prometheus/Prometheus.swift

Lines changed: 69 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,12 @@ public class Prometheus {
4242
///
4343
/// - Returns: Counter instance
4444
public func createCounter<T: Numeric>(
45-
forType: T.Type,
45+
forType type: T.Type,
4646
named name: String,
4747
helpText: String? = nil,
4848
initialValue: T = 0) -> Counter<T, EmptyCodable>
4949
{
50-
return self.createCounter(forType: T.self, named: name, helpText: helpText, initialValue: initialValue, withLabelType: EmptyCodable.self)
50+
return self.createCounter(forType: type, named: name, helpText: helpText, initialValue: initialValue, withLabelType: EmptyCodable.self)
5151
}
5252

5353
// MARK: - Gauge
@@ -84,12 +84,77 @@ public class Prometheus {
8484
///
8585
/// - Returns: Gauge instance
8686
public func createGauge<T: Numeric>(
87-
forType: T.Type,
87+
forType type: T.Type,
8888
named name: String,
8989
helpText: String? = nil,
9090
initialValue: T = 0) -> Gauge<T, EmptyCodable>
9191
{
92-
return self.createGauge(forType: T.self, named: name, helpText: helpText, initialValue: initialValue, withLabelType: EmptyCodable.self)
92+
return self.createGauge(forType: type, named: name, helpText: helpText, initialValue: initialValue, withLabelType: EmptyCodable.self)
93+
}
94+
95+
// MARK: - Histogram
96+
97+
/// Creates a histogram with the given values
98+
///
99+
/// - Parameters:
100+
/// - type: The type the histogram will observe
101+
/// - name: Name of the histogram
102+
/// - helpText: Help text for the histogram. Usually a short description
103+
/// - buckets: Buckets to divide values over
104+
/// - labels: Labels to give this Histogram. Can be left out to default to no labels
105+
///
106+
/// - Returns: Histogram instance
107+
public func createHistogram<T: Numeric, U: HistogramLabels>(
108+
forType type: T.Type,
109+
named name: String,
110+
helpText: String? = nil,
111+
buckets: [Double] = defaultBuckets,
112+
labels: U) -> Histogram<T, U>
113+
{
114+
let histogram = Histogram<T, U>(name, helpText, labels, buckets)
115+
self.metrics.append(histogram)
116+
return histogram
117+
}
118+
119+
/// Creates a histogram with the given values
120+
///
121+
/// - Parameters:
122+
/// - type: The type the histogram will observe
123+
/// - name: Name of the histogram
124+
/// - helpText: Help text for the histogram. Usually a short description
125+
/// - buckets: Buckets to divide values over
126+
///
127+
/// - Returns: Histogram instance
128+
public func createHistogram<T: Numeric>(
129+
forType type: T.Type,
130+
named name: String,
131+
helpText: String? = nil,
132+
buckets: [Double] = defaultBuckets) -> Histogram<T, EmptyHistogramCodable>
133+
{
134+
return self.createHistogram(forType: type, named: name, helpText: helpText, buckets: buckets, labels: EmptyHistogramCodable())
135+
}
136+
137+
// MARK: - Summary
138+
139+
public func createSummary<T: Numeric, U: SummaryLabels>(
140+
forType type: T.Type,
141+
named name: String,
142+
helpText: String? = nil,
143+
quantiles: [Double] = defaultQuantiles,
144+
labels: U) -> Summary<T, U>
145+
{
146+
let summary = Summary<T, U>(name, helpText, quantiles, labels)
147+
metrics.append(summary)
148+
return summary
149+
}
150+
151+
public func createSummary<T: Numeric>(
152+
forType type: T.Type,
153+
named name: String,
154+
helpText: String? = nil,
155+
quantiles: [Double] = defaultQuantiles) -> Summary<T, EmptySummaryCodable>
156+
{
157+
return self.createSummary(forType: type, named: name, helpText: helpText, quantiles: quantiles, labels: EmptySummaryCodable())
93158
}
94159

95160
/// Creates prometheus formatted metrics

Sources/Prometheus/Utils.swift

Lines changed: 11 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,16 @@ public struct EmptyCodable: MetricLabels {
44
public init() { }
55
}
66

7+
public struct EmptyHistogramCodable: HistogramLabels {
8+
public var le: String = ""
9+
public init() { }
10+
}
11+
12+
public struct EmptySummaryCodable: SummaryLabels {
13+
public var quantile: String = ""
14+
public init() { }
15+
}
16+
717
public func encodeLabels<Labels: MetricLabels>(_ labels: Labels, _ excludingKeys: [String] = []) -> String {
818
// TODO: Fix this up to a custom decoder or something
919
do {
@@ -24,35 +34,8 @@ public func encodeLabels<Labels: MetricLabels>(_ labels: Labels, _ excludingKeys
2434
}
2535
}
2636

27-
func calculateQuantiles(quantiles: [Double], values: [Double]) -> [Double: Double] {
28-
let values = values.sorted()
29-
var quantilesMap: [Double: Double] = [:]
30-
quantiles.forEach { (q) in
31-
quantilesMap[q] = quantile(q, values)
32-
}
33-
return quantilesMap
34-
}
35-
36-
func quantile(_ q: Double, _ values: [Double]) -> Double {
37-
if values.count == 1 {
38-
return values[0]
39-
}
40-
41-
let n = Double(values.count)
42-
if let pos = Int(exactly: n*q) {
43-
if pos < 2 {
44-
return values[0]
45-
} else if pos == values.count {
46-
return values[pos - 1]
47-
}
48-
return (values[pos - 1] + values[pos]) / 2.0
49-
} else {
50-
let pos = Int((n*q).rounded(.up))
51-
return values[pos - 1]
52-
}
53-
}
54-
5537
extension Double {
38+
/// Overwrite for use by Histogram bucketing
5639
var description: String {
5740
if self == Double.greatestFiniteMagnitude {
5841
return "+Inf"

Sources/PrometheusExample/main.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,16 @@ let gauge = Prometheus.shared.createGauge(forType: Int.self, named: "my_gauge",
1515

1616
gauge.set(123)
1717

18+
let histogram = Prometheus.shared.createHistogram(forType: Double.self, named: "my_histogram", helpText: "Just a histogram")
19+
20+
for _ in 0...Int.random(in: 10...50) {
21+
histogram.observe(Double.random(in: 0...1))
22+
}
23+
24+
let summary = Prometheus.shared.createSummary(forType: Double.self, named: "my_summary", helpText: "Just a summary")
25+
26+
for _ in 0...Int.random(in: 100...1000) {
27+
summary.observe(Double.random(in: 0...10000))
28+
}
29+
1830
print(Prometheus.shared.getMetrics())

0 commit comments

Comments
 (0)