Skip to content

Commit 04c35d3

Browse files
PMM-12384 Backup artifact metrics (#2428)
* PMM-12384 Add backup artifact metrics * PMM-12384 Fixes * PMM_12384 Fix * PMM-12384 Remove TODO * PMM-12384 Refactoring * Update managed/data/iatemplates/backup_error.yml
1 parent 6e8cc78 commit 04c35d3

File tree

4 files changed

+129
-0
lines changed

4 files changed

+129
-0
lines changed

dev/mongo-rs-backups/docker-compose.yml

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
networks:
22
pmm_default:
33
name: pmm_default
4+
external: true
45

56
services:
67
mongo1:

managed/cmd/pmm-managed/main.go

+3
Original file line numberDiff line numberDiff line change
@@ -932,6 +932,9 @@ func main() { //nolint:cyclop,maintidx
932932
dbaasClient := dbaas.NewClient(*dbaasControllerAPIAddrF)
933933
compatibilityService := backup.NewCompatibilityService(db, versioner)
934934
backupService := backup.NewService(db, jobsService, agentService, compatibilityService, pbmPITRService)
935+
backupMetricsCollector := backup.NewMetricsCollector(db)
936+
prom.MustRegister(backupMetricsCollector)
937+
935938
schedulerService := scheduler.New(db, backupService)
936939
versionCache := versioncache.New(db, versioner)
937940
emailer := alertmanager.NewEmailer(logrus.WithField("component", "alertmanager-emailer").Logger)
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
templates:
3+
- name: pmm_backup_error
4+
version: 1
5+
summary: Backup failed (Tech preview)
6+
expr: 'pmm_managed_backups_artifacts{status="error"} == bool 1'
7+
for: 1m
8+
severity: error
9+
annotations:
10+
description: |-
11+
Failed to create a backup artifact '{{ $labels.artifact_name}}' on service '{{ $labels.service_id }}'.
12+
summary: Failed to create a backup artifact '{{ $labels.artifact_name}}' on service '{{ $labels.service_id }}'.

managed/services/backup/metrics.go

+113
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
// Copyright (C) 2017 Percona LLC
2+
//
3+
// This program is free software: you can redistribute it and/or modify
4+
// it under the terms of the GNU Affero General Public License as published by
5+
// the Free Software Foundation, either version 3 of the License, or
6+
// (at your option) any later version.
7+
//
8+
// This program is distributed in the hope that it will be useful,
9+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+
// GNU Affero General Public License for more details.
12+
//
13+
// You should have received a copy of the GNU Affero General Public License
14+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
15+
16+
package backup
17+
18+
import (
19+
"context"
20+
"time"
21+
22+
"github.com/pkg/errors"
23+
prom "github.com/prometheus/client_golang/prometheus"
24+
"github.com/sirupsen/logrus"
25+
"gopkg.in/reform.v1"
26+
27+
"github.com/percona/pmm/managed/models"
28+
)
29+
30+
const (
31+
requestTimeout = 3 * time.Second
32+
artifactExists float64 = 1
33+
prometheusNamespace = "pmm_managed"
34+
prometheusSubsystem = "backups"
35+
)
36+
37+
type MetricsCollector struct {
38+
db *reform.DB
39+
l *logrus.Entry
40+
41+
mArtifactsDesc *prom.Desc
42+
}
43+
44+
func NewMetricsCollector(db *reform.DB) *MetricsCollector {
45+
return &MetricsCollector{
46+
db: db,
47+
l: logrus.WithField("component", "backups/metrics"),
48+
mArtifactsDesc: prom.NewDesc(
49+
prom.BuildFQName(prometheusNamespace, prometheusSubsystem, "artifacts"),
50+
"Artifacts",
51+
[]string{
52+
"artifact_id", "artifact_name", "artifact_vendor", "service_id", "service_name",
53+
"type", "db_version", "data_model", "mode", "status",
54+
},
55+
nil),
56+
}
57+
}
58+
59+
func (c *MetricsCollector) Describe(ch chan<- *prom.Desc) {
60+
ch <- c.mArtifactsDesc
61+
}
62+
63+
func (c *MetricsCollector) Collect(ch chan<- prom.Metric) {
64+
ctx, cancelCtx := context.WithTimeout(context.Background(), requestTimeout)
65+
defer cancelCtx()
66+
67+
var artifacts []*models.Artifact
68+
var services map[string]*models.Service
69+
errTx := c.db.InTransactionContext(ctx, nil, func(t *reform.TX) error {
70+
var err error
71+
artifacts, err = models.FindArtifacts(t.Querier, models.ArtifactFilters{})
72+
if err != nil {
73+
return errors.WithStack(err)
74+
}
75+
76+
serviceIDs := make([]string, 0, len(artifacts))
77+
for _, artifact := range artifacts {
78+
serviceIDs = append(serviceIDs, artifact.ServiceID)
79+
}
80+
81+
services, err = models.FindServicesByIDs(t.Querier, serviceIDs)
82+
if err != nil {
83+
return errors.WithStack(err)
84+
}
85+
return nil
86+
})
87+
if errTx != nil {
88+
c.l.Warnf("Failed to get artifacts: %v", errTx)
89+
return
90+
}
91+
92+
for _, artifact := range artifacts {
93+
var serviceName string
94+
if service, ok := services[artifact.ServiceID]; ok {
95+
serviceName = service.ServiceName
96+
}
97+
98+
ch <- prom.MustNewConstMetric(
99+
c.mArtifactsDesc,
100+
prom.GaugeValue,
101+
artifactExists,
102+
artifact.ID,
103+
artifact.Name,
104+
artifact.Vendor,
105+
artifact.ServiceID,
106+
serviceName,
107+
string(artifact.Type),
108+
artifact.DBVersion,
109+
string(artifact.DataModel),
110+
string(artifact.Mode),
111+
string(artifact.Status))
112+
}
113+
}

0 commit comments

Comments
 (0)