瀏覽代碼

feat(config): expose folder and device info as metrics (fixes #9519) (#10148)

Tihs makes it easier to use metrics based on device and folder labels,
names, and other attributes. Other metrics which are based on folder or
device ID can be joined with these info metrics to enrich their label
sets.

```
# HELP syncthing_config_device_info Provides additional information labels on devices
# TYPE syncthing_config_device_info gauge
syncthing_config_device_info{device="I6KAH76-66SLLLB-5PFXSOA-UFJCDZC-YAOMLEK-CP2GB32-BV5RQST-3PSROAU",introducer="false",name="s1",paused="false",untrusted="false"} 1

# HELP syncthing_config_folder_info Provides additional information labels on folders
# TYPE syncthing_config_folder_info gauge
syncthing_config_folder_info{folder="default",label="The default folder",path="s2",paused="false",type="sendreceive"} 1
```

With this you can e.g. query for

```
syncthing_connections_active * on(device) group_left syncthing_config_device_info
```

Fixes #9519 
Closes #10074 
Closes #10147
Jakob Borg 4 月之前
父節點
當前提交
1fdf07933c
共有 2 個文件被更改,包括 63 次插入0 次删除
  1. 1 0
      cmd/syncthing/main.go
  2. 62 0
      lib/config/metrics.go

+ 1 - 0
cmd/syncthing/main.go

@@ -578,6 +578,7 @@ func syncthingMain(options serveOptions) {
 		os.Exit(svcutil.ExitError.AsInt())
 	}
 	earlyService.Add(cfgWrapper)
+	config.RegisterInfoMetrics(cfgWrapper)
 
 	// Candidate builds should auto upgrade. Make sure the option is set,
 	// unless we are in a build where it's disabled or the STNOUPGRADE

+ 62 - 0
lib/config/metrics.go

@@ -0,0 +1,62 @@
+// Copyright (C) 2025 The Syncthing Authors.
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this file,
+// You can obtain one at https://mozilla.org/MPL/2.0/.
+
+package config
+
+import (
+	"strconv"
+
+	"github.com/prometheus/client_golang/prometheus"
+)
+
+// RegisterInfoMetrics registers Prometheus metrics for the given config
+// wrapper.
+func RegisterInfoMetrics(cfg Wrapper) {
+	prometheus.DefaultRegisterer.MustRegister(prometheus.CollectorFunc((&folderInfoMetric{cfg}).Collect))
+	prometheus.DefaultRegisterer.MustRegister(prometheus.CollectorFunc((&folderDeviceMetric{cfg}).Collect))
+}
+
+type folderInfoMetric struct {
+	cfg Wrapper
+}
+
+var folderInfoMetricDesc = prometheus.NewDesc(
+	"syncthing_config_folder_info",
+	"Provides additional information labels on folders",
+	[]string{"folder", "label", "type", "path", "paused"},
+	nil,
+)
+
+func (m *folderInfoMetric) Collect(ch chan<- prometheus.Metric) {
+	for _, folder := range m.cfg.FolderList() {
+		ch <- prometheus.MustNewConstMetric(
+			folderInfoMetricDesc,
+			prometheus.GaugeValue, 1,
+			folder.ID, folder.Label, folder.Type.String(), folder.Path, strconv.FormatBool(folder.Paused),
+		)
+	}
+}
+
+type folderDeviceMetric struct {
+	cfg Wrapper
+}
+
+var folderDeviceMetricDesc = prometheus.NewDesc(
+	"syncthing_config_device_info",
+	"Provides additional information labels on devices",
+	[]string{"device", "name", "introducer", "paused", "untrusted"},
+	nil,
+)
+
+func (m *folderDeviceMetric) Collect(ch chan<- prometheus.Metric) {
+	for _, device := range m.cfg.DeviceList() {
+		ch <- prometheus.MustNewConstMetric(
+			folderDeviceMetricDesc,
+			prometheus.GaugeValue, 1,
+			device.DeviceID.String(), device.Name, strconv.FormatBool(device.Introducer), strconv.FormatBool(device.Paused), strconv.FormatBool(device.Untrusted),
+		)
+	}
+}