Browse Source

Family{C}: use n-tuples for label names and values.

pull/6/head
Fredrik Ekre 2 years ago
parent
commit
f442736315
  1. 4
      docs/src/index.md
  2. 32
      src/Prometheus.jl
  3. 16
      src/gc_collector.jl
  4. 6
      src/process_collector.jl
  5. 28
      test/runtests.jl

4
docs/src/index.md

@ -167,8 +167,8 @@ See <https://prometheus.io/docs/concepts/data_model/#metric-names-and-labels> fo @@ -167,8 +167,8 @@ See <https://prometheus.io/docs/concepts/data_model/#metric-names-and-labels> 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)
```

32
src/Prometheus.jl

@ -355,12 +355,12 @@ end @@ -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) @@ -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 @@ -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) @@ -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 @@ -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 @@ -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. @@ -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

16
src/gc_collector.jl

@ -46,12 +46,12 @@ function collect!(metrics::Vector, ::GCCollector) @@ -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) @@ -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),
],
),
)

6
src/process_collector.jl

@ -121,10 +121,10 @@ function collect!(metrics::Vector, procc::ProcessCollector) @@ -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)

28
test/runtests.jl

@ -151,9 +151,9 @@ end @@ -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 @@ -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 @@ -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 @@ -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 @@ -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

Loading…
Cancel
Save