Add page operation metrics and expose them in Prometheus text format.

This commit is contained in:
miyuko
2025-09-22 14:33:25 +01:00
parent 584957a92d
commit 1aef0288e7
7 changed files with 79 additions and 9 deletions

View File

@@ -45,9 +45,10 @@ type Config struct {
}
type ServerConfig struct {
Pages string `toml:"pages" default:"tcp/:3000"`
Caddy string `toml:"caddy" default:"tcp/:3001"`
Health string `toml:"health" default:"tcp/:3002"`
Pages string `toml:"pages" default:"tcp/:3000"`
Caddy string `toml:"caddy" default:"tcp/:3001"`
Health string `toml:"health" default:"tcp/:3002"`
Metrics string `toml:"metrics" default:"tcp/:3003"`
}
type WildcardConfig struct {

View File

@@ -50,10 +50,8 @@ func panicHandler(handler http.Handler) http.Handler {
})
}
func serve(listener net.Listener, serve func(http.ResponseWriter, *http.Request)) {
func serve(listener net.Listener, handler http.Handler) {
if listener != nil {
var handler http.Handler
handler = http.HandlerFunc(serve)
handler = ObserveHTTPHandler(handler)
handler = panicHandler(handler)
@@ -148,6 +146,7 @@ func main() {
pagesListener := listen("pages", config.Server.Pages)
caddyListener := listen("caddy", config.Server.Caddy)
healthListener := listen("health", config.Server.Health)
metricsListener := listen("metrics", config.Server.Metrics)
if err := ConfigureBackend(&config.Storage); err != nil {
log.Fatalln(err)
@@ -157,9 +156,10 @@ func main() {
log.Fatalln(err)
}
go serve(pagesListener, ServePages)
go serve(caddyListener, ServeCaddy)
go serve(healthListener, ServeHealth)
go serve(pagesListener, http.HandlerFunc(ServePages))
go serve(caddyListener, http.HandlerFunc(ServeCaddy))
go serve(healthListener, http.HandlerFunc(ServeHealth))
go serve(metricsListener, NewMetricsHTTPHandler())
if config.Insecure {
log.Println("serve: ready (INSECURE)")

View File

@@ -6,6 +6,7 @@ import (
"runtime/debug"
"github.com/honeybadger-io/honeybadger-go"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
func hasHoneybadger() bool {
@@ -25,3 +26,7 @@ func ObserveHTTPHandler(handler http.Handler) http.Handler {
}
return handler
}
func NewMetricsHTTPHandler() http.Handler {
return promhttp.Handler()
}

View File

@@ -14,14 +14,51 @@ import (
"path"
"strings"
"time"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
)
const notFoundPage = "404.html"
var (
siteUpdatesCount = promauto.NewCounterVec(prometheus.CounterOpts{
Name: "git_pages_site_updates",
Help: "Count of site updates in total",
}, []string{"via"})
siteUpdateOkCount = promauto.NewCounterVec(prometheus.CounterOpts{
Name: "git_pages_site_update_ok",
Help: "Count of successful site updates",
}, []string{"outcome"})
siteUpdateErrorCount = promauto.NewCounterVec(prometheus.CounterOpts{
Name: "git_pages_site_update_error",
Help: "Count of failed site updates",
}, []string{"cause"})
)
func makeWebRoot(host string, projectName string) string {
return fmt.Sprintf("%s/%s", strings.ToLower(host), projectName)
}
func reportSiteUpdate(via string, result *UpdateResult) {
siteUpdatesCount.With(prometheus.Labels{"via": via}).Inc()
switch result.outcome {
case UpdateError:
siteUpdateErrorCount.With(prometheus.Labels{"cause": "other"}).Inc()
case UpdateTimeout:
siteUpdateErrorCount.With(prometheus.Labels{"cause": "timeout"}).Inc()
case UpdateNoChange:
// nothing to report
case UpdateCreated:
siteUpdateOkCount.With(prometheus.Labels{"outcome": "created"}).Inc()
case UpdateReplaced:
siteUpdateOkCount.With(prometheus.Labels{"outcome": "replaced"}).Inc()
case UpdateDeleted:
siteUpdateOkCount.With(prometheus.Labels{"outcome": "deleted"}).Inc()
}
}
func getPage(w http.ResponseWriter, r *http.Request) error {
var err error
var sitePath string
@@ -266,6 +303,7 @@ func putPage(w http.ResponseWriter, r *http.Request) error {
} else {
fmt.Fprintln(w, "internal error")
}
reportSiteUpdate("rest", &result)
return nil
}
@@ -401,6 +439,7 @@ func postPage(w http.ResponseWriter, r *http.Request) error {
fmt.Fprintf(w, "- %s\n", problem)
}
}
reportSiteUpdate("webhook", &result)
return nil
}