From 3d72c1dc8a4e4e7ae5c3d82c4f241e2eaf7afbfe Mon Sep 17 00:00:00 2001 From: chrislu Date: Fri, 21 Nov 2025 16:13:19 -0800 Subject: [PATCH] add build info metrics --- weed/stats/constants_4bytes.go | 9 +++ weed/stats/constants_5bytes.go | 9 +++ weed/stats/metrics.go | 28 ++++++++++ weed/stats/metrics_buildinfo_test.go | 82 ++++++++++++++++++++++++++++ weed/util/version/constants.go | 6 ++ 5 files changed, 134 insertions(+) create mode 100644 weed/stats/constants_4bytes.go create mode 100644 weed/stats/constants_5bytes.go create mode 100644 weed/stats/metrics_buildinfo_test.go diff --git a/weed/stats/constants_4bytes.go b/weed/stats/constants_4bytes.go new file mode 100644 index 000000000..352b24519 --- /dev/null +++ b/weed/stats/constants_4bytes.go @@ -0,0 +1,9 @@ +//go:build !5BytesOffset +// +build !5BytesOffset + +package stats + +const ( + SizeLimit = "30GB" +) + diff --git a/weed/stats/constants_5bytes.go b/weed/stats/constants_5bytes.go new file mode 100644 index 000000000..e4e6e4a05 --- /dev/null +++ b/weed/stats/constants_5bytes.go @@ -0,0 +1,9 @@ +//go:build 5BytesOffset +// +build 5BytesOffset + +package stats + +const ( + SizeLimit = "8000GB" +) + diff --git a/weed/stats/metrics.go b/weed/stats/metrics.go index 2723e253f..a46e715c1 100644 --- a/weed/stats/metrics.go +++ b/weed/stats/metrics.go @@ -4,6 +4,7 @@ import ( "net" "net/http" "os" + "runtime" "strconv" "strings" "sync" @@ -16,6 +17,22 @@ import ( "github.com/seaweedfs/seaweedfs/weed/glog" ) +// Version info - these are set by the version package to avoid import cycles +var ( + versionNumber = "unknown" + commit = "" +) + +// SetVersionInfo sets the version information for the BuildInfo metric +// This is called by the version package during initialization +func SetVersionInfo(version, commitHash string) { + versionNumber = version + commit = commitHash + // Update the metric with the new values + BuildInfo.Reset() + BuildInfo.WithLabelValues(versionNumber, commit, SizeLimit, runtime.GOOS, runtime.GOARCH).Set(1) +} + // Readonly volume types const ( Namespace = "SeaweedFS" @@ -34,6 +51,14 @@ var bucketLastActiveLock sync.Mutex var ( Gather = prometheus.NewRegistry() + BuildInfo = prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Namespace: Namespace, + Subsystem: "build", + Name: "info", + Help: "Build information", + }, []string{"version", "commit", "sizelimit", "goos", "goarch"}) + MasterClientConnectCounter = prometheus.NewCounterVec( prometheus.CounterOpts{ Namespace: Namespace, @@ -385,6 +410,9 @@ var ( ) func init() { + BuildInfo.WithLabelValues(versionNumber, commit, SizeLimit, runtime.GOOS, runtime.GOARCH).Set(1) + Gather.MustRegister(BuildInfo) + Gather.MustRegister(MasterClientConnectCounter) Gather.MustRegister(MasterRaftIsleader) Gather.MustRegister(MasterAdminLock) diff --git a/weed/stats/metrics_buildinfo_test.go b/weed/stats/metrics_buildinfo_test.go new file mode 100644 index 000000000..1fc4a2b52 --- /dev/null +++ b/weed/stats/metrics_buildinfo_test.go @@ -0,0 +1,82 @@ +package stats_test + +import ( + "runtime" + "strings" + "testing" + + "github.com/prometheus/client_golang/prometheus/testutil" + "github.com/seaweedfs/seaweedfs/weed/stats" + _ "github.com/seaweedfs/seaweedfs/weed/util/version" // Import to trigger version init +) + +func TestBuildInfo(t *testing.T) { + // Verify that BuildInfo metric is registered and has the expected value + count := testutil.CollectAndCount(stats.BuildInfo) + if count != 1 { + t.Errorf("Expected 1 BuildInfo metric, got %d", count) + } + + // Verify the metric can be gathered + metrics, err := stats.Gather.Gather() + if err != nil { + t.Fatalf("Failed to gather metrics: %v", err) + } + + // Find the build_info metric + found := false + for _, mf := range metrics { + if mf.GetName() == "SeaweedFS_build_info" { + found = true + metric := mf.GetMetric()[0] + + // Verify the metric value is 1 + if metric.GetGauge().GetValue() != 1 { + t.Errorf("Expected BuildInfo value to be 1, got %f", metric.GetGauge().GetValue()) + } + + // Verify labels exist + labels := metric.GetLabel() + labelMap := make(map[string]string) + for _, label := range labels { + labelMap[label.GetName()] = label.GetValue() + } + + // Check required labels + if _, ok := labelMap["version"]; !ok { + t.Error("Missing 'version' label") + } + if _, ok := labelMap["commit"]; !ok { + t.Error("Missing 'commit' label") + } + if _, ok := labelMap["sizelimit"]; !ok { + t.Error("Missing 'sizelimit' label") + } + if labelMap["goos"] != runtime.GOOS { + t.Errorf("Expected goos='%s', got '%s'", runtime.GOOS, labelMap["goos"]) + } + if labelMap["goarch"] != runtime.GOARCH { + t.Errorf("Expected goarch='%s', got '%s'", runtime.GOARCH, labelMap["goarch"]) + } + + // Verify version format + if !strings.Contains(labelMap["version"], ".") { + t.Errorf("Version should contain a dot: %s", labelMap["version"]) + } + + // Verify sizelimit is either 30GB or 8000GB + if labelMap["sizelimit"] != "30GB" && labelMap["sizelimit"] != "8000GB" { + t.Errorf("Expected sizelimit to be '30GB' or '8000GB', got '%s'", labelMap["sizelimit"]) + } + + t.Logf("BuildInfo metric: version=%s, commit=%s, sizelimit=%s, goos=%s, goarch=%s", + labelMap["version"], labelMap["commit"], labelMap["sizelimit"], + labelMap["goos"], labelMap["goarch"]) + } + } + + if !found { + t.Error("BuildInfo metric not found in gathered metrics") + } +} + diff --git a/weed/util/version/constants.go b/weed/util/version/constants.go index 33b226202..bb3bfa614 100644 --- a/weed/util/version/constants.go +++ b/weed/util/version/constants.go @@ -3,6 +3,7 @@ package version import ( "fmt" + "github.com/seaweedfs/seaweedfs/weed/stats" "github.com/seaweedfs/seaweedfs/weed/util" ) @@ -14,6 +15,11 @@ var ( COMMIT = "" ) +func init() { + // Set version info in stats for Prometheus metrics + stats.SetVersionInfo(VERSION_NUMBER, COMMIT) +} + func Version() string { return VERSION + " " + COMMIT }