From f442736315eb7bca5a117a7ff83e4487380d5519 Mon Sep 17 00:00:00 2001 From: Fredrik Ekre Date: Sun, 5 Nov 2023 21:41:35 +0100 Subject: [PATCH] Family{C}: use n-tuples for label names and values. --- docs/src/index.md | 4 ++-- src/Prometheus.jl | 32 ++++++++++++++++---------------- src/gc_collector.jl | 16 ++++++++-------- src/process_collector.jl | 6 +++--- test/runtests.jl | 28 ++++++++++++++-------------- 5 files changed, 43 insertions(+), 43 deletions(-) diff --git a/docs/src/index.md b/docs/src/index.md index f1eb638..8b39b6e 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -167,8 +167,8 @@ See fo ```@docs Prometheus.Family{C}(::String, ::String, ::Any; kwargs...) where C -Prometheus.labels(::Prometheus.Family, ::Vector{String}) -Prometheus.remove(::Prometheus.Family, ::Vector{String}) +Prometheus.labels(::Prometheus.Family{C, N}, ::NTuple{N, String}) where {C, N} +Prometheus.remove(::Prometheus.Family{C, N}, ::NTuple{N, String}) where {C, N} Prometheus.clear(::Prometheus.Family) ``` diff --git a/src/Prometheus.jl b/src/Prometheus.jl index 2873cd8..16b0394 100644 --- a/src/Prometheus.jl +++ b/src/Prometheus.jl @@ -355,12 +355,12 @@ end # Family{<:Collector} <: Collector # #################################### -struct LabelNames - labelnames::Vector{String} +struct LabelNames{N} + labelnames::NTuple{N, String} end -struct LabelValues - labelvalues::Vector{String} +struct LabelValues{N} + labelvalues::NTuple{N, String} end function Base.hash(l::LabelValues, h::UInt) h = hash(0x94a2d04ee9e5a55b, h) # hash("Prometheus.LabelValues") on Julia 1.9.3 @@ -373,20 +373,20 @@ function Base.:(==)(l1::LabelValues, l2::LabelValues) return l1.labelvalues == l2.labelvalues end -struct Family{C} <: Collector +struct Family{C, N} <: Collector metric_name::String help::String - labelnames::LabelNames - children::Dict{LabelValues, C} + labelnames::LabelNames{N} + children::Dict{LabelValues{N}, C} lock::ReentrantLock function Family{C}( - metric_name::String, help::String, labelnames::Vector{String}; + metric_name::String, help::String, labelnames::NTuple{N, String}; registry::Union{CollectorRegistry, Nothing}=DEFAULT_REGISTRY, - ) where C - children = Dict{LabelValues, C}() + ) where {C, N} + children = Dict{LabelValues{N}, C}() lock = ReentrantLock() - family = new(metric_name, help, LabelNames(labelnames), children, lock) + family = new{C, N}(metric_name, help, LabelNames(labelnames), children, lock) if registry !== nothing register(registry, family) end @@ -403,7 +403,7 @@ label values encountered a new collector of type `C <: Collector` will be create **Arguments** - `name :: String`: the name of the family metric. - `help :: String`: the documentation for the family metric. - - `labelnames :: Vector{String}`: the label names. + - `labelnames :: Tuple{String, ...}`: the label names. **Keyword arguments** - `registry :: Prometheus.CollectorRegistry`: the registry in which to register the @@ -433,7 +433,7 @@ function metric_names(family::Family) end """ - Prometheus.labels(family::Family{C}, labelvalues::Vector{String}) where C + Prometheus.labels(family::Family{C}, labelvalues::Tuple{String, ...}) where C Return the collector of type `C` from the family corresponding to the labels given by `labelvalues`. @@ -444,7 +444,7 @@ Return the collector of type `C` from the family corresponding to the labels giv matter (below 100ns for some basic benchmarks) but it is safe to cache the returned collector if required. """ -function labels(family::Family{C}, labelvalues::Vector{String}) where C +function labels(family::Family{C, N}, labelvalues::NTuple{N, String}) where {C, N} collector = @lock family.lock get!(family.children, LabelValues(labelvalues)) do C(family.metric_name, family.help; registry=nothing) end @@ -452,7 +452,7 @@ function labels(family::Family{C}, labelvalues::Vector{String}) where C end """ - Prometheus.remove(family::Family, labelvalues::Vector{String}) + Prometheus.remove(family::Family, labelvalues::Tuple{String, ...}) Remove the collector corresponding to `labelvalues`. Effectively this resets the collector since [`Prometheus.labels`](@ref) will recreate the collector when called with the same @@ -461,7 +461,7 @@ label names. !!! note This method invalidates cached collectors for the label names. """ -function remove(family::Family, labelvalues::Vector{String}) +function remove(family::Family{<:Any, N}, labelvalues::NTuple{N, String}) where N @lock family.lock delete!(family.children, LabelValues(labelvalues)) return end diff --git a/src/gc_collector.jl b/src/gc_collector.jl index 6f91e1d..bb95e74 100644 --- a/src/gc_collector.jl +++ b/src/gc_collector.jl @@ -46,12 +46,12 @@ function collect!(metrics::Vector, ::GCCollector) push!(metrics, Metric( "counter", "julia_gc_alloc_total", "Total number of allocations (calls to malloc, realloc, etc)", - LabelNames(["type"]), + LabelNames(("type",)), [ - Sample(nothing, LabelValues(["bigalloc"]), gc_num.bigalloc), - Sample(nothing, LabelValues(["malloc"]), gc_num.malloc), - Sample(nothing, LabelValues(["poolalloc"]), gc_num.poolalloc), - Sample(nothing, LabelValues(["realloc"]), gc_num.realloc), + Sample(nothing, LabelValues(("bigalloc",)), gc_num.bigalloc), + Sample(nothing, LabelValues(("malloc",)), gc_num.malloc), + Sample(nothing, LabelValues(("poolalloc",)), gc_num.poolalloc), + Sample(nothing, LabelValues(("realloc",)), gc_num.realloc), ], ), Metric( @@ -72,10 +72,10 @@ function collect!(metrics::Vector, ::GCCollector) ), Metric( "counter", "julia_gc_collections_total", "Total number of calls to garbage collection", - LabelNames(["type"]), + LabelNames(("type",)), [ - Sample(nothing, LabelValues(["full"]), gc_num.full_sweep), - Sample(nothing, LabelValues(["minor"]), gc_num.pause - gc_num.full_sweep), + Sample(nothing, LabelValues(("full",)), gc_num.full_sweep), + Sample(nothing, LabelValues(("minor",)), gc_num.pause - gc_num.full_sweep), ], ), ) diff --git a/src/process_collector.jl b/src/process_collector.jl index 03267a5..2717651 100644 --- a/src/process_collector.jl +++ b/src/process_collector.jl @@ -121,10 +121,10 @@ function collect!(metrics::Vector, procc::ProcessCollector) proc_cpu_seconds = Metric( "counter", "process_cpu_seconds_total", "Total CPU time (user and system mode) in seconds.", - LabelNames(["mode"]), + LabelNames(("mode",)), [ - Sample(nothing, LabelValues(["system"]), stime), - Sample(nothing, LabelValues(["user"]), utime), + Sample(nothing, LabelValues(("system",)), stime), + Sample(nothing, LabelValues(("user",)), utime), ], ) push!(metrics, proc_cpu_seconds) diff --git a/test/runtests.jl b/test/runtests.jl index 78cff7e..0b20873 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -151,9 +151,9 @@ end @testset "Prometheus.LabelNames and Prometheus.LabelValues" begin # Custom hashing - v1 = Prometheus.LabelValues(["foo", "bar"]) - v2 = Prometheus.LabelValues(["foo", "bar"]) - v3 = Prometheus.LabelValues(["foo", "baz"]) + v1 = Prometheus.LabelValues(("foo", "bar")) + v2 = Prometheus.LabelValues(("foo", "bar")) + v3 = Prometheus.LabelValues(("foo", "baz")) @test hash(v1) == hash(v2) @test hash(v1) != hash(v3) @test v1 == v2 @@ -167,20 +167,20 @@ end empty!(Prometheus.DEFAULT_REGISTRY.collectors) c = Prometheus.Family{Collector}( "http_requests", "Number of HTTP requests.", - ["endpoint", "status_code"], + ("endpoint", "status_code"), ) @test c in Prometheus.DEFAULT_REGISTRY.collectors r = Prometheus.CollectorRegistry() c = Prometheus.Family{Collector}( "http_requests", "Number of HTTP requests.", - ["endpoint", "status_code"]; + ("endpoint", "status_code"); registry = r, ) @test c in r.collectors @test length(c.children) == 0 # Prometheus.labels(...), Prometheus.remove(...), Prometheus.clear() - l1 = ["/foo/", "200"] - l2 = ["/bar/", "404"] + l1 = ("/foo/", "200") + l2 = ("/bar/", "404") @test Prometheus.labels(c, l1) === Prometheus.labels(c, l1) @test Prometheus.labels(c, l2) === Prometheus.labels(c, l2) @test length(c.children) == 2 @@ -207,8 +207,8 @@ end @test metric.help == c.help @test length(metric.samples) == 2 s1, s2 = metric.samples[1], metric.samples[2] - @test s1.labels.labelvalues == ["/bar/", "404"] - @test s2.labels.labelvalues == ["/foo/", "200"] + @test s1.labels.labelvalues == ("/bar/", "404") + @test s2.labels.labelvalues == ("/foo/", "200") @test s1.value == 3 @test s2.value == 3 # Prometheus.expose_metric(...) @@ -227,14 +227,14 @@ end r = Prometheus.CollectorRegistry() c = Prometheus.Family{Prometheus.Summary}( "http_request_time", "Time to process requests.", - ["endpoint", "status_code"]; + ("endpoint", "status_code"); registry = r, ) @test c in r.collectors @test length(c.children) == 0 # Prometheus.inc(...) - l1 = ["/foo/", "200"] - l2 = ["/bar/", "404"] + l1 = ("/foo/", "200") + l2 = ("/bar/", "404") @test Prometheus.labels(c, l1) === Prometheus.labels(c, l1) @test Prometheus.labels(c, l2) === Prometheus.labels(c, l2) @test length(c.children) == 2 @@ -262,8 +262,8 @@ end @test metric.help == c.help @test length(metric.samples) == 4 s1, s2, s3, s4 = metric.samples - @test s1.labels.labelvalues == s2.labels.labelvalues == ["/bar/", "404"] - @test s3.labels.labelvalues == s4.labels.labelvalues == ["/foo/", "200"] + @test s1.labels.labelvalues == s2.labels.labelvalues == ("/bar/", "404") + @test s3.labels.labelvalues == s4.labels.labelvalues == ("/foo/", "200") @test s1.value == 2 # _count @test s2.value == 6.4 # _sum @test s3.value == 2 # _count