Files
deploy/server/metrics/metrics.go
zeekayandHanzo Dev 1ab6e799c1 cd: the module is github.com/hanzoai/cd, where it is actually hosted
go.mod still declared `module github.com/hanzoai/deploy` after the repo was
renamed. A Go module path is not cosmetic — it is the resolvable location. So
`go get github.com/hanzoai/cd` could not work, and anything importing this
module had to spell a name that no longer exists at that address. The build log
of v3.6.0 is where it surfaced: the compiler was still emitting
github.com/hanzoai/deploy/cmd/cd/commands.

3541 import paths across 690 .go, 19 .proto, 4 .yaml, 3 .sh, 2 .mod, Procfile
and Makefile. Plus the 62 ghcr.io/hanzoai/deploy image references, moved to
ghcr.io/hanzoai/cd to match hanzo.yml's build target — a distinct string from
the module path, replaced separately so neither could clobber the other.

go mod tidy clean, CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build ./... clean.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-28 21:16:24 -07:00

132 lines
4.1 KiB
Go

package metrics
import (
"fmt"
"net/http"
"strconv"
"time"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/hanzoai/cd/common"
"github.com/hanzoai/cd/util/metrics/kubectl"
"github.com/hanzoai/cd/util/profile"
)
type MetricsServer struct {
*http.Server
redisRequestCounter *prometheus.CounterVec
redisRequestHistogram *prometheus.HistogramVec
extensionRequestCounter *prometheus.CounterVec
extensionRequestDuration *prometheus.HistogramVec
loginRequestCounter *prometheus.CounterVec
PrometheusRegistry *prometheus.Registry
}
var (
redisRequestCounter = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "cd_redis_request_total",
Help: "Number of kubernetes requests executed during application reconciliation.",
},
[]string{"initiator", "failed"},
)
redisRequestHistogram = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Name: "cd_redis_request_duration",
Help: "Redis requests duration.",
Buckets: []float64{0.1, 0.25, .5, 1, 2},
},
[]string{"initiator"},
)
extensionRequestCounter = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "cd_proxy_extension_request_total",
Help: "Number of requests sent to configured proxy extensions.",
},
[]string{"extension", "status"},
)
extensionRequestDuration = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Name: "cd_proxy_extension_request_duration_seconds",
Help: "Request duration in seconds between the Hanzo CD API server and the extension backend.",
Buckets: []float64{0.1, 0.25, .5, 1, 2, 5, 10},
},
[]string{"extension"},
)
loginRequestCounter = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "cd_login_request_total",
Help: "Number of login requests to the Hanzo CD API server.",
},
[]string{"status"},
)
argoVersion = prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: "cd_info",
Help: "Hanzo CD version information",
},
[]string{"version"},
)
)
// NewMetricsServer returns a new prometheus server which collects api server metrics
func NewMetricsServer(host string, port int) *MetricsServer {
mux := http.NewServeMux()
registry := prometheus.NewRegistry()
mux.Handle("/metrics", promhttp.HandlerFor(prometheus.Gatherers{
registry,
prometheus.DefaultGatherer,
}, promhttp.HandlerOpts{}))
argoVersion.WithLabelValues(common.GetVersion().Version).Set(1)
profile.RegisterProfiler(mux)
registry.MustRegister(redisRequestCounter)
registry.MustRegister(redisRequestHistogram)
registry.MustRegister(extensionRequestCounter)
registry.MustRegister(extensionRequestDuration)
registry.MustRegister(loginRequestCounter)
registry.MustRegister(argoVersion)
kubectl.RegisterWithClientGo()
kubectl.RegisterWithPrometheus(registry)
return &MetricsServer{
Server: &http.Server{
Addr: fmt.Sprintf("%s:%d", host, port),
Handler: mux,
},
redisRequestCounter: redisRequestCounter,
redisRequestHistogram: redisRequestHistogram,
extensionRequestCounter: extensionRequestCounter,
extensionRequestDuration: extensionRequestDuration,
loginRequestCounter: loginRequestCounter,
PrometheusRegistry: registry,
}
}
func (m *MetricsServer) IncRedisRequest(failed bool) {
m.redisRequestCounter.WithLabelValues("cd-server", strconv.FormatBool(failed)).Inc()
}
// ObserveRedisRequestDuration observes redis request duration
func (m *MetricsServer) ObserveRedisRequestDuration(duration time.Duration) {
m.redisRequestHistogram.WithLabelValues("cd-server").Observe(duration.Seconds())
}
func (m *MetricsServer) IncExtensionRequestCounter(extension string, status int) {
m.extensionRequestCounter.WithLabelValues(extension, strconv.Itoa(status)).Inc()
}
func (m *MetricsServer) ObserveExtensionRequestDuration(extension string, duration time.Duration) {
m.extensionRequestDuration.WithLabelValues(extension).Observe(duration.Seconds())
}
// IncLoginRequestCounter increments the login request counter with the given status
// status can be "success" or "failure"
func (m *MetricsServer) IncLoginRequestCounter(status string) {
m.loginRequestCounter.WithLabelValues(status).Inc()
}