mirror of
https://codeberg.org/git-pages/git-pages.git
synced 2026-05-14 03:01:48 +00:00
Add page operation metrics and expose them in Prometheus text format.
This commit is contained in:
@@ -8,6 +8,7 @@ log-format = "datetime+message"
|
||||
pages = "tcp/:3000"
|
||||
caddy = "tcp/:3001"
|
||||
health = "tcp/:3002"
|
||||
metrics = "tcp/:3003"
|
||||
|
||||
[[wildcard]] # non-default section
|
||||
domain = "codeberg.page"
|
||||
|
||||
8
go.mod
8
go.mod
@@ -22,6 +22,8 @@ require (
|
||||
dario.cat/mergo v1.0.1 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.2 // indirect
|
||||
github.com/ProtonMail/go-crypto v1.3.0 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/cloudflare/circl v1.6.1 // indirect
|
||||
github.com/cyphar/filepath-securejoin v0.4.1 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
@@ -36,11 +38,16 @@ require (
|
||||
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
|
||||
github.com/minio/crc64nvme v1.0.2 // indirect
|
||||
github.com/minio/md5-simd v1.1.2 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect
|
||||
github.com/pborman/uuid v1.2.1 // indirect
|
||||
github.com/philhofer/fwd v1.2.0 // indirect
|
||||
github.com/pjbgf/sha1cd v0.5.0 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/prometheus/client_golang v1.23.2 // indirect
|
||||
github.com/prometheus/client_model v0.6.2 // indirect
|
||||
github.com/prometheus/common v0.66.1 // indirect
|
||||
github.com/prometheus/procfs v0.16.1 // indirect
|
||||
github.com/rs/xid v1.6.0 // indirect
|
||||
github.com/sergi/go-diff v1.4.0 // indirect
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible // indirect
|
||||
@@ -48,6 +55,7 @@ require (
|
||||
github.com/tj/assert v0.0.3 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.3 // indirect
|
||||
go.yaml.in/yaml/v2 v2.4.2 // indirect
|
||||
golang.org/x/crypto v0.41.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20250531010427-b6e5de432a8b // indirect
|
||||
golang.org/x/net v0.43.0 // indirect
|
||||
|
||||
16
go.sum
16
go.sum
@@ -10,8 +10,12 @@ github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFI
|
||||
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/c2h5oh/datasize v0.0.0-20231215233829-aa82cc1e6500 h1:6lhrsTEnloDPXyeZBvSYvQf8u86jbKehZPVDDlkgDl4=
|
||||
github.com/c2h5oh/datasize v0.0.0-20231215233829-aa82cc1e6500/go.mod h1:S/7n9copUssQ56c7aAgHqftWO4LTf4xY6CGWt8Bc+3M=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0=
|
||||
github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
|
||||
github.com/creasty/defaults v1.8.0 h1:z27FJxCAa0JKt3utc0sCImAEb+spPucmKoOdLHvHYKk=
|
||||
@@ -70,6 +74,8 @@ github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
|
||||
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
|
||||
github.com/minio/minio-go/v7 v7.0.95 h1:ywOUPg+PebTMTzn9VDsoFJy32ZuARN9zhB+K3IYEvYU=
|
||||
github.com/minio/minio-go/v7 v7.0.95/go.mod h1:wOOX3uxS334vImCNRVyIDdXX9OsXDm89ToynKgqUKlo=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0=
|
||||
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y=
|
||||
github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw=
|
||||
@@ -84,6 +90,14 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o=
|
||||
github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg=
|
||||
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
|
||||
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
|
||||
github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs=
|
||||
github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA=
|
||||
github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg=
|
||||
github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is=
|
||||
github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU=
|
||||
github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=
|
||||
github.com/sergi/go-diff v1.4.0 h1:n/SP9D5ad1fORl+llWyN+D6qoUETXNZARKjyY2/KVCw=
|
||||
@@ -113,6 +127,8 @@ github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQ
|
||||
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||
github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw=
|
||||
github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI=
|
||||
go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU=
|
||||
golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4=
|
||||
golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc=
|
||||
golang.org/x/exp v0.0.0-20250531010427-b6e5de432a8b h1:QoALfVG9rhQ/M7vYDScfPdWjGL9dlsVVM5VGh7aKoAA=
|
||||
|
||||
@@ -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 {
|
||||
|
||||
12
src/main.go
12
src/main.go
@@ -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)")
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
39
src/pages.go
39
src/pages.go
@@ -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
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user