From e79ec70373aecbc7d256c8bed40ac42e1c40e469 Mon Sep 17 00:00:00 2001 From: Fredrik Ekre Date: Fri, 17 Nov 2023 02:06:36 +0100 Subject: [PATCH] NFC: Move label names from Metric to Sample This patch moves the label names from the Metric struct to the Sample struct in preparation for the Histogram collector where only some of the samples have labels. --- src/Prometheus.jl | 32 +++++++++++++------------ src/gc_collector.jl | 52 +++++++++++++++++++++------------------- src/process_collector.jl | 46 +++++++++++++++++------------------ 3 files changed, 67 insertions(+), 63 deletions(-) diff --git a/src/Prometheus.jl b/src/Prometheus.jl index 916cdc3..4dc3346 100644 --- a/src/Prometheus.jl +++ b/src/Prometheus.jl @@ -202,7 +202,7 @@ function collect!(metrics::Vector, counter::Counter) push!(metrics, Metric( "counter", counter.metric_name, counter.help, - nothing, Sample(nothing, nothing, @atomic(counter.value)), + Sample(nothing, nothing, nothing, @atomic(counter.value)), ), ) return metrics @@ -310,7 +310,7 @@ function collect!(metrics::Vector, gauge::Gauge) push!(metrics, Metric( "gauge", gauge.metric_name, gauge.help, - nothing, Sample(nothing, nothing, @atomic(gauge.value)), + Sample(nothing, nothing, nothing, @atomic(gauge.value)), ), ) return metrics @@ -381,10 +381,10 @@ end function collect!(metrics::Vector, summary::Summary) push!(metrics, Metric( - "summary", summary.metric_name, summary.help, nothing, + "summary", summary.metric_name, summary.help, [ - Sample("_count", nothing, @atomic(summary._count)), - Sample("_sum", nothing, @atomic(summary._sum)), + Sample("_count", nothing, nothing, @atomic(summary._count)), + Sample("_sum", nothing, nothing, @atomic(summary._sum)), ] ), ) @@ -748,8 +748,9 @@ function collect!(metrics::Vector, family::Family{C}) where C type = prometheus_type(C) samples = Sample[] buf = Metric[] + label_names = family.label_names @lock family.lock begin - for (labels, child) in family.children + for (label_values, child) in family.children # collect!(...) the child, throw away the metric, but keep the samples child_metrics = collect!(resize!(buf, 0), child) length(child_metrics) != 1 && unreachable() # TODO: maybe this should be supported? @@ -758,12 +759,12 @@ function collect!(metrics::Vector, family::Family{C}) where C # Unwrap and rewrap samples with the labels child_samples = child_metric.samples if child_samples isa Sample - push!(samples, Sample(child_samples.suffix, labels, child_samples.value)) + push!(samples, Sample(child_samples.suffix, label_names, label_values, child_samples.value)) else @assert(child_samples isa Vector{Sample}) for child_sample in child_samples @assert(child_sample.label_values === nothing) - push!(samples, Sample(child_sample.suffix, labels, child_sample.value)) + push!(samples, Sample(child_sample.suffix, label_names, label_values, child_sample.value)) end end end @@ -776,7 +777,7 @@ function collect!(metrics::Vector, family::Family{C}) where C end) push!( metrics, - Metric(type, family.metric_name, family.help, family.label_names, samples), + Metric(type, family.metric_name, family.help, samples), ) return metrics end @@ -788,6 +789,7 @@ end struct Sample suffix::Union{String, Nothing} # e.g. _count or _sum + label_names::Union{LabelNames, Nothing} label_values::Union{LabelValues, Nothing} value::Float64 end @@ -796,7 +798,6 @@ struct Metric type::String metric_name::String help::String - label_names::Union{LabelNames, Nothing} # TODO: Union{Tuple{Sample}, Vector{Sample}} would always make this iterable. samples::Union{Sample, Vector{Sample}} end @@ -817,11 +818,10 @@ function expose_metric(io::IO, metric::Metric) print_escaped(io, metric.help, ('\\', '\n')) println(io) println(io, "# TYPE ", metric.metric_name, " ", metric.type) - label_names = metric.label_names samples = metric.samples if samples isa Sample # Single sample, no labels - @assert(label_names === nothing) + @assert(samples.label_names === nothing) @assert(samples.label_values === nothing) @assert(samples.suffix === nothing) val = samples.value @@ -837,11 +837,13 @@ function expose_metric(io::IO, metric::Metric) print(io, sample.suffix) end # Print potential labels - labels = sample.label_values - if label_names !== nothing && labels !== nothing + label_names = sample.label_names + label_values = sample.label_values + @assert((label_names === nothing) === (label_values === nothing)) + if label_names !== nothing && label_values !== nothing first = true print(io, "{") - for (name, value) in zip(label_names.label_names, labels.label_values) + for (name, value) in zip(label_names.label_names, label_values.label_values) first || print(io, ",") print(io, name, "=\"") print_escaped(io, value, ('\\', '\"', '\n')) diff --git a/src/gc_collector.jl b/src/gc_collector.jl index bb95e74..e5a15ab 100644 --- a/src/gc_collector.jl +++ b/src/gc_collector.jl @@ -44,40 +44,42 @@ function collect!(metrics::Vector, ::GCCollector) gc_live_bytes = Base.gc_live_bytes() # Push all the metrics push!(metrics, - Metric( - "counter", "julia_gc_alloc_total", "Total number of allocations (calls to malloc, realloc, etc)", - 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), - ], - ), + let label_names = LabelNames(("type",)) + Metric( + "counter", "julia_gc_alloc_total", "Total number of allocations (calls to malloc, realloc, etc)", + [ + Sample(nothing, label_names, LabelValues(("bigalloc",)), gc_num.bigalloc), + Sample(nothing, label_names, LabelValues(("malloc",)), gc_num.malloc), + Sample(nothing, label_names, LabelValues(("poolalloc",)), gc_num.poolalloc), + Sample(nothing, label_names, LabelValues(("realloc",)), gc_num.realloc), + ], + ) + end, Metric( "counter", "julia_gc_free_total", "Total number of calls to free()", - nothing, Sample(nothing, nothing, gc_num.freecall), - ), - Metric( - "counter", "julia_gc_alloc_bytes_total", "Total number of allocated bytes", nothing, - Sample(nothing, nothing, Base.gc_total_bytes(gc_num)), + Sample(nothing, nothing, nothing, gc_num.freecall), ), Metric( - "gauge", "julia_gc_live_bytes", "Current number of live bytes", nothing, - Sample(nothing, nothing, gc_live_bytes), + "counter", "julia_gc_alloc_bytes_total", "Total number of allocated bytes", + Sample(nothing, nothing, nothing, Base.gc_total_bytes(gc_num)), ), Metric( - "counter", "julia_gc_seconds_total", "Total time spent in garbage collection", nothing, - Sample(nothing, nothing, gc_num.total_time / 10^9), # [ns] to [s] + "gauge", "julia_gc_live_bytes", "Current number of live bytes", + Sample(nothing, nothing, nothing, gc_live_bytes), ), Metric( - "counter", "julia_gc_collections_total", "Total number of calls to garbage collection", - LabelNames(("type",)), - [ - Sample(nothing, LabelValues(("full",)), gc_num.full_sweep), - Sample(nothing, LabelValues(("minor",)), gc_num.pause - gc_num.full_sweep), - ], + "counter", "julia_gc_seconds_total", "Total time spent in garbage collection", + Sample(nothing, nothing, nothing, gc_num.total_time / 10^9), # [ns] to [s] ), + let label_names = LabelNames(("type",)) + Metric( + "counter", "julia_gc_collections_total", "Total number of calls to garbage collection", + [ + Sample(nothing, label_names, LabelValues(("full",)), gc_num.full_sweep), + Sample(nothing, label_names, LabelValues(("minor",)), gc_num.pause - gc_num.full_sweep), + ], + ) + end, ) return metrics end diff --git a/src/process_collector.jl b/src/process_collector.jl index 2717651..8bb19b5 100644 --- a/src/process_collector.jl +++ b/src/process_collector.jl @@ -118,13 +118,13 @@ function collect!(metrics::Vector, procc::ProcessCollector) if procc.clock_ticks_per_second > 0 utime = parse(Int, fields[14 - 2]) / procc.clock_ticks_per_second stime = parse(Int, fields[15 - 2]) / procc.clock_ticks_per_second + label_names = LabelNames(("mode",)) proc_cpu_seconds = Metric( "counter", "process_cpu_seconds_total", "Total CPU time (user and system mode) in seconds.", - LabelNames(("mode",)), [ - Sample(nothing, LabelValues(("system",)), stime), - Sample(nothing, LabelValues(("user",)), utime), + Sample(nothing, label_names, LabelValues(("system",)), stime), + Sample(nothing, label_names, LabelValues(("user",)), utime), ], ) push!(metrics, proc_cpu_seconds) @@ -132,16 +132,16 @@ function collect!(metrics::Vector, procc::ProcessCollector) starttime = parse(Int, fields[22 - 2]) / procc.clock_ticks_per_second proc_start_time = Metric( "gauge", "process_start_time_seconds", - "Start time since unix epoch in seconds.", nothing, - Sample(nothing, nothing, starttime + procc.system_boot_time), + "Start time since unix epoch in seconds.", + Sample(nothing, nothing, nothing, starttime + procc.system_boot_time), ) push!(metrics, proc_start_time) end # Virtual memory vsize = parse(Int, fields[23 - 2]) proc_virtual_memory = Metric( - "gauge", "process_virtual_memory_bytes", "Virtual memory size in bytes.", nothing, - Sample(nothing, nothing, vsize), + "gauge", "process_virtual_memory_bytes", "Virtual memory size in bytes.", + Sample(nothing, nothing, nothing, vsize), ) push!(metrics, proc_virtual_memory) if procc.pagesize > 0 @@ -149,8 +149,8 @@ function collect!(metrics::Vector, procc::ProcessCollector) rss = parse(Int, fields[24 - 2]) proc_resident_memory = Metric( "gauge", "process_resident_memory_bytes", - "Resident memory size (RSS) in bytes.", nothing, - Sample(nothing, nothing, rss * procc.pagesize), + "Resident memory size (RSS) in bytes.", + Sample(nothing, nothing, nothing, rss * procc.pagesize), ) push!(metrics, proc_resident_memory) end @@ -166,8 +166,8 @@ function collect!(metrics::Vector, procc::ProcessCollector) # Open file descriptors proc_open_fds = Metric( "gauge", "process_open_fds", - "Number of open file descriptors.", nothing, - Sample(nothing, nothing, proc_fd), + "Number of open file descriptors.", + Sample(nothing, nothing, nothing, proc_fd), ) push!(metrics, proc_open_fds) # TODO: Maybe add maximum open fds from /proc/$(pid)/limits like the Python client @@ -184,8 +184,8 @@ function collect!(metrics::Vector, procc::ProcessCollector) if rchar !== nothing proc_io_rchar = Metric( "counter", "process_io_rchar_bytes_total", - "Total number of bytes read in bytes (rchar from /proc/[pid]/io).", nothing, - Sample(nothing, nothing, parse(Int, rchar.captures[1]::AbstractString)), + "Total number of bytes read in bytes (rchar from /proc/[pid]/io).", + Sample(nothing, nothing, nothing, parse(Int, rchar.captures[1]::AbstractString)), ) push!(metrics, proc_io_rchar) end @@ -193,8 +193,8 @@ function collect!(metrics::Vector, procc::ProcessCollector) if wchar !== nothing proc_io_wchar = Metric( "counter", "process_io_wchar_bytes_total", - "Total number of bytes written in bytes (wchar from /proc/[pid]/io).", nothing, - Sample(nothing, nothing, parse(Int, wchar.captures[1]::AbstractString)), + "Total number of bytes written in bytes (wchar from /proc/[pid]/io).", + Sample(nothing, nothing, nothing, parse(Int, wchar.captures[1]::AbstractString)), ) push!(metrics, proc_io_wchar) end @@ -202,8 +202,8 @@ function collect!(metrics::Vector, procc::ProcessCollector) if syscr !== nothing proc_io_syscr = Metric( "counter", "process_io_syscr_total", - "Total number of read I/O operations (syscalls) (syscr from /proc/[pid]/io).", nothing, - Sample(nothing, nothing, parse(Int, syscr.captures[1]::AbstractString)), + "Total number of read I/O operations (syscalls) (syscr from /proc/[pid]/io).", + Sample(nothing, nothing, nothing, parse(Int, syscr.captures[1]::AbstractString)), ) push!(metrics, proc_io_syscr) end @@ -211,8 +211,8 @@ function collect!(metrics::Vector, procc::ProcessCollector) if syscw !== nothing proc_io_syscw = Metric( "counter", "process_io_syscw_total", - "Total number of write I/O operations (syscalls) (syscw from /proc/[pid]/io).", nothing, - Sample(nothing, nothing, parse(Int, syscw.captures[1]::AbstractString)), + "Total number of write I/O operations (syscalls) (syscw from /proc/[pid]/io).", + Sample(nothing, nothing, nothing, parse(Int, syscw.captures[1]::AbstractString)), ) push!(metrics, proc_io_syscw) end @@ -220,8 +220,8 @@ function collect!(metrics::Vector, procc::ProcessCollector) if read_bytes !== nothing proc_io_read_bytes = Metric( "counter", "process_io_read_bytes_total", - "Total number of bytes read from the file system (read_bytes from /proc/[pid]/io).", nothing, - Sample(nothing, nothing, parse(Int, read_bytes.captures[1]::AbstractString)), + "Total number of bytes read from the file system (read_bytes from /proc/[pid]/io).", + Sample(nothing, nothing, nothing, parse(Int, read_bytes.captures[1]::AbstractString)), ) push!(metrics, proc_io_read_bytes) end @@ -229,8 +229,8 @@ function collect!(metrics::Vector, procc::ProcessCollector) if write_bytes !== nothing proc_io_write_bytes = Metric( "counter", "process_io_write_bytes_total", - "Total number of bytes written to the file system (write_bytes from /proc/[pid]/io).", nothing, - Sample(nothing, nothing, parse(Int, write_bytes.captures[1]::AbstractString)), + "Total number of bytes written to the file system (write_bytes from /proc/[pid]/io).", + Sample(nothing, nothing, nothing, parse(Int, write_bytes.captures[1]::AbstractString)), ) push!(metrics, proc_io_write_bytes) end