boulder/test/ocsp/ocsp_forever/main.go

106 lines
3.0 KiB
Go

package main
import (
"flag"
"fmt"
"log"
"net/http"
"os"
"path/filepath"
"time"
"github.com/letsencrypt/boulder/test/ocsp/helper"
prom "github.com/prometheus/client_golang/prometheus"
promhttp "github.com/prometheus/client_golang/prometheus/promhttp"
)
var listenAddress = flag.String("listen", ":8080", "Port to listen on")
var interval = flag.String("interval", "1m", "Time to sleep between fetches")
var (
response_count = prom.NewCounterVec(prom.CounterOpts{
Name: "responses",
Help: "completed responses",
}, nil)
errors_count = prom.NewCounterVec(prom.CounterOpts{
Name: "errors",
Help: "errored responses",
}, nil)
request_time_seconds_hist = prom.NewHistogram(prom.HistogramOpts{
Name: "request_time_seconds",
Help: "time a request takes",
})
request_time_seconds_summary = prom.NewSummary(prom.SummaryOpts{
Name: "request_time_seconds_summary",
Help: "time a request takes",
})
response_age_seconds = prom.NewHistogram(prom.HistogramOpts{
Name: "response_age_seconds",
Help: "how old OCSP responses were",
Buckets: []float64{24 * time.Hour.Seconds(), 48 * time.Hour.Seconds(),
72 * time.Hour.Seconds(), 96 * time.Hour.Seconds(), 120 * time.Hour.Seconds()},
})
response_age_seconds_summary = prom.NewSummary(prom.SummaryOpts{
Name: "response_age_seconds_summary",
Help: "how old OCSP responses were",
Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001, 1: 0.0001},
})
)
func init() {
prom.MustRegister(response_count)
prom.MustRegister(request_time_seconds_hist)
prom.MustRegister(request_time_seconds_summary)
prom.MustRegister(response_age_seconds)
prom.MustRegister(response_age_seconds_summary)
}
func do(f string) {
start := time.Now()
resp, err := helper.ReqFile(f, helper.ConfigFromFlags())
latency := time.Since(start)
if err != nil {
errors_count.With(prom.Labels{}).Inc()
fmt.Fprintf(os.Stderr, "error for %s: %s\n", f, err)
}
request_time_seconds_hist.Observe(latency.Seconds())
response_count.With(prom.Labels{}).Inc()
request_time_seconds_summary.Observe(latency.Seconds())
if resp != nil {
response_age_seconds.Observe(time.Since(resp.ThisUpdate).Seconds())
response_age_seconds_summary.Observe(time.Since(resp.ThisUpdate).Seconds())
}
}
func main() {
flag.Parse()
sleepTime, err := time.ParseDuration(*interval)
if err != nil {
log.Fatal(err)
}
http.Handle("/metrics", promhttp.Handler())
go func() {
err := http.ListenAndServe(*listenAddress, nil)
if err != nil && err != http.ErrServerClosed {
log.Fatal(err)
}
}()
for {
for _, pattern := range flag.Args() {
// Note: re-glob this pattern on each run, in case new certificates have
// been added. This makes it easy to keep the list of certificates to be
// checked fresh.
files, err := filepath.Glob(pattern)
if err != nil {
log.Fatal(err)
}
// Loop through the available files (potentially hundreds or thousands),
// requesting one response per `sleepTime`
for _, f := range files {
do(f)
time.Sleep(sleepTime)
}
}
}
}