Browse Source

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.
pull/9/head
Fredrik Ekre 2 years ago
parent
commit
e79ec70373
  1. 32
      src/Prometheus.jl
  2. 36
      src/gc_collector.jl
  3. 46
      src/process_collector.jl

32
src/Prometheus.jl

@ -202,7 +202,7 @@ function collect!(metrics::Vector, counter::Counter)
push!(metrics, push!(metrics,
Metric( Metric(
"counter", counter.metric_name, counter.help, "counter", counter.metric_name, counter.help,
nothing, Sample(nothing, nothing, @atomic(counter.value)), Sample(nothing, nothing, nothing, @atomic(counter.value)),
), ),
) )
return metrics return metrics
@ -310,7 +310,7 @@ function collect!(metrics::Vector, gauge::Gauge)
push!(metrics, push!(metrics,
Metric( Metric(
"gauge", gauge.metric_name, gauge.help, "gauge", gauge.metric_name, gauge.help,
nothing, Sample(nothing, nothing, @atomic(gauge.value)), Sample(nothing, nothing, nothing, @atomic(gauge.value)),
), ),
) )
return metrics return metrics
@ -381,10 +381,10 @@ end
function collect!(metrics::Vector, summary::Summary) function collect!(metrics::Vector, summary::Summary)
push!(metrics, push!(metrics,
Metric( Metric(
"summary", summary.metric_name, summary.help, nothing, "summary", summary.metric_name, summary.help,
[ [
Sample("_count", nothing, @atomic(summary._count)), Sample("_count", nothing, nothing, @atomic(summary._count)),
Sample("_sum", nothing, @atomic(summary._sum)), Sample("_sum", nothing, nothing, @atomic(summary._sum)),
] ]
), ),
) )
@ -748,8 +748,9 @@ function collect!(metrics::Vector, family::Family{C}) where C
type = prometheus_type(C) type = prometheus_type(C)
samples = Sample[] samples = Sample[]
buf = Metric[] buf = Metric[]
label_names = family.label_names
@lock family.lock begin @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 # collect!(...) the child, throw away the metric, but keep the samples
child_metrics = collect!(resize!(buf, 0), child) child_metrics = collect!(resize!(buf, 0), child)
length(child_metrics) != 1 && unreachable() # TODO: maybe this should be supported? 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 # Unwrap and rewrap samples with the labels
child_samples = child_metric.samples child_samples = child_metric.samples
if child_samples isa Sample 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 else
@assert(child_samples isa Vector{Sample}) @assert(child_samples isa Vector{Sample})
for child_sample in child_samples for child_sample in child_samples
@assert(child_sample.label_values === nothing) @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 end
end end
@ -776,7 +777,7 @@ function collect!(metrics::Vector, family::Family{C}) where C
end) end)
push!( push!(
metrics, metrics,
Metric(type, family.metric_name, family.help, family.label_names, samples), Metric(type, family.metric_name, family.help, samples),
) )
return metrics return metrics
end end
@ -788,6 +789,7 @@ end
struct Sample struct Sample
suffix::Union{String, Nothing} # e.g. _count or _sum suffix::Union{String, Nothing} # e.g. _count or _sum
label_names::Union{LabelNames, Nothing}
label_values::Union{LabelValues, Nothing} label_values::Union{LabelValues, Nothing}
value::Float64 value::Float64
end end
@ -796,7 +798,6 @@ struct Metric
type::String type::String
metric_name::String metric_name::String
help::String help::String
label_names::Union{LabelNames, Nothing}
# TODO: Union{Tuple{Sample}, Vector{Sample}} would always make this iterable. # TODO: Union{Tuple{Sample}, Vector{Sample}} would always make this iterable.
samples::Union{Sample, Vector{Sample}} samples::Union{Sample, Vector{Sample}}
end end
@ -817,11 +818,10 @@ function expose_metric(io::IO, metric::Metric)
print_escaped(io, metric.help, ('\\', '\n')) print_escaped(io, metric.help, ('\\', '\n'))
println(io) println(io)
println(io, "# TYPE ", metric.metric_name, " ", metric.type) println(io, "# TYPE ", metric.metric_name, " ", metric.type)
label_names = metric.label_names
samples = metric.samples samples = metric.samples
if samples isa Sample if samples isa Sample
# Single sample, no labels # Single sample, no labels
@assert(label_names === nothing) @assert(samples.label_names === nothing)
@assert(samples.label_values === nothing) @assert(samples.label_values === nothing)
@assert(samples.suffix === nothing) @assert(samples.suffix === nothing)
val = samples.value val = samples.value
@ -837,11 +837,13 @@ function expose_metric(io::IO, metric::Metric)
print(io, sample.suffix) print(io, sample.suffix)
end end
# Print potential labels # Print potential labels
labels = sample.label_values label_names = sample.label_names
if label_names !== nothing && labels !== nothing label_values = sample.label_values
@assert((label_names === nothing) === (label_values === nothing))
if label_names !== nothing && label_values !== nothing
first = true first = true
print(io, "{") 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, ",") first || print(io, ",")
print(io, name, "=\"") print(io, name, "=\"")
print_escaped(io, value, ('\\', '\"', '\n')) print_escaped(io, value, ('\\', '\"', '\n'))

36
src/gc_collector.jl

@ -44,40 +44,42 @@ function collect!(metrics::Vector, ::GCCollector)
gc_live_bytes = Base.gc_live_bytes() gc_live_bytes = Base.gc_live_bytes()
# Push all the metrics # Push all the metrics
push!(metrics, push!(metrics,
let label_names = LabelNames(("type",))
Metric( Metric(
"counter", "julia_gc_alloc_total", "Total number of allocations (calls to malloc, realloc, etc)", "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, label_names, LabelValues(("bigalloc",)), gc_num.bigalloc),
Sample(nothing, LabelValues(("malloc",)), gc_num.malloc), Sample(nothing, label_names, LabelValues(("malloc",)), gc_num.malloc),
Sample(nothing, LabelValues(("poolalloc",)), gc_num.poolalloc), Sample(nothing, label_names, LabelValues(("poolalloc",)), gc_num.poolalloc),
Sample(nothing, LabelValues(("realloc",)), gc_num.realloc), Sample(nothing, label_names, LabelValues(("realloc",)), gc_num.realloc),
], ],
), )
end,
Metric( Metric(
"counter", "julia_gc_free_total", "Total number of calls to free()", "counter", "julia_gc_free_total", "Total number of calls to free()",
nothing, Sample(nothing, nothing, gc_num.freecall), Sample(nothing, nothing, nothing, gc_num.freecall),
), ),
Metric( Metric(
"counter", "julia_gc_alloc_bytes_total", "Total number of allocated bytes", nothing, "counter", "julia_gc_alloc_bytes_total", "Total number of allocated bytes",
Sample(nothing, nothing, Base.gc_total_bytes(gc_num)), Sample(nothing, nothing, nothing, Base.gc_total_bytes(gc_num)),
), ),
Metric( Metric(
"gauge", "julia_gc_live_bytes", "Current number of live bytes", nothing, "gauge", "julia_gc_live_bytes", "Current number of live bytes",
Sample(nothing, nothing, gc_live_bytes), Sample(nothing, nothing, nothing, gc_live_bytes),
), ),
Metric( Metric(
"counter", "julia_gc_seconds_total", "Total time spent in garbage collection", nothing, "counter", "julia_gc_seconds_total", "Total time spent in garbage collection",
Sample(nothing, nothing, gc_num.total_time / 10^9), # [ns] to [s] Sample(nothing, nothing, nothing, gc_num.total_time / 10^9), # [ns] to [s]
), ),
let label_names = LabelNames(("type",))
Metric( Metric(
"counter", "julia_gc_collections_total", "Total number of calls to garbage collection", "counter", "julia_gc_collections_total", "Total number of calls to garbage collection",
LabelNames(("type",)),
[ [
Sample(nothing, LabelValues(("full",)), gc_num.full_sweep), Sample(nothing, label_names, LabelValues(("full",)), gc_num.full_sweep),
Sample(nothing, LabelValues(("minor",)), gc_num.pause - gc_num.full_sweep), Sample(nothing, label_names, LabelValues(("minor",)), gc_num.pause - gc_num.full_sweep),
], ],
), )
end,
) )
return metrics return metrics
end end

46
src/process_collector.jl

@ -118,13 +118,13 @@ function collect!(metrics::Vector, procc::ProcessCollector)
if procc.clock_ticks_per_second > 0 if procc.clock_ticks_per_second > 0
utime = parse(Int, fields[14 - 2]) / procc.clock_ticks_per_second utime = parse(Int, fields[14 - 2]) / procc.clock_ticks_per_second
stime = parse(Int, fields[15 - 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( proc_cpu_seconds = Metric(
"counter", "process_cpu_seconds_total", "counter", "process_cpu_seconds_total",
"Total CPU time (user and system mode) in seconds.", "Total CPU time (user and system mode) in seconds.",
LabelNames(("mode",)),
[ [
Sample(nothing, LabelValues(("system",)), stime), Sample(nothing, label_names, LabelValues(("system",)), stime),
Sample(nothing, LabelValues(("user",)), utime), Sample(nothing, label_names, LabelValues(("user",)), utime),
], ],
) )
push!(metrics, proc_cpu_seconds) 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 starttime = parse(Int, fields[22 - 2]) / procc.clock_ticks_per_second
proc_start_time = Metric( proc_start_time = Metric(
"gauge", "process_start_time_seconds", "gauge", "process_start_time_seconds",
"Start time since unix epoch in seconds.", nothing, "Start time since unix epoch in seconds.",
Sample(nothing, nothing, starttime + procc.system_boot_time), Sample(nothing, nothing, nothing, starttime + procc.system_boot_time),
) )
push!(metrics, proc_start_time) push!(metrics, proc_start_time)
end end
# Virtual memory # Virtual memory
vsize = parse(Int, fields[23 - 2]) vsize = parse(Int, fields[23 - 2])
proc_virtual_memory = Metric( proc_virtual_memory = Metric(
"gauge", "process_virtual_memory_bytes", "Virtual memory size in bytes.", nothing, "gauge", "process_virtual_memory_bytes", "Virtual memory size in bytes.",
Sample(nothing, nothing, vsize), Sample(nothing, nothing, nothing, vsize),
) )
push!(metrics, proc_virtual_memory) push!(metrics, proc_virtual_memory)
if procc.pagesize > 0 if procc.pagesize > 0
@ -149,8 +149,8 @@ function collect!(metrics::Vector, procc::ProcessCollector)
rss = parse(Int, fields[24 - 2]) rss = parse(Int, fields[24 - 2])
proc_resident_memory = Metric( proc_resident_memory = Metric(
"gauge", "process_resident_memory_bytes", "gauge", "process_resident_memory_bytes",
"Resident memory size (RSS) in bytes.", nothing, "Resident memory size (RSS) in bytes.",
Sample(nothing, nothing, rss * procc.pagesize), Sample(nothing, nothing, nothing, rss * procc.pagesize),
) )
push!(metrics, proc_resident_memory) push!(metrics, proc_resident_memory)
end end
@ -166,8 +166,8 @@ function collect!(metrics::Vector, procc::ProcessCollector)
# Open file descriptors # Open file descriptors
proc_open_fds = Metric( proc_open_fds = Metric(
"gauge", "process_open_fds", "gauge", "process_open_fds",
"Number of open file descriptors.", nothing, "Number of open file descriptors.",
Sample(nothing, nothing, proc_fd), Sample(nothing, nothing, nothing, proc_fd),
) )
push!(metrics, proc_open_fds) push!(metrics, proc_open_fds)
# TODO: Maybe add maximum open fds from /proc/$(pid)/limits like the Python client # 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 if rchar !== nothing
proc_io_rchar = Metric( proc_io_rchar = Metric(
"counter", "process_io_rchar_bytes_total", "counter", "process_io_rchar_bytes_total",
"Total number of bytes read in bytes (rchar from /proc/[pid]/io).", nothing, "Total number of bytes read in bytes (rchar from /proc/[pid]/io).",
Sample(nothing, nothing, parse(Int, rchar.captures[1]::AbstractString)), Sample(nothing, nothing, nothing, parse(Int, rchar.captures[1]::AbstractString)),
) )
push!(metrics, proc_io_rchar) push!(metrics, proc_io_rchar)
end end
@ -193,8 +193,8 @@ function collect!(metrics::Vector, procc::ProcessCollector)
if wchar !== nothing if wchar !== nothing
proc_io_wchar = Metric( proc_io_wchar = Metric(
"counter", "process_io_wchar_bytes_total", "counter", "process_io_wchar_bytes_total",
"Total number of bytes written in bytes (wchar from /proc/[pid]/io).", nothing, "Total number of bytes written in bytes (wchar from /proc/[pid]/io).",
Sample(nothing, nothing, parse(Int, wchar.captures[1]::AbstractString)), Sample(nothing, nothing, nothing, parse(Int, wchar.captures[1]::AbstractString)),
) )
push!(metrics, proc_io_wchar) push!(metrics, proc_io_wchar)
end end
@ -202,8 +202,8 @@ function collect!(metrics::Vector, procc::ProcessCollector)
if syscr !== nothing if syscr !== nothing
proc_io_syscr = Metric( proc_io_syscr = Metric(
"counter", "process_io_syscr_total", "counter", "process_io_syscr_total",
"Total number of read I/O operations (syscalls) (syscr from /proc/[pid]/io).", nothing, "Total number of read I/O operations (syscalls) (syscr from /proc/[pid]/io).",
Sample(nothing, nothing, parse(Int, syscr.captures[1]::AbstractString)), Sample(nothing, nothing, nothing, parse(Int, syscr.captures[1]::AbstractString)),
) )
push!(metrics, proc_io_syscr) push!(metrics, proc_io_syscr)
end end
@ -211,8 +211,8 @@ function collect!(metrics::Vector, procc::ProcessCollector)
if syscw !== nothing if syscw !== nothing
proc_io_syscw = Metric( proc_io_syscw = Metric(
"counter", "process_io_syscw_total", "counter", "process_io_syscw_total",
"Total number of write I/O operations (syscalls) (syscw from /proc/[pid]/io).", nothing, "Total number of write I/O operations (syscalls) (syscw from /proc/[pid]/io).",
Sample(nothing, nothing, parse(Int, syscw.captures[1]::AbstractString)), Sample(nothing, nothing, nothing, parse(Int, syscw.captures[1]::AbstractString)),
) )
push!(metrics, proc_io_syscw) push!(metrics, proc_io_syscw)
end end
@ -220,8 +220,8 @@ function collect!(metrics::Vector, procc::ProcessCollector)
if read_bytes !== nothing if read_bytes !== nothing
proc_io_read_bytes = Metric( proc_io_read_bytes = Metric(
"counter", "process_io_read_bytes_total", "counter", "process_io_read_bytes_total",
"Total number of bytes read from the file system (read_bytes from /proc/[pid]/io).", nothing, "Total number of bytes read from the file system (read_bytes from /proc/[pid]/io).",
Sample(nothing, nothing, parse(Int, read_bytes.captures[1]::AbstractString)), Sample(nothing, nothing, nothing, parse(Int, read_bytes.captures[1]::AbstractString)),
) )
push!(metrics, proc_io_read_bytes) push!(metrics, proc_io_read_bytes)
end end
@ -229,8 +229,8 @@ function collect!(metrics::Vector, procc::ProcessCollector)
if write_bytes !== nothing if write_bytes !== nothing
proc_io_write_bytes = Metric( proc_io_write_bytes = Metric(
"counter", "process_io_write_bytes_total", "counter", "process_io_write_bytes_total",
"Total number of bytes written to the file system (write_bytes from /proc/[pid]/io).", nothing, "Total number of bytes written to the file system (write_bytes from /proc/[pid]/io).",
Sample(nothing, nothing, parse(Int, write_bytes.captures[1]::AbstractString)), Sample(nothing, nothing, nothing, parse(Int, write_bytes.captures[1]::AbstractString)),
) )
push!(metrics, proc_io_write_bytes) push!(metrics, proc_io_write_bytes)
end end

Loading…
Cancel
Save