mangleDuration := prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Name: "mangle_html_duration_seconds",
Help: "Time spent processing HTML",
Buckets: []float64{.001, .005, .01, .05, .1, .5},
},
[]string{"status"},
)
I want to add a custom metric into caddy,what should I do?
func (m *ContentFilter) Provision(ctx caddy.Context) error {
var registerErr error
if reg := ctx.GetMetricsRegistry(); reg != nil {
registerOnce.Do(func() {
logrus.Infof("Registing metric: %s", "mangle_html_duration_seconds")
if err := reg.Register(mangleDuration); err != nil {
registerErr = fmt.Errorf("failed to register metrics: %v", err)
}
})
}
return registerErr
}
timer := prometheus.NewTimer(prometheus.ObserverFunc(func(v float64) {
mangleDuration.WithLabelValues("status").Observe(v)
}))
defer timer.ObserveDuration()
I’m new to Caddy, why is the metric not showing up after registration?
Mohammed90
(Mohammed Al Sahaf)
April 16, 2025, 10:27pm
4
Did you initiate any requests that affect the values of the metric? Metrics only show up when their values change from the initial one. Show us how you’re testing.
what I did
var (
mangleDuration = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Name: "mangle_html_duration_seconds",
Help: "Time spent processing HTML",
Buckets: []float64{1, 5, 10, 50, 100, 500},
},
[]string{"status"},
)
registerOnce sync.Once
)
func mangleHTML(input []byte) ([]byte, bool) {
var (
buf bytes.Buffer
err error
doc *html.Node
)
timer := prometheus.NewTimer(prometheus.ObserverFunc(func(v float64) {
mangleDuration.WithLabelValues("success").Observe(v)
logrus.Infof("mangleHTML invoke spent %.3f", v*1000)
}))
defer timer.ObserveDuration()
......
}
func (m *ContentFilter) Provision(ctx caddy.Context) error {
var registerErr error
if reg := ctx.GetMetricsRegistry(); reg != nil {
registerOnce.Do(func() {
logrus.Infof("Registing metric: %s", "mangle_html_duration_seconds")
if err := reg.Register(mangleDuration); err != nil {
registerErr = fmt.Errorf("failed to register metrics: %v", err)
}
})
}
return registerErr
}
I wrote a Caddy module that intercepts reverse proxy responses to sanitize HTML. I can confirm that this method has been called, as shown in the logs below.
time="2025-04-16T17:48:21+08:00" level=info msg="mangleHTML invoke spent 17.520"
time="2025-04-16T17:48:21+08:00" level=info msg="request url: 127.0.0.1:64839/be7e29b0e84f/avatar/05bb842f87f5c312304d66352d694b02 replace to -> 127.0.0.1:64839/avatar/05bb842f87f5c312304d66352d694b02\n"
Find this metric with Grafana
I’ve already integrated Caddy metrics into Grafana.
version: "3.8"
services:
prometheus:
image: prom/prometheus:latest
container_name: prometheus
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
restart: unless-stopped
grafana:
image: grafana/grafana-oss:latest
container_name: grafana
ports:
- "3000:3000"
restart: unless-stopped
global:
scrape_interval: 5s
scrape_configs:
- job_name: 'caddy'
static_configs:
- targets: ['10.21.177.52:2019']