Browse Source

Runic formatter (#20)

pull/21/head
Fredrik Ekre 1 year ago committed by GitHub
parent
commit
4d033e8d33
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 0
      .git-blame-ignore-revs
  2. 21
      .github/workflows/Check.yml
  3. 1
      docs/liveserver.jl
  4. 171
      src/Prometheus.jl
  5. 5
      src/gc_collector.jl
  6. 14
      src/process_collector.jl
  7. 206
      test/runtests.jl

0
.git-blame-ignore-revs

21
.github/workflows/Check.yml

@ -0,0 +1,21 @@
---
name: Check
on:
push:
branches:
- 'master'
- 'release-'
tags:
- '*'
pull_request:
jobs:
runic:
name: Runic formatting
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# - uses: julia-actions/setup-julia@v2
# with:
# version: '1.11'
- uses: julia-actions/cache@v2
- uses: fredrikekre/runic-action@v1

1
docs/liveserver.jl

@ -22,4 +22,3 @@ LiveServer.servedocs(;
joinpath(repo_root, "src"), joinpath(repo_root, "src"),
], ],
) )

171
src/Prometheus.jl

@ -7,14 +7,15 @@ using HTTP: HTTP
using SimpleBufferStream: BufferStream using SimpleBufferStream: BufferStream
if VERSION >= v"1.11.0-DEV.469" if VERSION >= v"1.11.0-DEV.469"
eval(Meta.parse(""" let str = """
public CollectorRegistry, register, unregister, public CollectorRegistry, register, unregister,
Counter, Gauge, Histogram, Summary, GCCollector, ProcessCollector, Counter, Gauge, Histogram, Summary, GCCollector, ProcessCollector,
inc, dec, set, set_to_current_time, observe, @inprogress, @time, inc, dec, set, set_to_current_time, observe, @inprogress, @time,
Family, labels, remove, clear, Family, labels, remove, clear,
expose expose
""" """
)) eval(Meta.parse(str))
end
end end
abstract type Collector end abstract type Collector end
@ -30,6 +31,7 @@ struct ArgumentError <: PrometheusException
end end
function Base.showerror(io::IO, err::ArgumentError) function Base.showerror(io::IO, err::ArgumentError)
print(io, "Prometheus.", nameof(typeof(err)), ": ", err.msg) print(io, "Prometheus.", nameof(typeof(err)), ": ", err.msg)
return
end end
struct AssertionError <: PrometheusException struct AssertionError <: PrometheusException
@ -44,8 +46,9 @@ function Base.showerror(io::IO, err::AssertionError)
print( print(
io, io,
"Prometheus.AssertionError: `", err.msg, "`. This is unexpected, please file an " * "Prometheus.AssertionError: `", err.msg, "`. This is unexpected, please file an " *
"issue at https://github.com/fredrikekre/Prometheus.jl/issues/new.", "issue at https://github.com/fredrikekre/Prometheus.jl/issues/new.",
) )
return
end end
# https://prometheus.io/docs/concepts/data_model/#metric-names-and-labels # https://prometheus.io/docs/concepts/data_model/#metric-names-and-labels
@ -115,9 +118,7 @@ function register(reg::CollectorRegistry, collector::Collector)
end end
for metric_name in metric_names(collector) for metric_name in metric_names(collector)
if metric_name in existing_names if metric_name in existing_names
throw(ArgumentError( throw(ArgumentError("collector already contains a metric with the name \"$(metric_name)\""))
"collector already contains a metric with the name \"$(metric_name)\""
))
end end
end end
push!(reg.collectors, collector) push!(reg.collectors, collector)
@ -156,7 +157,7 @@ mutable struct Counter <: Collector
function Counter( function Counter(
metric_name::String, help::String; metric_name::String, help::String;
registry::Union{CollectorRegistry, Nothing}=DEFAULT_REGISTRY, registry::Union{CollectorRegistry, Nothing} = DEFAULT_REGISTRY,
) )
initial_value = 0.0 initial_value = 0.0
counter = new(verify_metric_name(metric_name), help, initial_value) counter = new(verify_metric_name(metric_name), help, initial_value)
@ -187,7 +188,7 @@ Construct a Counter collector.
Counter(::String, ::String; kwargs...) Counter(::String, ::String; kwargs...)
function metric_names(counter::Counter) function metric_names(counter::Counter)
return (counter.metric_name, ) return (counter.metric_name,)
end end
""" """
@ -199,21 +200,18 @@ Throw a `Prometheus.ArgumentError` if `v < 0` (a counter must not decrease).
""" """
function inc(counter::Counter, v::Real = 1.0) function inc(counter::Counter, v::Real = 1.0)
if v < 0 if v < 0
throw(ArgumentError( throw(ArgumentError("invalid value $v: a counter must not decrease"))
"invalid value $v: a counter must not decrease"
))
end end
@atomic counter.value += convert(Float64, v) @atomic counter.value += convert(Float64, v)
return nothing return nothing
end end
function collect!(metrics::Vector, counter::Counter) function collect!(metrics::Vector, counter::Counter)
push!(metrics, metric = Metric(
Metric( "counter", counter.metric_name, counter.help,
"counter", counter.metric_name, counter.help, Sample(nothing, nothing, nothing, @atomic(counter.value))
Sample(nothing, nothing, nothing, @atomic(counter.value)),
),
) )
push!(metrics, metric)
return metrics return metrics
end end
@ -230,7 +228,7 @@ mutable struct Gauge <: Collector
function Gauge( function Gauge(
metric_name::String, help::String; metric_name::String, help::String;
registry::Union{CollectorRegistry, Nothing}=DEFAULT_REGISTRY, registry::Union{CollectorRegistry, Nothing} = DEFAULT_REGISTRY,
) )
initial_value = 0.0 initial_value = 0.0
gauge = new(verify_metric_name(metric_name), help, initial_value) gauge = new(verify_metric_name(metric_name), help, initial_value)
@ -270,7 +268,7 @@ Construct a Gauge collector.
Gauge(::String, ::String; kwargs...) Gauge(::String, ::String; kwargs...)
function metric_names(gauge::Gauge) function metric_names(gauge::Gauge)
return (gauge.metric_name, ) return (gauge.metric_name,)
end end
""" """
@ -316,12 +314,11 @@ function set_to_current_time(gauge::Gauge)
end end
function collect!(metrics::Vector, gauge::Gauge) function collect!(metrics::Vector, gauge::Gauge)
push!(metrics, metric = Metric(
Metric( "gauge", gauge.metric_name, gauge.help,
"gauge", gauge.metric_name, gauge.help, Sample(nothing, nothing, nothing, @atomic(gauge.value)),
Sample(nothing, nothing, nothing, @atomic(gauge.value)),
),
) )
push!(metrics, metric)
return metrics return metrics
end end
@ -334,7 +331,7 @@ end
# A histogram SHOULD have the same default buckets as other client libraries. # A histogram SHOULD have the same default buckets as other client libraries.
# https://github.com/prometheus/client_python/blob/d8306b7b39ed814f3ec667a7901df249cee8a956/prometheus_client/metrics.py#L565 # https://github.com/prometheus/client_python/blob/d8306b7b39ed814f3ec667a7901df249cee8a956/prometheus_client/metrics.py#L565
const DEFAULT_BUCKETS = [ const DEFAULT_BUCKETS = [
.005, .01, .025, .05, .075, .1, .25, .5, .75, 1.0, 2.5, 5.0, 7.5, 10.0, Inf, 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1.0, 2.5, 5.0, 7.5, 10.0, Inf,
] ]
mutable struct Histogram <: Collector mutable struct Histogram <: Collector
@ -346,8 +343,8 @@ mutable struct Histogram <: Collector
@const bucket_counters::Vector{Threads.Atomic{Int}} @const bucket_counters::Vector{Threads.Atomic{Int}}
function Histogram( function Histogram(
metric_name::String, help::String; buckets::Vector{Float64}=DEFAULT_BUCKETS, metric_name::String, help::String; buckets::Vector{Float64} = DEFAULT_BUCKETS,
registry::Union{CollectorRegistry, Nothing}=DEFAULT_REGISTRY, registry::Union{CollectorRegistry, Nothing} = DEFAULT_REGISTRY,
) )
# Make a copy of and verify buckets # Make a copy of and verify buckets
buckets = copy(buckets) buckets = copy(buckets)
@ -420,22 +417,18 @@ end
function collect!(metrics::Vector, histogram::Histogram) function collect!(metrics::Vector, histogram::Histogram)
label_names = LabelNames(("le",)) label_names = LabelNames(("le",))
push!(metrics, samples = Vector{Sample}(undef, 2 + length(histogram.buckets))
Metric( samples[1] = Sample("_count", nothing, nothing, @atomic(histogram._count))
"histogram", histogram.metric_name, histogram.help, samples[2] = Sample("_sum", nothing, nothing, @atomic(histogram._sum))
[ for i in 1:length(histogram.buckets)
Sample("_count", nothing, nothing, @atomic(histogram._count)), sample = Sample(
Sample("_sum", nothing, nothing, @atomic(histogram._sum)), nothing, label_names, make_label_values(label_names, (histogram.buckets[i],)),
( histogram.bucket_counters[i][],
Sample( )
nothing, label_names, samples[2 + i] = sample
make_label_values(label_names, (histogram.buckets[i],)), end
histogram.bucket_counters[i][], metric = Metric("histogram", histogram.metric_name, histogram.help, samples)
) for i in 1:length(histogram.buckets) push!(metrics, metric)
)...,
]
),
)
return metrics return metrics
end end
@ -453,7 +446,7 @@ mutable struct Summary <: Collector
function Summary( function Summary(
metric_name::String, help::String; metric_name::String, help::String;
registry::Union{CollectorRegistry, Nothing}=DEFAULT_REGISTRY, registry::Union{CollectorRegistry, Nothing} = DEFAULT_REGISTRY,
) )
initial_count = 0 initial_count = 0
initial_sum = 0.0 initial_sum = 0.0
@ -503,15 +496,14 @@ function observe(summary::Summary, v::Real)
end end
function collect!(metrics::Vector, summary::Summary) function collect!(metrics::Vector, summary::Summary)
push!(metrics, metric = Metric(
Metric( "summary", summary.metric_name, summary.help,
"summary", summary.metric_name, summary.help, [
[ Sample("_count", nothing, nothing, @atomic(summary._count)),
Sample("_count", nothing, nothing, @atomic(summary._count)), Sample("_sum", nothing, nothing, @atomic(summary._sum)),
Sample("_sum", nothing, nothing, @atomic(summary._sum)), ]
]
),
) )
push!(metrics, metric)
return metrics return metrics
end end
@ -600,7 +592,7 @@ function expr_gen(macroname, collector, code)
] ]
postamble = Expr[ postamble = Expr[
Expr(:(=), val, Expr(:call, max, Expr(:call, -, Expr(:call, time), t0), 0.0)), Expr(:(=), val, Expr(:call, max, Expr(:call, -, Expr(:call, time), t0), 0.0)),
Expr(:call, at_time, cllctr, val) Expr(:call, at_time, cllctr, val),
] ]
elseif macroname === :inprogress elseif macroname === :inprogress
local cllctr local cllctr
@ -610,7 +602,7 @@ function expr_gen(macroname, collector, code)
Expr(:call, at_inprogress_enter, cllctr), Expr(:call, at_inprogress_enter, cllctr),
] ]
postamble = Expr[ postamble = Expr[
Expr(:call, at_inprogress_exit, cllctr) Expr(:call, at_inprogress_exit, cllctr),
] ]
else else
throw(ArgumentError("unknown macro name $(repr(macroname))")) throw(ArgumentError("unknown macro name $(repr(macroname))"))
@ -630,7 +622,7 @@ function expr_gen(macroname, collector, code)
Expr( Expr(
:tryfinally, :tryfinally,
Expr(:(=), ret, fbody), Expr(:(=), ret, fbody),
Expr(:block, postamble...,), Expr(:block, postamble...),
), ),
ret, ret,
), ),
@ -642,7 +634,7 @@ function expr_gen(macroname, collector, code)
Expr( Expr(
:tryfinally, :tryfinally,
Expr(:(=), ret, esc(code)), Expr(:(=), ret, esc(code)),
Expr(:block, postamble...,), Expr(:block, postamble...),
), ),
ret, ret,
) )
@ -668,7 +660,7 @@ end
struct LabelNames{N} struct LabelNames{N}
label_names::NTuple{N, Symbol} label_names::NTuple{N, Symbol}
function LabelNames(label_names::NTuple{N, Symbol}) where N function LabelNames(label_names::NTuple{N, Symbol}) where {N}
for label_name in label_names for label_name in label_names
verify_label_name(String(label_name)) verify_label_name(String(label_name))
end end
@ -677,12 +669,12 @@ struct LabelNames{N}
end end
# Tuple of strings # Tuple of strings
function LabelNames(label_names::NTuple{N, String}) where N function LabelNames(label_names::NTuple{N, String}) where {N}
return LabelNames(map(Symbol, label_names)) return LabelNames(map(Symbol, label_names))
end end
# NamedTuple-type or a (user defined) struct # NamedTuple-type or a (user defined) struct
function LabelNames(::Type{T}) where T function LabelNames(::Type{T}) where {T}
return LabelNames(fieldnames(T)) return LabelNames(fieldnames(T))
end end
@ -690,7 +682,7 @@ struct LabelValues{N}
label_values::NTuple{N, String} label_values::NTuple{N, String}
end end
function make_label_values(::LabelNames{N}, label_values::NTuple{N, String}) where N function make_label_values(::LabelNames{N}, label_values::NTuple{N, String}) where {N}
return LabelValues(label_values) return LabelValues(label_values)
end end
@ -698,12 +690,12 @@ stringify(str::String) = str
stringify(str) = String(string(str))::String stringify(str) = String(string(str))::String
# Heterogeneous tuple # Heterogeneous tuple
function make_label_values(::LabelNames{N}, label_values::Tuple{Vararg{Any, N}}) where N function make_label_values(::LabelNames{N}, label_values::Tuple{Vararg{Any, N}}) where {N}
return LabelValues(map(stringify, label_values)::NTuple{N, String}) return LabelValues(map(stringify, label_values)::NTuple{N, String})
end end
# NamedTuple or a (user defined) struct # NamedTuple or a (user defined) struct
function make_label_values(label_names::LabelNames{N}, label_values) where N function make_label_values(label_names::LabelNames{N}, label_values) where {N}
t::NTuple{N, String} = ntuple(N) do i t::NTuple{N, String} = ntuple(N) do i
stringify(getfield(label_values, label_names.label_names[i]))::String stringify(getfield(label_values, label_names.label_names[i]))::String
end end
@ -732,10 +724,10 @@ struct Family{C, N, F} <: Collector
function Family{C}( function Family{C}(
metric_name::String, help::String, args_first, args_tail...; metric_name::String, help::String, args_first, args_tail...;
registry::Union{CollectorRegistry, Nothing}=DEFAULT_REGISTRY, kwargs..., registry::Union{CollectorRegistry, Nothing} = DEFAULT_REGISTRY, kwargs...,
) where {C} ) where {C}
# Support ... on non-final argument # Support ... on non-final argument
args_all = (args_first, args_tail...,) args_all = (args_first, args_tail...)
label_names = last(args_all) label_names = last(args_all)
args = Base.front(args_all) args = Base.front(args_all)
@assert(isempty(args)) @assert(isempty(args))
@ -743,7 +735,7 @@ struct Family{C, N, F} <: Collector
# make_constructor(::Type{Collector}, metric_name, help, args...; kwargs...) # make_constructor(::Type{Collector}, metric_name, help, args...; kwargs...)
# so that some Collectors (like Counter) can skip the closure over args and kwargs. # so that some Collectors (like Counter) can skip the closure over args and kwargs.
function constructor() function constructor()
return C(metric_name, help, args...; kwargs..., registry=nothing)::C return C(metric_name, help, args...; kwargs..., registry = nothing)::C
end end
labels = LabelNames(label_names) labels = LabelNames(label_names)
N = length(labels.label_names) N = length(labels.label_names)
@ -810,10 +802,10 @@ counter_family = Prometheus.Family{Counter}(
Prometheus.inc(Prometheus.labels(counter_family, (target="/api", status_code=200))) Prometheus.inc(Prometheus.labels(counter_family, (target="/api", status_code=200)))
``` ```
""" """
Family{C}(::String, ::String, ::Any; kwargs...) where C Family{C}(::String, ::String, ::Any; kwargs...) where {C}
function metric_names(family::Family) function metric_names(family::Family)
return (family.metric_name, ) return (family.metric_name,)
end end
""" """
@ -870,7 +862,7 @@ Refer to [`Prometheus.labels`](@ref) for how to specify `label_values`.
!!! note !!! note
This method invalidates cached collectors for the label names. This method invalidates cached collectors for the label names.
""" """
function remove(family::Family{<:Any, N}, label_values) where N function remove(family::Family{<:Any, N}, label_values) where {N}
labels = make_label_values(family.label_names, label_values)::LabelValues{N} labels = make_label_values(family.label_names, label_values)::LabelValues{N}
@lock family.lock delete!(family.children, labels) @lock family.lock delete!(family.children, labels)
return return
@ -895,7 +887,7 @@ prometheus_type(::Type{Gauge}) = "gauge"
prometheus_type(::Type{Histogram}) = "histogram" prometheus_type(::Type{Histogram}) = "histogram"
prometheus_type(::Type{Summary}) = "summary" prometheus_type(::Type{Summary}) = "summary"
function collect!(metrics::Vector, family::Family{C}) where C 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[]
@ -919,22 +911,16 @@ function collect!(metrics::Vector, family::Family{C}) where C
# collectors for now. # collectors for now.
@assert( @assert(
length(child_sample.label_names.label_names) == length(child_sample.label_names.label_names) ==
length(child_sample.label_values.label_values) length(child_sample.label_values.label_values)
) )
# TODO: Bypass constructor verifications # TODO: Bypass constructor verifications
merged_names = LabelNames(( merged_names = LabelNames((label_names.label_names..., child_sample.label_names.label_names...))
label_names.label_names..., merged_values = LabelValues((label_values.label_values..., child_sample.label_values.label_values...))
child_sample.label_names.label_names...,
))
merged_values = LabelValues((
label_values.label_values...,
child_sample.label_values.label_values...,
))
push!(samples, Sample(child_sample.suffix, merged_names, merged_values, child_sample.value)) push!(samples, Sample(child_sample.suffix, merged_names, merged_values, child_sample.value))
else else
@assert( @assert(
(child_sample.label_names === nothing) === (child_sample.label_names === nothing) ===
(child_sample.label_values === nothing) (child_sample.label_values === nothing)
) )
push!(samples, Sample(child_sample.suffix, label_names, label_values, child_sample.value)) push!(samples, Sample(child_sample.suffix, label_names, label_values, child_sample.value))
end end
@ -943,11 +929,13 @@ function collect!(metrics::Vector, family::Family{C}) where C
end end
end end
# Sort samples lexicographically by the labels # Sort samples lexicographically by the labels
sort!(samples; by = function(x) sort!(
labels = x.label_values samples; by = function(x)
@assert(labels !== nothing) labels = x.label_values
return labels.label_values @assert(labels !== nothing)
end) return labels.label_values
end
)
push!( push!(
metrics, metrics,
Metric(type, family.metric_name, family.help, samples), Metric(type, family.metric_name, family.help, samples),
@ -970,7 +958,7 @@ struct Sample
label_names::Union{Nothing, LabelNames{N}}, label_names::Union{Nothing, LabelNames{N}},
label_values::Union{Nothing, LabelValues{N}}, label_values::Union{Nothing, LabelValues{N}},
value::Real, value::Real,
) where N ) where {N}
@assert((label_names === nothing) === (label_values === nothing)) @assert((label_names === nothing) === (label_values === nothing))
return new(suffix, label_names, label_values, value) return new(suffix, label_names, label_values, value)
end end
@ -1038,6 +1026,7 @@ function expose_metric(io::IO, metric::Metric)
println(io, " ", isinteger(sample.value) ? Int(sample.value) : sample.value) println(io, " ", isinteger(sample.value) ? Int(sample.value) : sample.value)
end end
end end
return
end end
""" """
@ -1051,7 +1040,7 @@ function expose(path::String, reg::CollectorRegistry = DEFAULT_REGISTRY)
mktemp(dirname(path)) do tmp_path, tmp_io mktemp(dirname(path)) do tmp_path, tmp_io
expose_io(tmp_io, reg) expose_io(tmp_io, reg)
close(tmp_io) close(tmp_io)
mv(tmp_path, path; force=true) mv(tmp_path, path; force = true)
end end
return return
end end
@ -1075,7 +1064,7 @@ function expose_io(io::IO, reg::CollectorRegistry)
end end
sort!(metrics; by = metric -> metric.metric_name) sort!(metrics; by = metric -> metric.metric_name)
# Write to IO # Write to IO
buf = IOBuffer(; maxsize=1024^2) # 1 MB buf = IOBuffer(; maxsize = 1024^2) # 1 MB
for metric in metrics for metric in metrics
truncate(buf, 0) truncate(buf, 0)
expose_metric(buf, metric) expose_metric(buf, metric)
@ -1109,7 +1098,7 @@ Export all metrics in `reg` by writing them to the HTTP stream `http`.
The caller is responsible for checking e.g. the HTTP method and URI target. For The caller is responsible for checking e.g. the HTTP method and URI target. For
HEAD requests this method do not write a body, however. HEAD requests this method do not write a body, however.
""" """
function expose(http::HTTP.Stream, reg::CollectorRegistry = DEFAULT_REGISTRY; compress::Bool=true) function expose(http::HTTP.Stream, reg::CollectorRegistry = DEFAULT_REGISTRY; compress::Bool = true)
# TODO: Handle Accept request header for different formats? # TODO: Handle Accept request header for different formats?
# Compress by default if client supports it and user haven't disabled it # Compress by default if client supports it and user haven't disabled it
if compress if compress
@ -1149,7 +1138,7 @@ include("process_collector.jl")
# Default registry and collectors # Default registry and collectors
const DEFAULT_REGISTRY = CollectorRegistry() const DEFAULT_REGISTRY = CollectorRegistry()
const GC_COLLECTOR = GCCollector(; registry=DEFAULT_REGISTRY) const GC_COLLECTOR = GCCollector(; registry = DEFAULT_REGISTRY)
const PROCESS_COLLECTOR = ProcessCollector(; registry=DEFAULT_REGISTRY) const PROCESS_COLLECTOR = ProcessCollector(; registry = DEFAULT_REGISTRY)
end # module Prometheus end # module Prometheus

5
src/gc_collector.jl

@ -5,7 +5,7 @@
############################ ############################
mutable struct GCCollector <: Collector mutable struct GCCollector <: Collector
function GCCollector(; registry::Union{CollectorRegistry, Nothing}=DEFAULT_REGISTRY) function GCCollector(; registry::Union{CollectorRegistry, Nothing} = DEFAULT_REGISTRY)
gcc = new() gcc = new()
if registry !== nothing if registry !== nothing
register(registry, gcc) register(registry, gcc)
@ -45,7 +45,8 @@ function collect!(metrics::Vector, ::GCCollector)
gc_num = Base.gc_num() gc_num = Base.gc_num()
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",)) 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)",

14
src/process_collector.jl

@ -12,7 +12,7 @@ mutable struct ProcessCollector <: Collector
@atomic pagesize::Int @atomic pagesize::Int
function ProcessCollector( function ProcessCollector(
pid::Function = () -> "self"; pid::Function = () -> "self";
registry::Union{CollectorRegistry, Nothing}=DEFAULT_REGISTRY, registry::Union{CollectorRegistry, Nothing} = DEFAULT_REGISTRY,
) )
procc = new(pid, C_NULL, 0, 0, 0) procc = new(pid, C_NULL, 0, 0, 0)
if registry !== nothing if registry !== nothing
@ -45,25 +45,25 @@ function initialize_process_collector(procc::ProcessCollector)
# Fetch clock ticks per second # Fetch clock ticks per second
clock_ticks_per_second = 0 clock_ticks_per_second = 0
try try
cmd = pipeline(`getconf CLK_TCK`, stderr=devnull) cmd = pipeline(`getconf CLK_TCK`, stderr = devnull)
str = read(cmd, String) str = read(cmd, String)
clock_ticks_per_second = parse(Int, strip(str)) clock_ticks_per_second = parse(Int, strip(str))
catch e catch e
if system_boot_time > 0 if system_boot_time > 0
@debug "ProcessCollector: /proc is available but could not read " * @debug "ProcessCollector: /proc is available but could not read " *
"CLK_TCK from getconf, partially disabling." e "CLK_TCK from getconf, partially disabling." e
end end
end end
# Fetch pagesize # Fetch pagesize
pagesize = 0 pagesize = 0
try try
cmd = pipeline(`getconf PAGESIZE`, stderr=devnull) cmd = pipeline(`getconf PAGESIZE`, stderr = devnull)
str = read(cmd, String) str = read(cmd, String)
pagesize = parse(Int, strip(str)) pagesize = parse(Int, strip(str))
catch e catch e
if system_boot_time > 0 if system_boot_time > 0
@debug "ProcessCollector: /proc is available but could not read " * @debug "ProcessCollector: /proc is available but could not read " *
"PAGESIZE from getconf, partially disabling." e "PAGESIZE from getconf, partially disabling." e
end end
end end
# Set the values and return # Set the values and return
@ -108,7 +108,7 @@ function metric_names(::ProcessCollector)
"process_virtual_memory_bytes", "process_resident_memory_bytes", "process_open_fds", "process_virtual_memory_bytes", "process_resident_memory_bytes", "process_open_fds",
"process_io_rchar_bytes_total", "process_io_wchar_bytes_total", "process_io_rchar_bytes_total", "process_io_wchar_bytes_total",
"process_io_syscr_total", "process_io_syscw_total", "process_io_read_bytes_total", "process_io_syscr_total", "process_io_syscw_total", "process_io_read_bytes_total",
"process_io_write_bytes_total" "process_io_write_bytes_total",
) )
end end
@ -124,7 +124,7 @@ function collect!(metrics::Vector, procc::ProcessCollector)
procc.system_boot_time == 0 && return metrics procc.system_boot_time == 0 && return metrics
# Fetch the pid # Fetch the pid
pid = try pid = try
String(strip(string(procc.pid()::Union{AbstractString,Integer})))::String String(strip(string(procc.pid()::Union{AbstractString, Integer})))::String
catch e catch e
@error "ProcessCollector: could not look up the pid from the lambda" e @error "ProcessCollector: could not look up the pid from the lambda" e
return metrics return metrics

206
test/runtests.jl

@ -19,11 +19,11 @@ using Test: @test, @test_logs, @test_throws, @testset
@test c2 in Prometheus.DEFAULT_REGISTRY.collectors @test c2 in Prometheus.DEFAULT_REGISTRY.collectors
# Provided registry # Provided registry
r = Prometheus.CollectorRegistry() r = Prometheus.CollectorRegistry()
c = Prometheus.Counter("metric_name_counter", "A counter."; registry=r) c = Prometheus.Counter("metric_name_counter", "A counter."; registry = r)
@test c in r.collectors @test c in r.collectors
@test !(c in Prometheus.DEFAULT_REGISTRY.collectors) @test !(c in Prometheus.DEFAULT_REGISTRY.collectors)
# No registry on construction, register after # No registry on construction, register after
c = Prometheus.Counter("metric_name_counter", "A counter."; registry=nothing) c = Prometheus.Counter("metric_name_counter", "A counter."; registry = nothing)
@test !(c in Prometheus.DEFAULT_REGISTRY.collectors) @test !(c in Prometheus.DEFAULT_REGISTRY.collectors)
r = Prometheus.CollectorRegistry() r = Prometheus.CollectorRegistry()
Prometheus.register(r, c) Prometheus.register(r, c)
@ -40,7 +40,7 @@ end
c = Prometheus.Counter("metric_name_counter", "A counter.") c = Prometheus.Counter("metric_name_counter", "A counter.")
@test c in Prometheus.DEFAULT_REGISTRY.collectors @test c in Prometheus.DEFAULT_REGISTRY.collectors
r = Prometheus.CollectorRegistry() r = Prometheus.CollectorRegistry()
c = Prometheus.Counter("metric_name_counter", "A counter."; registry=r) c = Prometheus.Counter("metric_name_counter", "A counter."; registry = r)
@test c in r.collectors @test c in r.collectors
@test c.value == 0 @test c.value == 0
@test_throws( @test_throws(
@ -64,12 +64,12 @@ end
@test metric.samples.value == c.value @test metric.samples.value == c.value
# Prometheus.expose_metric(...) # Prometheus.expose_metric(...)
@test sprint(Prometheus.expose_metric, metric) == @test sprint(Prometheus.expose_metric, metric) ==
sprint(Prometheus.expose_io, r) == sprint(Prometheus.expose_io, r) ==
""" """
# HELP metric_name_counter A counter. # HELP metric_name_counter A counter.
# TYPE metric_name_counter counter # TYPE metric_name_counter counter
metric_name_counter 3 metric_name_counter 3
""" """
end end
@testset "Prometheus.Gauge" begin @testset "Prometheus.Gauge" begin
@ -78,7 +78,7 @@ end
c = Prometheus.Gauge("metric_name_gauge", "A gauge.") c = Prometheus.Gauge("metric_name_gauge", "A gauge.")
@test c in Prometheus.DEFAULT_REGISTRY.collectors @test c in Prometheus.DEFAULT_REGISTRY.collectors
r = Prometheus.CollectorRegistry() r = Prometheus.CollectorRegistry()
c = Prometheus.Gauge("metric_name_gauge", "A gauge."; registry=r) c = Prometheus.Gauge("metric_name_gauge", "A gauge."; registry = r)
@test c in r.collectors @test c in r.collectors
@test c.value == 0 @test c.value == 0
@test_throws( @test_throws(
@ -115,12 +115,12 @@ end
@test metric.samples.value == c.value @test metric.samples.value == c.value
# Prometheus.expose_metric(...) # Prometheus.expose_metric(...)
@test sprint(Prometheus.expose_metric, metric) == @test sprint(Prometheus.expose_metric, metric) ==
sprint(Prometheus.expose_io, r) == sprint(Prometheus.expose_io, r) ==
""" """
# HELP metric_name_gauge A gauge. # HELP metric_name_gauge A gauge.
# TYPE metric_name_gauge gauge # TYPE metric_name_gauge gauge
metric_name_gauge 42 metric_name_gauge 42
""" """
end end
@testset "Prometheus.Summary" begin @testset "Prometheus.Summary" begin
@ -129,7 +129,7 @@ end
c = Prometheus.Summary("metric_name_summary", "A summary.") c = Prometheus.Summary("metric_name_summary", "A summary.")
@test c in Prometheus.DEFAULT_REGISTRY.collectors @test c in Prometheus.DEFAULT_REGISTRY.collectors
r = Prometheus.CollectorRegistry() r = Prometheus.CollectorRegistry()
c = Prometheus.Summary("metric_name_summary", "A summary."; registry=r) c = Prometheus.Summary("metric_name_summary", "A summary."; registry = r)
@test c in r.collectors @test c in r.collectors
@test c._count == 0 @test c._count == 0
@test c._sum == 0 @test c._sum == 0
@ -160,13 +160,13 @@ end
@test s2.value == 11 @test s2.value == 11
# Prometheus.expose_metric(...) # Prometheus.expose_metric(...)
@test sprint(Prometheus.expose_metric, metric) == @test sprint(Prometheus.expose_metric, metric) ==
sprint(Prometheus.expose_io, r) == sprint(Prometheus.expose_io, r) ==
""" """
# HELP metric_name_summary A summary. # HELP metric_name_summary A summary.
# TYPE metric_name_summary summary # TYPE metric_name_summary summary
metric_name_summary_count 2 metric_name_summary_count 2
metric_name_summary_sum 11 metric_name_summary_sum 11
""" """
end end
@testset "Prometheus.Histogram" begin @testset "Prometheus.Histogram" begin
@ -175,7 +175,7 @@ end
c = Prometheus.Histogram("metric_name_histogram", "A histogram.") c = Prometheus.Histogram("metric_name_histogram", "A histogram.")
@test c in Prometheus.DEFAULT_REGISTRY.collectors @test c in Prometheus.DEFAULT_REGISTRY.collectors
r = Prometheus.CollectorRegistry() r = Prometheus.CollectorRegistry()
c = Prometheus.Histogram("metric_name_histogram", "A histogram."; registry=r) c = Prometheus.Histogram("metric_name_histogram", "A histogram."; registry = r)
@test c in r.collectors @test c in r.collectors
@test c.buckets == Prometheus.DEFAULT_BUCKETS @test c.buckets == Prometheus.DEFAULT_BUCKETS
@test c._count == 0 @test c._count == 0
@ -203,7 +203,7 @@ end
# Prometheus.collect(...) # Prometheus.collect(...)
r = Prometheus.CollectorRegistry() r = Prometheus.CollectorRegistry()
buckets = [1.0, 2.0, Inf] buckets = [1.0, 2.0, Inf]
c = Prometheus.Histogram("metric_name_histogram", "A histogram."; buckets=buckets, registry=r) c = Prometheus.Histogram("metric_name_histogram", "A histogram."; buckets = buckets, registry = r)
Prometheus.observe(c, 0.5) Prometheus.observe(c, 0.5)
Prometheus.observe(c, 1.6) Prometheus.observe(c, 1.6)
metrics = Prometheus.collect(c) metrics = Prometheus.collect(c)
@ -227,16 +227,16 @@ end
end end
# Prometheus.expose_metric(...) # Prometheus.expose_metric(...)
@test sprint(Prometheus.expose_metric, metric) == @test sprint(Prometheus.expose_metric, metric) ==
sprint(Prometheus.expose_io, r) == sprint(Prometheus.expose_io, r) ==
""" """
# HELP metric_name_histogram A histogram. # HELP metric_name_histogram A histogram.
# TYPE metric_name_histogram histogram # TYPE metric_name_histogram histogram
metric_name_histogram_count 2 metric_name_histogram_count 2
metric_name_histogram_sum 2.1 metric_name_histogram_sum 2.1
metric_name_histogram{le="1.0"} 1 metric_name_histogram{le="1.0"} 1
metric_name_histogram{le="2.0"} 2 metric_name_histogram{le="2.0"} 2
metric_name_histogram{le="Inf"} 2 metric_name_histogram{le="Inf"} 2
""" """
end end
@testset "Prometheus.LabelNames and Prometheus.LabelValues" begin @testset "Prometheus.LabelNames and Prometheus.LabelValues" begin
@ -316,17 +316,17 @@ end
# Prometheus.expose_metric(...) # Prometheus.expose_metric(...)
type = Collector === Prometheus.Counter ? "counter" : "gauge" type = Collector === Prometheus.Counter ? "counter" : "gauge"
@test sprint(Prometheus.expose_metric, metric) == @test sprint(Prometheus.expose_metric, metric) ==
sprint(Prometheus.expose_io, r) == sprint(Prometheus.expose_io, r) ==
""" """
# HELP http_requests Number of HTTP requests. # HELP http_requests Number of HTTP requests.
# TYPE http_requests $(type) # TYPE http_requests $(type)
http_requests{endpoint="/bar/",status_code="404"} 3 http_requests{endpoint="/bar/",status_code="404"} 3
http_requests{endpoint="/foo/",status_code="200"} 3 http_requests{endpoint="/foo/",status_code="200"} 3
""" """
end end
@testset "Prometheus.@time gauge::Gauge" begin @testset "Prometheus.@time gauge::Gauge" begin
gauge = Prometheus.Gauge("call_time_last", "Time of last call"; registry=nothing) gauge = Prometheus.Gauge("call_time_last", "Time of last call"; registry = nothing)
Prometheus.@time gauge sleep(0.1) Prometheus.@time gauge sleep(0.1)
@test 0.3 > gauge.value > 0.1 @test 0.3 > gauge.value > 0.1
Prometheus.@time gauge let Prometheus.@time gauge let
@ -354,19 +354,19 @@ end
buckets = [1.0, Inf] buckets = [1.0, Inf]
collector = Collector( collector = Collector(
"call_time", "Time of calls"; "call_time", "Time of calls";
(ishist ? (; buckets=buckets) : (;))..., (ishist ? (; buckets = buckets) : (;))...,
registry=nothing, registry = nothing,
) )
Prometheus.@time collector sleep(0.1) Prometheus.@time collector sleep(0.1)
@test 0.3 > collector._sum > 0.1 @test 0.3 > collector._sum > 0.1
@test collector._count == 1 @test collector._count == 1
ishist && @test (x->x[]).(collector.bucket_counters) == [1, 1] ishist && @test (x -> x[]).(collector.bucket_counters) == [1, 1]
Prometheus.@time collector let Prometheus.@time collector let
sleep(0.1) sleep(0.1)
end end
@test 0.4 > collector._sum > 0.2 @test 0.4 > collector._sum > 0.2
@test collector._count == 2 @test collector._count == 2
ishist && @test (x->x[]).(collector.bucket_counters) == [2, 2] ishist && @test (x -> x[]).(collector.bucket_counters) == [2, 2]
Prometheus.@time collector f() = sleep(0.1) Prometheus.@time collector f() = sleep(0.1)
@sync begin @sync begin
@async f() @async f()
@ -374,7 +374,7 @@ end
end end
@test 0.7 > collector._sum > 0.4 @test 0.7 > collector._sum > 0.4
@test collector._count == 4 @test collector._count == 4
ishist && @test (x->x[]).(collector.bucket_counters) == [4, 4] ishist && @test (x -> x[]).(collector.bucket_counters) == [4, 4]
Prometheus.@time collector function g() Prometheus.@time collector function g()
sleep(0.1) sleep(0.1)
end end
@ -384,15 +384,15 @@ end
end end
@test 0.9 > collector._sum > 0.6 @test 0.9 > collector._sum > 0.6
@test collector._count == 6 @test collector._count == 6
ishist && @test (x->x[]).(collector.bucket_counters) == [6, 6] ishist && @test (x -> x[]).(collector.bucket_counters) == [6, 6]
if ishist if ishist
Prometheus.@time collector sleep(1.1) Prometheus.@time collector sleep(1.1)
@test (x->x[]).(collector.bucket_counters) == [6, 7] @test (x -> x[]).(collector.bucket_counters) == [6, 7]
end end
end end
@testset "Prometheus.@inprogress gauge::Gauge" begin @testset "Prometheus.@inprogress gauge::Gauge" begin
gauge = Prometheus.Gauge("calls_inprogres", "Number of calls in progress"; registry=nothing) gauge = Prometheus.Gauge("calls_inprogres", "Number of calls in progress"; registry = nothing)
Prometheus.@inprogress gauge sleep(0.01) Prometheus.@inprogress gauge sleep(0.01)
@test gauge.value == 0.0 @test gauge.value == 0.0
Prometheus.@inprogress gauge let Prometheus.@inprogress gauge let
@ -493,9 +493,9 @@ end
for (ub, counter, sample) in zip(buckets, Prometheus.labels(c, ls).bucket_counters, metric.samples[subrange]) for (ub, counter, sample) in zip(buckets, Prometheus.labels(c, ls).bucket_counters, metric.samples[subrange])
@test sample.suffix === nothing @test sample.suffix === nothing
@test (sample.label_names::Prometheus.LabelNames{3}).label_names === @test (sample.label_names::Prometheus.LabelNames{3}).label_names ===
(:endpoint, :status_code, :le) (:endpoint, :status_code, :le)
@test (sample.label_values::Prometheus.LabelValues{3}).label_values == @test (sample.label_values::Prometheus.LabelValues{3}).label_values ==
(ls..., string(ub)) (ls..., string(ub))
@test sample.value == counter[] @test sample.value == counter[]
end end
end end
@ -510,15 +510,15 @@ end
@test s4.value == 4.6 # _sum @test s4.value == 4.6 # _sum
# Prometheus.expose_metric(...) # Prometheus.expose_metric(...)
@test sprint(Prometheus.expose_metric, metric) == @test sprint(Prometheus.expose_metric, metric) ==
sprint(Prometheus.expose_io, r) == sprint(Prometheus.expose_io, r) ==
""" """
# HELP http_request_time Time to process requests. # HELP http_request_time Time to process requests.
# TYPE http_request_time summary # TYPE http_request_time summary
http_request_time_count{endpoint="/bar/",status_code="404"} 2 http_request_time_count{endpoint="/bar/",status_code="404"} 2
http_request_time_sum{endpoint="/bar/",status_code="404"} 6.4 http_request_time_sum{endpoint="/bar/",status_code="404"} 6.4
http_request_time_count{endpoint="/foo/",status_code="200"} 2 http_request_time_count{endpoint="/foo/",status_code="200"} 2
http_request_time_sum{endpoint="/foo/",status_code="200"} 4.6 http_request_time_sum{endpoint="/foo/",status_code="200"} 4.6
""" """
end end
end end
@ -531,45 +531,45 @@ end
# Constructor with NTuple{N, String} names # Constructor with NTuple{N, String} names
Prometheus.Family{Prometheus.Counter}( Prometheus.Family{Prometheus.Counter}(
"http_requests", "Total number of HTTP requests", ("target", "status_code"); "http_requests", "Total number of HTTP requests", ("target", "status_code");
registry=nothing, registry = nothing,
), ),
# Constructor with NTuple{N, Symbol} names # Constructor with NTuple{N, Symbol} names
Prometheus.Family{Prometheus.Counter}( Prometheus.Family{Prometheus.Counter}(
"http_requests", "Total number of HTTP requests", (:target, :status_code); "http_requests", "Total number of HTTP requests", (:target, :status_code);
registry=nothing, registry = nothing,
), ),
# Constructor with NamedTuple type # Constructor with NamedTuple type
Prometheus.Family{Prometheus.Counter}( Prometheus.Family{Prometheus.Counter}(
"http_requests", "Total number of HTTP requests", "http_requests", "Total number of HTTP requests",
@NamedTuple{target::String, status_code::Int}; @NamedTuple{target::String, status_code::Int};
registry=nothing, registry = nothing,
), ),
# Constructor with custom struct # Constructor with custom struct
Prometheus.Family{Prometheus.Counter}( Prometheus.Family{Prometheus.Counter}(
"http_requests", "Total number of HTTP requests", RequestLabels; "http_requests", "Total number of HTTP requests", RequestLabels;
registry=nothing, registry = nothing,
), ),
) )
@test Prometheus.labels(fam, ("/api", "200")) === @test Prometheus.labels(fam, ("/api", "200")) ===
fam[("/api", "200")] === fam[("/api", "200")] ===
Prometheus.labels(fam, ("/api", 200)) === Prometheus.labels(fam, ("/api", 200)) ===
fam[("/api", 200)] === fam[("/api", 200)] ===
Prometheus.labels(fam, (target="/api", status_code="200")) === Prometheus.labels(fam, (target = "/api", status_code = "200")) ===
fam[(target="/api", status_code="200")] === fam[(target = "/api", status_code = "200")] ===
Prometheus.labels(fam, (target="/api", status_code=200)) === Prometheus.labels(fam, (target = "/api", status_code = 200)) ===
fam[(target="/api", status_code=200)] === fam[(target = "/api", status_code = 200)] ===
Prometheus.labels(fam, (status_code="200", target="/api")) === Prometheus.labels(fam, (status_code = "200", target = "/api")) ===
fam[(status_code="200", target="/api")] === fam[(status_code = "200", target = "/api")] ===
Prometheus.labels(fam, (status_code=200, target="/api")) === Prometheus.labels(fam, (status_code = 200, target = "/api")) ===
fam[(status_code=200, target="/api")] === fam[(status_code = 200, target = "/api")] ===
Prometheus.labels(fam, RequestLabels("/api", 200)) === Prometheus.labels(fam, RequestLabels("/api", 200)) ===
fam[RequestLabels("/api", 200)] fam[RequestLabels("/api", 200)]
end end
end end
@testset "Prometheus.GCCollector" begin @testset "Prometheus.GCCollector" begin
r = Prometheus.CollectorRegistry() r = Prometheus.CollectorRegistry()
c = Prometheus.GCCollector(; registry=r) c = Prometheus.GCCollector(; registry = r)
@test c in r.collectors @test c in r.collectors
# Record before and after stats and test that the metrics are in between # Record before and after stats and test that the metrics are in between
old_stats = Base.gc_num() old_stats = Base.gc_num()
@ -606,7 +606,7 @@ end
@testset "Prometheus.ProcessCollector" begin @testset "Prometheus.ProcessCollector" begin
r = Prometheus.CollectorRegistry() r = Prometheus.CollectorRegistry()
c = Prometheus.ProcessCollector(; registry=r) c = Prometheus.ProcessCollector(; registry = r)
@test c in r.collectors @test c in r.collectors
metrics = Prometheus.collect(c) metrics = Prometheus.collect(c)
procfs_available = c.system_boot_time > 0 procfs_available = c.system_boot_time > 0
@ -656,7 +656,7 @@ end
@test isempty(metrics) @test isempty(metrics)
end end
# Test that pid function works # Test that pid function works
procc = Prometheus.ProcessCollector(() -> getpid(); registry=nothing) procc = Prometheus.ProcessCollector(() -> getpid(); registry = nothing)
metrics = Prometheus.collect(procc) metrics = Prometheus.collect(procc)
if procfs_available if procfs_available
@test length(metrics) > 0 @test length(metrics) > 0
@ -680,10 +680,10 @@ end
@testset "Character escaping in exposition" begin @testset "Character escaping in exposition" begin
counter = Prometheus.Family{Prometheus.Counter}( counter = Prometheus.Family{Prometheus.Counter}(
"counter_name", "Help with slash \\ and newline \n", ("label_name", ); "counter_name", "Help with slash \\ and newline \n", ("label_name",);
registry = nothing, registry = nothing,
) )
Prometheus.inc(Prometheus.labels(counter, ("backslash \\, quote \", newline \n", ))) Prometheus.inc(Prometheus.labels(counter, ("backslash \\, quote \", newline \n",)))
metric = first(Prometheus.collect(counter)) metric = first(Prometheus.collect(counter))
@test sprint(Prometheus.expose_metric, metric) == @test sprint(Prometheus.expose_metric, metric) ==
""" """
@ -696,8 +696,8 @@ end
@testset "Prometheus.expose(::Union{String, IO})" begin @testset "Prometheus.expose(::Union{String, IO})" begin
r = Prometheus.DEFAULT_REGISTRY r = Prometheus.DEFAULT_REGISTRY
empty!(r.collectors) empty!(r.collectors)
Prometheus.inc(Prometheus.Counter("prom_counter", "Counting things"; registry=r)) Prometheus.inc(Prometheus.Counter("prom_counter", "Counting things"; registry = r))
Prometheus.set(Prometheus.Gauge("prom_gauge", "Gauging things"; registry=r), 1.2) Prometheus.set(Prometheus.Gauge("prom_gauge", "Gauging things"; registry = r), 1.2)
mktempdir() do dir mktempdir() do dir
default = joinpath(dir, "default.prom") default = joinpath(dir, "default.prom")
Prometheus.expose(default) Prometheus.expose(default)
@ -708,17 +708,17 @@ end
reg_io = IOBuffer() reg_io = IOBuffer()
Prometheus.expose(reg_io, r) Prometheus.expose(reg_io, r)
@test read(default, String) == @test read(default, String) ==
read(reg, String) == read(reg, String) ==
String(take!(default_io)) == String(take!(default_io)) ==
String(take!(reg_io)) == String(take!(reg_io)) ==
""" """
# HELP prom_counter Counting things # HELP prom_counter Counting things
# TYPE prom_counter counter # TYPE prom_counter counter
prom_counter 1 prom_counter 1
# HELP prom_gauge Gauging things # HELP prom_gauge Gauging things
# TYPE prom_gauge gauge # TYPE prom_gauge gauge
prom_gauge 1.2 prom_gauge 1.2
""" """
end end
end end
@ -736,7 +736,7 @@ end
elseif http.message.target == "/metrics/reg" elseif http.message.target == "/metrics/reg"
return Prometheus.expose(http, Prometheus.DEFAULT_REGISTRY) return Prometheus.expose(http, Prometheus.DEFAULT_REGISTRY)
elseif http.message.target == "/metrics/nogzip" elseif http.message.target == "/metrics/nogzip"
return Prometheus.expose(http; compress=false) return Prometheus.expose(http; compress = false)
else else
HTTP.setstatus(http, 404) HTTP.setstatus(http, 404)
HTTP.startwrite(http) HTTP.startwrite(http)
@ -752,7 +752,7 @@ end
r_post = HTTP.request("POST", "http://localhost:8123/metrics/default") r_post = HTTP.request("POST", "http://localhost:8123/metrics/default")
@test String(r_post.body) == reference_output @test String(r_post.body) == reference_output
# Bad URI # Bad URI
r_bad = HTTP.request("GET", "http://localhost:8123"; status_exception=false) r_bad = HTTP.request("GET", "http://localhost:8123"; status_exception = false)
@test r_bad.status == 404 @test r_bad.status == 404
# Compression # Compression
for enc in ("gzip", "br, compress, gzip", "br;q=1.0, gzip;q=0.8, *;q=0.1") for enc in ("gzip", "br, compress, gzip", "br;q=1.0, gzip;q=0.8, *;q=0.1")
@ -780,7 +780,11 @@ end
@testset "Utilities" begin @testset "Utilities" begin
x = 1 x = 1
err = try Prometheus.@assert x === nothing; catch e; e; end err = try
Prometheus.@assert x === nothing
catch e
e
end
@test err isa Prometheus.AssertionError @test err isa Prometheus.AssertionError
@test err.msg == "x === nothing" @test err.msg == "x === nothing"
@test occursin("`x === nothing`", sprint(showerror, err)) @test occursin("`x === nothing`", sprint(showerror, err))

Loading…
Cancel
Save