Skip to content

Commit 233e4b8

Browse files
Add prometheus label to build info (#319)
* Add prometheus label to build info * add test with group
1 parent 9eba431 commit 233e4b8

File tree

7 files changed

+84
-87
lines changed

7 files changed

+84
-87
lines changed

docs/content/status/prometheus/index.md

+12-12
Original file line numberDiff line numberDiff line change
@@ -89,43 +89,43 @@ Here's an example of the generated prometheus file:
8989
```
9090
# HELP resticprofile_backup_added_bytes Total number of bytes added to the repository.
9191
# TYPE resticprofile_backup_added_bytes gauge
92-
resticprofile_backup_added_bytes{profile="prom"} 70690
92+
resticprofile_backup_added_bytes{profile="prom"} 9.83610983e+08
9393
# HELP resticprofile_backup_dir_changed Number of directories with changes.
9494
# TYPE resticprofile_backup_dir_changed gauge
95-
resticprofile_backup_dir_changed{profile="prom"} 15
95+
resticprofile_backup_dir_changed{profile="prom"} 0
9696
# HELP resticprofile_backup_dir_new Number of new directories added to the backup.
9797
# TYPE resticprofile_backup_dir_new gauge
98-
resticprofile_backup_dir_new{profile="prom"} 0
98+
resticprofile_backup_dir_new{profile="prom"} 847
9999
# HELP resticprofile_backup_dir_unmodified Number of directories unmodified since last backup.
100100
# TYPE resticprofile_backup_dir_unmodified gauge
101-
resticprofile_backup_dir_unmodified{profile="prom"} 529
101+
resticprofile_backup_dir_unmodified{profile="prom"} 0
102102
# HELP resticprofile_backup_duration_seconds The backup duration (in seconds).
103103
# TYPE resticprofile_backup_duration_seconds gauge
104-
resticprofile_backup_duration_seconds{profile="prom"} 0.879901212
104+
resticprofile_backup_duration_seconds{profile="prom"} 4.453124672
105105
# HELP resticprofile_backup_files_changed Number of files with changes.
106106
# TYPE resticprofile_backup_files_changed gauge
107-
resticprofile_backup_files_changed{profile="prom"} 3
107+
resticprofile_backup_files_changed{profile="prom"} 0
108108
# HELP resticprofile_backup_files_new Number of new files added to the backup.
109109
# TYPE resticprofile_backup_files_new gauge
110-
resticprofile_backup_files_new{profile="prom"} 1
110+
resticprofile_backup_files_new{profile="prom"} 6006
111111
# HELP resticprofile_backup_files_processed Total number of files scanned by the backup for changes.
112112
# TYPE resticprofile_backup_files_processed gauge
113-
resticprofile_backup_files_processed{profile="prom"} 3680
113+
resticprofile_backup_files_processed{profile="prom"} 6006
114114
# HELP resticprofile_backup_files_unmodified Number of files unmodified since last backup.
115115
# TYPE resticprofile_backup_files_unmodified gauge
116-
resticprofile_backup_files_unmodified{profile="prom"} 3676
116+
resticprofile_backup_files_unmodified{profile="prom"} 0
117117
# HELP resticprofile_backup_processed_bytes Total number of bytes scanned for changes.
118118
# TYPE resticprofile_backup_processed_bytes gauge
119-
resticprofile_backup_processed_bytes{profile="prom"} 8.55433765e+08
119+
resticprofile_backup_processed_bytes{profile="prom"} 1.016520315e+09
120120
# HELP resticprofile_backup_status Backup status: 0=fail, 1=warning, 2=success.
121121
# TYPE resticprofile_backup_status gauge
122122
resticprofile_backup_status{profile="prom"} 2
123123
# HELP resticprofile_backup_time_seconds Last backup run (unixtime).
124124
# TYPE resticprofile_backup_time_seconds gauge
125-
resticprofile_backup_time_seconds{profile="prom"} 1.662310865e+09
125+
resticprofile_backup_time_seconds{profile="prom"} 1.707863748e+09
126126
# HELP resticprofile_build_info resticprofile build information.
127127
# TYPE resticprofile_build_info gauge
128-
resticprofile_build_info{goversion="go1.19",version="0.19.0"} 1
128+
resticprofile_build_info{goversion="go1.22.0",profile="prom",version="0.26.0-dev"} 1
129129
130130
```
131131

examples/dev.yaml

+4
Original file line numberDiff line numberDiff line change
@@ -163,10 +163,14 @@ prom:
163163
host: "{{ .Hostname }}"
164164
status-file: /Volumes/RAMDisk/status.json
165165
backup:
166+
check-after: true
166167
extended-status: true
167168
no-error-on-warning: true
168169
source:
169170
- "{{ .CurrentDir }}"
171+
retention:
172+
after-backup: true
173+
keep-last: 30
170174

171175
system:
172176
initialize: true

main.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -562,7 +562,7 @@ func runProfile(ctx *Context) error {
562562
wrapper.addProgress(status.NewProgress(profile, status.NewStatus(profile.StatusFile)))
563563
}
564564
if profile.PrometheusPush != "" || profile.PrometheusSaveToFile != "" {
565-
wrapper.addProgress(prom.NewProgress(profile, prom.NewMetrics(ctx.request.group, version, profile.PrometheusLabels)))
565+
wrapper.addProgress(prom.NewProgress(profile, prom.NewMetrics(profile.Name, ctx.request.group, version, profile.PrometheusLabels)))
566566
}
567567

568568
err = wrapper.runProfile()

monitor/prom/backup.go

+1-9
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,7 @@ type BackupMetrics struct {
2727
time *prometheus.GaugeVec
2828
}
2929

30-
func newBackupMetrics(group string, configLabels map[string]string) BackupMetrics {
31-
var labels []string
32-
if group != "" {
33-
labels = []string{groupLabel, profileLabel}
34-
} else {
35-
labels = []string{profileLabel}
36-
}
37-
labels = mergeKeys(labels, configLabels)
38-
30+
func newBackupMetrics(labels []string) BackupMetrics {
3931
backupMetrics := BackupMetrics{
4032
duration: prometheus.NewGaugeVec(prometheus.GaugeOpts{
4133
Namespace: namespace,

monitor/prom/metrics.go

+53-47
Original file line numberDiff line numberDiff line change
@@ -8,38 +8,48 @@ import (
88
"github.com/prometheus/client_golang/prometheus"
99
"github.com/prometheus/client_golang/prometheus/push"
1010
"github.com/prometheus/common/expfmt"
11+
"golang.org/x/exp/maps"
1112
)
1213

13-
const namespace = "resticprofile"
14-
const backup = "backup"
15-
const groupLabel = "group"
16-
const profileLabel = "profile"
17-
const goVersionLabel = "goversion"
18-
const versionLabel = "version"
14+
const (
15+
namespace = "resticprofile"
16+
backup = "backup"
17+
groupLabel = "group"
18+
profileLabel = "profile"
19+
goVersionLabel = "goversion"
20+
versionLabel = "version"
21+
)
1922

2023
type Metrics struct {
21-
group string
22-
configLabels map[string]string
23-
registry *prometheus.Registry
24-
info *prometheus.GaugeVec
25-
backup BackupMetrics
24+
labels prometheus.Labels
25+
registry *prometheus.Registry
26+
info *prometheus.GaugeVec
27+
backup BackupMetrics
2628
}
2729

28-
func NewMetrics(group, version string, configLabels map[string]string) *Metrics {
30+
func NewMetrics(profile, group, version string, configLabels map[string]string) *Metrics {
31+
// default labels for all metrics
32+
labels := prometheus.Labels{profileLabel: profile}
33+
if group != "" {
34+
labels[groupLabel] = group
35+
}
36+
labels = mergeLabels(labels, configLabels)
37+
keys := maps.Keys(labels)
38+
2939
registry := prometheus.NewRegistry()
3040
p := &Metrics{
31-
group: group,
32-
configLabels: configLabels,
33-
registry: registry,
41+
labels: labels,
42+
registry: registry,
3443
}
3544
p.info = prometheus.NewGaugeVec(prometheus.GaugeOpts{
3645
Namespace: namespace,
3746
Name: "build_info",
3847
Help: "resticprofile build information.",
39-
}, mergeKeys([]string{goVersionLabel, versionLabel}, configLabels))
40-
p.info.With(mergeLabels(prometheus.Labels{goVersionLabel: runtime.Version(), versionLabel: version}, configLabels)).Set(1)
48+
}, append(keys, goVersionLabel, versionLabel))
49+
// send the information about the build right away
50+
p.info.With(mergeLabels(cloneLabels(labels), map[string]string{goVersionLabel: runtime.Version(), versionLabel: version})).Set(1)
4151

42-
p.backup = newBackupMetrics(group, configLabels)
52+
p.backup = newBackupMetrics(keys)
4353

4454
registry.MustRegister(
4555
p.info,
@@ -59,34 +69,29 @@ func NewMetrics(group, version string, configLabels map[string]string) *Metrics
5969
return p
6070
}
6171

62-
func (p *Metrics) BackupResults(profile string, status Status, summary monitor.Summary) {
63-
labels := prometheus.Labels{profileLabel: profile}
64-
if p.group != "" {
65-
labels[groupLabel] = p.group
66-
}
67-
labels = mergeLabels(labels, p.configLabels)
68-
p.backup.duration.With(labels).Set(summary.Duration.Seconds())
69-
70-
p.backup.filesNew.With(labels).Set(float64(summary.FilesNew))
71-
p.backup.filesChanged.With(labels).Set(float64(summary.FilesChanged))
72-
p.backup.filesUnmodified.With(labels).Set(float64(summary.FilesUnmodified))
73-
74-
p.backup.dirNew.With(labels).Set(float64(summary.DirsNew))
75-
p.backup.dirChanged.With(labels).Set(float64(summary.DirsChanged))
76-
p.backup.dirUnmodified.With(labels).Set(float64(summary.DirsUnmodified))
77-
78-
p.backup.filesTotal.With(labels).Set(float64(summary.FilesTotal))
79-
p.backup.bytesAdded.With(labels).Set(float64(summary.BytesAdded))
80-
p.backup.bytesTotal.With(labels).Set(float64(summary.BytesTotal))
81-
p.backup.status.With(labels).Set(float64(status))
82-
p.backup.time.With(labels).Set(float64(time.Now().Unix()))
72+
func (p *Metrics) BackupResults(status Status, summary monitor.Summary) {
73+
p.backup.duration.With(p.labels).Set(summary.Duration.Seconds())
74+
75+
p.backup.filesNew.With(p.labels).Set(float64(summary.FilesNew))
76+
p.backup.filesChanged.With(p.labels).Set(float64(summary.FilesChanged))
77+
p.backup.filesUnmodified.With(p.labels).Set(float64(summary.FilesUnmodified))
78+
79+
p.backup.dirNew.With(p.labels).Set(float64(summary.DirsNew))
80+
p.backup.dirChanged.With(p.labels).Set(float64(summary.DirsChanged))
81+
p.backup.dirUnmodified.With(p.labels).Set(float64(summary.DirsUnmodified))
82+
83+
p.backup.filesTotal.With(p.labels).Set(float64(summary.FilesTotal))
84+
p.backup.bytesAdded.With(p.labels).Set(float64(summary.BytesAdded))
85+
p.backup.bytesTotal.With(p.labels).Set(float64(summary.BytesTotal))
86+
p.backup.status.With(p.labels).Set(float64(status))
87+
p.backup.time.With(p.labels).Set(float64(time.Now().Unix()))
8388
}
8489

8590
func (p *Metrics) SaveTo(filename string) error {
8691
return prometheus.WriteToTextfile(filename, p.registry)
8792
}
8893

89-
func (p *Metrics) Push(url, format string, jobName string) error {
94+
func (p *Metrics) Push(url, format, jobName string) error {
9095
var expFmt expfmt.Format
9196

9297
if format == "protobuf" {
@@ -101,16 +106,17 @@ func (p *Metrics) Push(url, format string, jobName string) error {
101106
Add()
102107
}
103108

104-
func mergeKeys(keys []string, add map[string]string) []string {
105-
for key := range add {
106-
keys = append(keys, key)
107-
}
108-
return keys
109-
}
110-
111109
func mergeLabels(labels prometheus.Labels, add map[string]string) prometheus.Labels {
112110
for key, value := range add {
113111
labels[key] = value
114112
}
115113
return labels
116114
}
115+
116+
func cloneLabels(labels prometheus.Labels) prometheus.Labels {
117+
clone := make(prometheus.Labels, len(labels))
118+
for key, value := range labels {
119+
clone[key] = value
120+
}
121+
return clone
122+
}

monitor/prom/metrics_test.go

+9-14
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ import (
99
)
1010

1111
func TestSaveSingleBackup(t *testing.T) {
12-
p := NewMetrics("", "", nil)
13-
p.BackupResults("test", StatusSuccess, monitor.Summary{
12+
p := NewMetrics("test", "", "", nil)
13+
p.BackupResults(StatusSuccess, monitor.Summary{
1414
Duration: time.Duration(11 * time.Second),
1515
BytesAdded: 100,
1616
BytesTotal: 1000,
@@ -20,8 +20,8 @@ func TestSaveSingleBackup(t *testing.T) {
2020
}
2121

2222
func TestSaveSingleBackupWithConfigLabel(t *testing.T) {
23-
p := NewMetrics("", "", map[string]string{"test_label": "test_value"})
24-
p.BackupResults("test", StatusSuccess, monitor.Summary{
23+
p := NewMetrics("test", "", "", map[string]string{"test_label": "test_value"})
24+
p.BackupResults(StatusSuccess, monitor.Summary{
2525
Duration: time.Duration(11 * time.Second),
2626
BytesAdded: 100,
2727
BytesTotal: 1000,
@@ -30,17 +30,12 @@ func TestSaveSingleBackupWithConfigLabel(t *testing.T) {
3030
require.NoError(t, err)
3131
}
3232

33-
func TestSaveBackupsInGroup(t *testing.T) {
34-
p := NewMetrics("full-backup", "", nil)
35-
p.BackupResults("test1", StatusSuccess, monitor.Summary{
33+
func TestSaveBackupGroup(t *testing.T) {
34+
p := NewMetrics("test", "group", "", nil)
35+
p.BackupResults(StatusSuccess, monitor.Summary{
3636
Duration: time.Duration(11 * time.Second),
37-
BytesAdded: 1001,
38-
BytesTotal: 10001,
39-
})
40-
p.BackupResults("test2", StatusSuccess, monitor.Summary{
41-
Duration: time.Duration(12 * time.Second),
42-
BytesAdded: 1002,
43-
BytesTotal: 10002,
37+
BytesAdded: 100,
38+
BytesTotal: 1000,
4439
})
4540
err := p.SaveTo("test_group.prom")
4641
require.NoError(t, err)

monitor/prom/progress.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ func (p *Progress) Summary(command string, summary monitor.Summary, stderr strin
3535
if p.profile.PrometheusPush == "" && p.profile.PrometheusSaveToFile == "" {
3636
return
3737
}
38+
if command != constants.CommandBackup {
39+
return
40+
}
3841
var status Status
3942
switch {
4043
case monitor.IsSuccess(result):
@@ -46,10 +49,7 @@ func (p *Progress) Summary(command string, summary monitor.Summary, stderr strin
4649
case monitor.IsError(result):
4750
status = StatusFailed
4851
}
49-
if command != constants.CommandBackup {
50-
return
51-
}
52-
p.metrics.BackupResults(p.profile.Name, status, summary)
52+
p.metrics.BackupResults(status, summary)
5353

5454
if p.profile.PrometheusSaveToFile != "" {
5555
err := p.metrics.SaveTo(p.profile.PrometheusSaveToFile)

0 commit comments

Comments
 (0)