Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add prometheus label to build info #319

Merged
merged 2 commits into from
Feb 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions docs/content/status/prometheus/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,43 +89,43 @@ Here's an example of the generated prometheus file:
```
# HELP resticprofile_backup_added_bytes Total number of bytes added to the repository.
# TYPE resticprofile_backup_added_bytes gauge
resticprofile_backup_added_bytes{profile="prom"} 70690
resticprofile_backup_added_bytes{profile="prom"} 9.83610983e+08
# HELP resticprofile_backup_dir_changed Number of directories with changes.
# TYPE resticprofile_backup_dir_changed gauge
resticprofile_backup_dir_changed{profile="prom"} 15
resticprofile_backup_dir_changed{profile="prom"} 0
# HELP resticprofile_backup_dir_new Number of new directories added to the backup.
# TYPE resticprofile_backup_dir_new gauge
resticprofile_backup_dir_new{profile="prom"} 0
resticprofile_backup_dir_new{profile="prom"} 847
# HELP resticprofile_backup_dir_unmodified Number of directories unmodified since last backup.
# TYPE resticprofile_backup_dir_unmodified gauge
resticprofile_backup_dir_unmodified{profile="prom"} 529
resticprofile_backup_dir_unmodified{profile="prom"} 0
# HELP resticprofile_backup_duration_seconds The backup duration (in seconds).
# TYPE resticprofile_backup_duration_seconds gauge
resticprofile_backup_duration_seconds{profile="prom"} 0.879901212
resticprofile_backup_duration_seconds{profile="prom"} 4.453124672
# HELP resticprofile_backup_files_changed Number of files with changes.
# TYPE resticprofile_backup_files_changed gauge
resticprofile_backup_files_changed{profile="prom"} 3
resticprofile_backup_files_changed{profile="prom"} 0
# HELP resticprofile_backup_files_new Number of new files added to the backup.
# TYPE resticprofile_backup_files_new gauge
resticprofile_backup_files_new{profile="prom"} 1
resticprofile_backup_files_new{profile="prom"} 6006
# HELP resticprofile_backup_files_processed Total number of files scanned by the backup for changes.
# TYPE resticprofile_backup_files_processed gauge
resticprofile_backup_files_processed{profile="prom"} 3680
resticprofile_backup_files_processed{profile="prom"} 6006
# HELP resticprofile_backup_files_unmodified Number of files unmodified since last backup.
# TYPE resticprofile_backup_files_unmodified gauge
resticprofile_backup_files_unmodified{profile="prom"} 3676
resticprofile_backup_files_unmodified{profile="prom"} 0
# HELP resticprofile_backup_processed_bytes Total number of bytes scanned for changes.
# TYPE resticprofile_backup_processed_bytes gauge
resticprofile_backup_processed_bytes{profile="prom"} 8.55433765e+08
resticprofile_backup_processed_bytes{profile="prom"} 1.016520315e+09
# HELP resticprofile_backup_status Backup status: 0=fail, 1=warning, 2=success.
# TYPE resticprofile_backup_status gauge
resticprofile_backup_status{profile="prom"} 2
# HELP resticprofile_backup_time_seconds Last backup run (unixtime).
# TYPE resticprofile_backup_time_seconds gauge
resticprofile_backup_time_seconds{profile="prom"} 1.662310865e+09
resticprofile_backup_time_seconds{profile="prom"} 1.707863748e+09
# HELP resticprofile_build_info resticprofile build information.
# TYPE resticprofile_build_info gauge
resticprofile_build_info{goversion="go1.19",version="0.19.0"} 1
resticprofile_build_info{goversion="go1.22.0",profile="prom",version="0.26.0-dev"} 1

```

Expand Down
4 changes: 4 additions & 0 deletions examples/dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -163,10 +163,14 @@ prom:
host: "{{ .Hostname }}"
status-file: /Volumes/RAMDisk/status.json
backup:
check-after: true
extended-status: true
no-error-on-warning: true
source:
- "{{ .CurrentDir }}"
retention:
after-backup: true
keep-last: 30

system:
initialize: true
Expand Down
2 changes: 1 addition & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,7 @@ func runProfile(ctx *Context) error {
wrapper.addProgress(status.NewProgress(profile, status.NewStatus(profile.StatusFile)))
}
if profile.PrometheusPush != "" || profile.PrometheusSaveToFile != "" {
wrapper.addProgress(prom.NewProgress(profile, prom.NewMetrics(ctx.request.group, version, profile.PrometheusLabels)))
wrapper.addProgress(prom.NewProgress(profile, prom.NewMetrics(profile.Name, ctx.request.group, version, profile.PrometheusLabels)))
}

err = wrapper.runProfile()
Expand Down
10 changes: 1 addition & 9 deletions monitor/prom/backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,7 @@ type BackupMetrics struct {
time *prometheus.GaugeVec
}

func newBackupMetrics(group string, configLabels map[string]string) BackupMetrics {
var labels []string
if group != "" {
labels = []string{groupLabel, profileLabel}
} else {
labels = []string{profileLabel}
}
labels = mergeKeys(labels, configLabels)

func newBackupMetrics(labels []string) BackupMetrics {
backupMetrics := BackupMetrics{
duration: prometheus.NewGaugeVec(prometheus.GaugeOpts{
Namespace: namespace,
Expand Down
100 changes: 53 additions & 47 deletions monitor/prom/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,38 +8,48 @@
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/push"
"github.com/prometheus/common/expfmt"
"golang.org/x/exp/maps"
)

const namespace = "resticprofile"
const backup = "backup"
const groupLabel = "group"
const profileLabel = "profile"
const goVersionLabel = "goversion"
const versionLabel = "version"
const (
namespace = "resticprofile"
backup = "backup"
groupLabel = "group"
profileLabel = "profile"
goVersionLabel = "goversion"
versionLabel = "version"
)

type Metrics struct {
group string
configLabels map[string]string
registry *prometheus.Registry
info *prometheus.GaugeVec
backup BackupMetrics
labels prometheus.Labels
registry *prometheus.Registry
info *prometheus.GaugeVec
backup BackupMetrics
}

func NewMetrics(group, version string, configLabels map[string]string) *Metrics {
func NewMetrics(profile, group, version string, configLabels map[string]string) *Metrics {
// default labels for all metrics
labels := prometheus.Labels{profileLabel: profile}
if group != "" {
labels[groupLabel] = group
}
labels = mergeLabels(labels, configLabels)
keys := maps.Keys(labels)

registry := prometheus.NewRegistry()
p := &Metrics{
group: group,
configLabels: configLabels,
registry: registry,
labels: labels,
registry: registry,
}
p.info = prometheus.NewGaugeVec(prometheus.GaugeOpts{
Namespace: namespace,
Name: "build_info",
Help: "resticprofile build information.",
}, mergeKeys([]string{goVersionLabel, versionLabel}, configLabels))
p.info.With(mergeLabels(prometheus.Labels{goVersionLabel: runtime.Version(), versionLabel: version}, configLabels)).Set(1)
}, append(keys, goVersionLabel, versionLabel))
// send the information about the build right away
p.info.With(mergeLabels(cloneLabels(labels), map[string]string{goVersionLabel: runtime.Version(), versionLabel: version})).Set(1)

p.backup = newBackupMetrics(group, configLabels)
p.backup = newBackupMetrics(keys)

registry.MustRegister(
p.info,
Expand All @@ -59,34 +69,29 @@
return p
}

func (p *Metrics) BackupResults(profile string, status Status, summary monitor.Summary) {
labels := prometheus.Labels{profileLabel: profile}
if p.group != "" {
labels[groupLabel] = p.group
}
labels = mergeLabels(labels, p.configLabels)
p.backup.duration.With(labels).Set(summary.Duration.Seconds())

p.backup.filesNew.With(labels).Set(float64(summary.FilesNew))
p.backup.filesChanged.With(labels).Set(float64(summary.FilesChanged))
p.backup.filesUnmodified.With(labels).Set(float64(summary.FilesUnmodified))

p.backup.dirNew.With(labels).Set(float64(summary.DirsNew))
p.backup.dirChanged.With(labels).Set(float64(summary.DirsChanged))
p.backup.dirUnmodified.With(labels).Set(float64(summary.DirsUnmodified))

p.backup.filesTotal.With(labels).Set(float64(summary.FilesTotal))
p.backup.bytesAdded.With(labels).Set(float64(summary.BytesAdded))
p.backup.bytesTotal.With(labels).Set(float64(summary.BytesTotal))
p.backup.status.With(labels).Set(float64(status))
p.backup.time.With(labels).Set(float64(time.Now().Unix()))
func (p *Metrics) BackupResults(status Status, summary monitor.Summary) {
p.backup.duration.With(p.labels).Set(summary.Duration.Seconds())

p.backup.filesNew.With(p.labels).Set(float64(summary.FilesNew))
p.backup.filesChanged.With(p.labels).Set(float64(summary.FilesChanged))
p.backup.filesUnmodified.With(p.labels).Set(float64(summary.FilesUnmodified))

p.backup.dirNew.With(p.labels).Set(float64(summary.DirsNew))
p.backup.dirChanged.With(p.labels).Set(float64(summary.DirsChanged))
p.backup.dirUnmodified.With(p.labels).Set(float64(summary.DirsUnmodified))

p.backup.filesTotal.With(p.labels).Set(float64(summary.FilesTotal))
p.backup.bytesAdded.With(p.labels).Set(float64(summary.BytesAdded))
p.backup.bytesTotal.With(p.labels).Set(float64(summary.BytesTotal))
p.backup.status.With(p.labels).Set(float64(status))
p.backup.time.With(p.labels).Set(float64(time.Now().Unix()))
}

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

func (p *Metrics) Push(url, format string, jobName string) error {
func (p *Metrics) Push(url, format, jobName string) error {

Check warning on line 94 in monitor/prom/metrics.go

View check run for this annotation

Codecov / codecov/patch

monitor/prom/metrics.go#L94

Added line #L94 was not covered by tests
var expFmt expfmt.Format

if format == "protobuf" {
Expand All @@ -101,16 +106,17 @@
Add()
}

func mergeKeys(keys []string, add map[string]string) []string {
for key := range add {
keys = append(keys, key)
}
return keys
}

func mergeLabels(labels prometheus.Labels, add map[string]string) prometheus.Labels {
for key, value := range add {
labels[key] = value
}
return labels
}

func cloneLabels(labels prometheus.Labels) prometheus.Labels {
clone := make(prometheus.Labels, len(labels))
for key, value := range labels {
clone[key] = value
}
return clone
}
23 changes: 9 additions & 14 deletions monitor/prom/metrics_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import (
)

func TestSaveSingleBackup(t *testing.T) {
p := NewMetrics("", "", nil)
p.BackupResults("test", StatusSuccess, monitor.Summary{
p := NewMetrics("test", "", "", nil)
p.BackupResults(StatusSuccess, monitor.Summary{
Duration: time.Duration(11 * time.Second),
BytesAdded: 100,
BytesTotal: 1000,
Expand All @@ -20,8 +20,8 @@ func TestSaveSingleBackup(t *testing.T) {
}

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

func TestSaveBackupsInGroup(t *testing.T) {
p := NewMetrics("full-backup", "", nil)
p.BackupResults("test1", StatusSuccess, monitor.Summary{
func TestSaveBackupGroup(t *testing.T) {
p := NewMetrics("test", "group", "", nil)
p.BackupResults(StatusSuccess, monitor.Summary{
Duration: time.Duration(11 * time.Second),
BytesAdded: 1001,
BytesTotal: 10001,
})
p.BackupResults("test2", StatusSuccess, monitor.Summary{
Duration: time.Duration(12 * time.Second),
BytesAdded: 1002,
BytesTotal: 10002,
BytesAdded: 100,
BytesTotal: 1000,
})
err := p.SaveTo("test_group.prom")
require.NoError(t, err)
Expand Down
8 changes: 4 additions & 4 deletions monitor/prom/progress.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@
if p.profile.PrometheusPush == "" && p.profile.PrometheusSaveToFile == "" {
return
}
if command != constants.CommandBackup {
return
}

Check warning on line 40 in monitor/prom/progress.go

View check run for this annotation

Codecov / codecov/patch

monitor/prom/progress.go#L38-L40

Added lines #L38 - L40 were not covered by tests
var status Status
switch {
case monitor.IsSuccess(result):
Expand All @@ -46,10 +49,7 @@
case monitor.IsError(result):
status = StatusFailed
}
if command != constants.CommandBackup {
return
}
p.metrics.BackupResults(p.profile.Name, status, summary)
p.metrics.BackupResults(status, summary)

Check warning on line 52 in monitor/prom/progress.go

View check run for this annotation

Codecov / codecov/patch

monitor/prom/progress.go#L52

Added line #L52 was not covered by tests

if p.profile.PrometheusSaveToFile != "" {
err := p.metrics.SaveTo(p.profile.PrometheusSaveToFile)
Expand Down
Loading