Skip to content

Commit

Permalink
Family{C}: use n-tuples for label names and values.
Browse files Browse the repository at this point in the history
  • Loading branch information
fredrikekre committed Nov 5, 2023
1 parent 3363f3e commit f442736
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 43 deletions.
4 changes: 2 additions & 2 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
```

Expand Down
32 changes: 16 additions & 16 deletions src/Prometheus.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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`.
Expand All @@ -444,15 +444,15 @@ 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
return collector
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
Expand All @@ -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
Expand Down
16 changes: 8 additions & 8 deletions src/gc_collector.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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),
],
),
)
Expand Down
6 changes: 3 additions & 3 deletions src/process_collector.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
28 changes: 14 additions & 14 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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(...)
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit f442736

Please sign in to comment.