Open
Description
When I was using the Summary and Histogram type I noticed, that if I record a value for a metric with name and dimensions, the value is also recorded for the dimension less version of the metric. This is in contrast to the Counter, where an increment on a Counter that was created with a dimension, does not increment the dimension less counter.
We should have a consistent behavior here. @ktoso do you know by any chance what is correct?
Steps to reproduce
func testHistogramWithLabels() {
let prom = PrometheusClient()
var config = PrometheusMetricsFactory.Configuration()
config.timerImplementation = .histogram()
let metricsFactory = PrometheusMetricsFactory(client: prom)
let timer = metricsFactory.makeTimer(label: "duration_nanos", dimensions: [("foo", "bar")])
timer.recordNanoseconds(1)
let counter = metricsFactory.makeCounter(label: "simple_counter", dimensions: [("foo", "bar")])
counter.increment(by: 1)
prom.collect() { (output: String) in
print(output)
XCTAssert(output.utf8.hasSubSequence(#"duration_nanos_count 1"#.utf8)) // <--- 🚨 inconsistent part 1
XCTAssert(output.utf8.hasSubSequence(#"duration_nanos_count{foo="bar"} 1"#.utf8))
XCTAssert(output.utf8.hasSubSequence(#"simple_counter 0"#.utf8)) // <--- 🚨 inconsistent part 1
XCTAssert(output.utf8.hasSubSequence(#"simple_counter{foo="bar"} 1"#.utf8))
}
}
func testSummaryWithLabels() {
let prom = PrometheusClient()
var config = PrometheusMetricsFactory.Configuration()
config.timerImplementation = .summary()
let metricsFactory = PrometheusMetricsFactory(client: prom)
let timer = metricsFactory.makeTimer(label: "duration_nanos", dimensions: [("foo", "bar")])
timer.recordNanoseconds(1)
let counter = metricsFactory.makeCounter(label: "simple_counter", dimensions: [("foo", "bar")])
counter.increment(by: 1)
prom.collect() { (output: String) in
print(output)
XCTAssert(output.utf8.hasSubSequence(#"duration_nanos_count 1"#.utf8)) // <--- 🚨 inconsistent part 2
XCTAssert(output.utf8.hasSubSequence(#"duration_nanos_count{foo="bar"} 1"#.utf8))
XCTAssert(output.utf8.hasSubSequence(#"simple_counter 0"#.utf8)) // <--- 🚨 inconsistent part 2
XCTAssert(output.utf8.hasSubSequence(#"simple_counter{foo="bar"} 1"#.utf8))
}
}
}
extension Sequence {
func hasSubSequence<Other: Collection>(_ other: Other) -> Bool where Other.Element == Self.Element, Other.Element: Equatable {
var otherIterator = other.makeIterator()
for element in self {
let next = otherIterator.next()
if element == next {
continue
} else if next == nil {
return true
} else {
// unequal. reset iterator
otherIterator = other.makeIterator()
}
}
// check if other is also done
if otherIterator.next() == nil {
return true
}
return false
}
}
Environment
SwiftPrometheus: 1.0.0