Skip to content

Inconsistent: Summary and Histogram deal with dimensional values differently than Counter #77

Open
@fabianfett

Description

@fabianfett

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

Metadata

Metadata

Assignees

Labels

kind/bugFeature doesn't work as expected.

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions