aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lu <chrislusf@users.noreply.github.com>2025-11-21 16:55:28 -0800
committerGitHub <noreply@github.com>2025-11-21 16:55:28 -0800
commit5f7a292334e952ac17fd7458d31c3d36e0b98769 (patch)
tree800dee668aa04abdfc3587842f0065d3f8813e4a
parenta77dfb1ddd36d071f90acc01a1399e7ae52865d1 (diff)
downloadseaweedfs-5f7a292334e952ac17fd7458d31c3d36e0b98769.tar.xz
seaweedfs-5f7a292334e952ac17fd7458d31c3d36e0b98769.zip
add build info metrics (#7525)
* add build info metrics * unused * metrics on build * size limit * once
-rw-r--r--weed/stats/metrics.go26
-rw-r--r--weed/stats/metrics_buildinfo_test.go82
-rw-r--r--weed/util/version/constants.go6
3 files changed, 112 insertions, 2 deletions
diff --git a/weed/stats/metrics.go b/weed/stats/metrics.go
index 2723e253f..95491abf1 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,19 @@ import (
"github.com/seaweedfs/seaweedfs/weed/glog"
)
+// SetVersionInfo sets the version information for the BuildInfo metric
+// This is called by the version package during initialization.
+// It uses sync.Once to ensure the build information is set only once,
+// making it safe to call multiple times while ensuring immutability.
+var SetVersionInfo = func() func(string, string, string) {
+ var once sync.Once
+ return func(version, commitHash, sizeLimit string) {
+ once.Do(func() {
+ BuildInfo.WithLabelValues(version, commitHash, sizeLimit, runtime.GOOS, runtime.GOARCH).Set(1)
+ })
+ }
+}()
+
// Readonly volume types
const (
Namespace = "SeaweedFS"
@@ -26,14 +40,20 @@ const (
bucketAtiveTTL = 10 * time.Minute
)
-var readOnlyVolumeTypes = [4]string{IsReadOnly, NoWriteOrDelete, NoWriteCanDelete, IsDiskSpaceLow}
-
var bucketLastActiveTsNs map[string]int64 = map[string]int64{}
var bucketLastActiveLock sync.Mutex
var (
Gather = prometheus.NewRegistry()
+ BuildInfo = prometheus.NewGaugeVec(
+ prometheus.GaugeOpts{
+ Namespace: Namespace,
+ Subsystem: "build",
+ Name: "info",
+ Help: "A metric with a constant '1' value labeled by version, commit, sizelimit, goos, and goarch from which SeaweedFS was built.",
+ }, []string{"version", "commit", "sizelimit", "goos", "goarch"})
+
MasterClientConnectCounter = prometheus.NewCounterVec(
prometheus.CounterOpts{
Namespace: Namespace,
@@ -385,6 +405,8 @@ var (
)
func init() {
+ 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..8cbe2225a 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, util.SizeLimit)
+}
+
func Version() string {
return VERSION + " " + COMMIT
}