Skip to content

Commit 7d12fc4

Browse files
skoya76ushitora-anqoullamerada-jp
committed
Renew metrics
This commit add following metrics. - mantle_backup_duration_seconds_total - mantle_mantlebackupconfig_info - mantle_backup_duration_seconds_bucket - mantle_backup_duration_seconds_sum - mantle_backup_duration_seconds_count Signed-off-by: Kohya Shiozaki <kouyan120706@gmail.com> Co-authored-by: Ryotaro Banno <ryotaro.banno@gmail.com> Co-authored-by: Yuji Ito <llamerada.jp@gmail.com>
1 parent 1e90066 commit 7d12fc4

7 files changed

Lines changed: 159 additions & 46 deletions

File tree

README.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,35 @@ make uninstall
7171
make undeploy
7272
```
7373

74+
## Prometheus metrics
75+
76+
### `mantle_backup_duration_seconds_total`
77+
78+
`mantle_backup_duration_seconds_total` is a Counter that indicates the time from the creationTimestamp to the completion of the backup.
79+
80+
| Label | Description |
81+
| ----------------------- | ----------------------- |
82+
| `persistentvolumeclaim` | The PVC name. |
83+
| `resource_namespace` | The resource namespace. |
84+
85+
### `mantle_mantlebackupconfig_info`
86+
87+
`mantle_mantlebackupconfig_info` is a Gauge that indicates information about the backup configuration.
88+
89+
| Label | Description |
90+
| ----------------------- | ----------------------- |
91+
| `persistentvolumeclaim` | The PVC name. |
92+
| `resource_namespace` | The resource namespace. |
93+
94+
### `mantle_backup_duration_seconds`
95+
96+
`mantle_backup_duration_seconds` is a Histogram that indicates the time from the creationTimestamp to the completion of the backup.
97+
98+
| Label | Description |
99+
| ----------------------- | ----------------------- |
100+
| `persistentvolumeclaim` | The PVC name. |
101+
| `resource_namespace` | The resource namespace. |
102+
74103
## Development
75104

76105
The following tools should be installed manually.

internal/controller/mantlebackup_controller.go

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import (
1515
_ "embed"
1616

1717
mantlev1 "github.com/cybozu-go/mantle/api/v1"
18-
"github.com/cybozu-go/mantle/cmd/backup"
1918
"github.com/cybozu-go/mantle/internal/ceph"
2019
"github.com/cybozu-go/mantle/internal/controller/internal/objectstorage"
2120
"github.com/cybozu-go/mantle/internal/controller/metrics"
@@ -2446,19 +2445,15 @@ func (r *MantleBackupReconciler) primaryCleanup(
24462445
}
24472446

24482447
duration := time.Since(target.GetCreationTimestamp().Time).Seconds()
2449-
source := "none"
2450-
if _, ok := target.GetLabels()[backup.MantleBackupConfigUID]; ok {
2451-
source = "mantle-backup-config"
2452-
}
2453-
metrics.BackupCreationDuration.
2454-
With(prometheus.Labels{
2455-
"cluster_namespace": r.managedCephClusterID,
2456-
// PVC is located in the same namespace as the MantleBackup.
2457-
"pvc_namespace": target.GetNamespace(),
2458-
"pvc": target.Spec.PVC,
2459-
"source": source,
2460-
}).
2461-
Observe(duration)
2448+
metrics.BackupDurationSecondsTotal.With(prometheus.Labels{
2449+
"persistentvolumeclaim": target.Spec.PVC,
2450+
"resource_namespace": target.GetNamespace(),
2451+
}).Add(float64(duration))
2452+
2453+
metrics.BackupDurationSeconds.With(prometheus.Labels{
2454+
"persistentvolumeclaim": target.Spec.PVC,
2455+
"resource_namespace": target.GetNamespace(),
2456+
}).Observe(duration)
24622457

24632458
return ctrl.Result{}, nil
24642459
}

internal/controller/mantlebackupconfig_controller.go

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,17 @@ import (
1919
"sigs.k8s.io/controller-runtime/pkg/reconcile"
2020

2121
mantlev1 "github.com/cybozu-go/mantle/api/v1"
22+
"github.com/cybozu-go/mantle/internal/controller/metrics"
23+
"github.com/prometheus/client_golang/prometheus"
2224
batchv1 "k8s.io/api/batch/v1"
2325
corev1 "k8s.io/api/core/v1"
2426
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2527
)
2628

2729
const (
28-
MantleBackupConfigFinalizerName = "mantlebackupconfig.mantle.cybozu.io/finalizer"
29-
MantleBackupConfigCronJobNamePrefix = "mbc-"
30+
MantleBackupConfigFinalizerName = "mantlebackupconfig.mantle.cybozu.io/finalizer"
31+
MantleBackupConfigAnnotationManagedClusterID = "mantlebackupconfig.mantle.cybozu.io/managed-cluster-id"
32+
MantleBackupConfigCronJobNamePrefix = "mbc-"
3033
)
3134

3235
// MantleBackupConfigReconciler reconciles a MantleBackupConfig object
@@ -88,7 +91,14 @@ func (r *MantleBackupConfigReconciler) Reconcile(ctx context.Context, req ctrl.R
8891

8992
// When the deletionTimestamp is set, remove the finalizer and finish reconciling.
9093
if !mbc.DeletionTimestamp.IsZero() {
91-
if controllerutil.ContainsFinalizer(&mbc, MantleBackupConfigFinalizerName) {
94+
if controllerutil.ContainsFinalizer(&mbc, MantleBackupConfigFinalizerName) &&
95+
mbc.Annotations[MantleBackupConfigAnnotationManagedClusterID] == r.managedCephClusterID {
96+
_ = metrics.BackupConfigInfo.Delete(prometheus.Labels{
97+
"persistentvolumeclaim": mbc.Spec.PVC,
98+
"resource_namespace": mbc.Namespace,
99+
"mantlebackupconfig": mbc.Name,
100+
})
101+
92102
// Delete the CronJob. If we failed to delete it because it's not found, ignore the error.
93103
logger.Info("start deleting cronjobs")
94104
if err := r.deleteCronJob(ctx, &mbc, cronJobInfo.namespace); err != nil && !errors.IsNotFound(err) {
@@ -119,12 +129,24 @@ func (r *MantleBackupConfigReconciler) Reconcile(ctx context.Context, req ctrl.R
119129

120130
// Set the finalizer if it's not yet set.
121131
if !controllerutil.ContainsFinalizer(&mbc, MantleBackupConfigFinalizerName) {
132+
if mbc.Annotations == nil {
133+
mbc.Annotations = make(map[string]string)
134+
}
135+
mbc.Annotations[MantleBackupConfigAnnotationManagedClusterID] = r.managedCephClusterID
136+
122137
controllerutil.AddFinalizer(&mbc, MantleBackupConfigFinalizerName)
123138
if err := r.Client.Update(ctx, &mbc); err != nil {
124139
return ctrl.Result{}, fmt.Errorf("failed to add mbc finalizer: %w", err)
125140
}
126141
}
127142

143+
// Export metrics.
144+
metrics.BackupConfigInfo.With(prometheus.Labels{
145+
"persistentvolumeclaim": mbc.Spec.PVC,
146+
"resource_namespace": mbc.ObjectMeta.Namespace,
147+
"mantlebackupconfig": mbc.ObjectMeta.Name,
148+
}).Set(1)
149+
128150
// Create or update the CronJob
129151
if err := r.createOrUpdateCronJob(
130152
ctx,

internal/controller/metrics/metrics.go

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,46 @@ import (
55
runtimemetrics "sigs.k8s.io/controller-runtime/pkg/metrics"
66
)
77

8-
const subsystem = "mantle"
8+
const namespace = "mantle"
99

1010
var (
11-
BackupCreationDuration = prometheus.NewHistogramVec(
11+
BackupDurationSecondsTotal = prometheus.NewCounterVec(
12+
prometheus.CounterOpts{
13+
Namespace: namespace,
14+
Name: "backup_duration_seconds_total",
15+
Help: "The time from the creationTimestamp to the completion of the backup.",
16+
},
17+
[]string{"persistentvolumeclaim", "resource_namespace"},
18+
)
19+
20+
BackupConfigInfo = prometheus.NewGaugeVec(
21+
prometheus.GaugeOpts{
22+
Namespace: namespace,
23+
Name: "mantlebackupconfig_info",
24+
Help: "Information about the backup configuration.",
25+
},
26+
[]string{"persistentvolumeclaim", "resource_namespace", "mantlebackupconfig"},
27+
)
28+
29+
BackupDurationSeconds = prometheus.NewHistogramVec(
1230
prometheus.HistogramOpts{
13-
Subsystem: subsystem,
14-
Name: "backup_creation_duration_seconds",
15-
Help: "Duration in seconds of backup creation.",
16-
Buckets: []float64{100, 250, 500, 750, 1_000, 2_500, 5_000, 7_500, 10_000, 25_000, 50_000, 75_000, 100_000, 250_000},
31+
Namespace: namespace,
32+
Name: "backup_duration_seconds",
33+
Help: "The time from the creationTimestamp to the completion of the backup.",
34+
Buckets: []float64{100, 200, 400, 800, 1600, 3200, 9600, 28800, 86400, 259200},
1735
},
18-
[]string{"cluster_namespace", "pvc_namespace", "pvc", "source"},
36+
[]string{"persistentvolumeclaim", "resource_namespace"},
1937
)
2038
)
2139

2240
func init() {
23-
runtimemetrics.Registry.MustRegister(BackupCreationDuration)
41+
metricsToRegister := []prometheus.Collector{
42+
BackupDurationSecondsTotal,
43+
BackupConfigInfo,
44+
BackupDurationSeconds,
45+
}
46+
47+
for _, metric := range metricsToRegister {
48+
runtimemetrics.Registry.MustRegister(metric)
49+
}
2450
}

test/e2e/multik8s/misc_test.go

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,39 @@ import (
1414
"k8s.io/apimachinery/pkg/api/meta"
1515
)
1616

17+
var _ = Describe("metrics tests", func() {
18+
namespace := util.GetUniqueName("ns-")
19+
pvcName := util.GetUniqueName("pvc-")
20+
backupName := util.GetUniqueName("mb-")
21+
backupConfigName := util.GetUniqueName("mbc-")
22+
23+
It("should setup", func(ctx SpecContext) {
24+
SetupEnvironment(namespace)
25+
CreatePVC(ctx, PrimaryK8sCluster, namespace, pvcName)
26+
CreateMantleBackup(PrimaryK8sCluster, namespace, pvcName, backupName)
27+
WaitMantleBackupSynced(namespace, backupName)
28+
CreateMantleBackupConfig(PrimaryK8sCluster, namespace, pvcName, backupConfigName)
29+
})
30+
31+
DescribeTable("metrics should be exposed",
32+
func(ctx SpecContext, metricName string) {
33+
Eventually(ctx, func(g Gomega) {
34+
controllerPod, err := GetControllerPodName(PrimaryK8sCluster)
35+
g.Expect(err).NotTo(HaveOccurred())
36+
stdout, _, err := Kubectl(PrimaryK8sCluster, nil, "exec", "-n", CephClusterNamespace, controllerPod, "--",
37+
"curl", "-s", "http://localhost:8080/metrics")
38+
g.Expect(err).NotTo(HaveOccurred())
39+
g.Expect(strings.Contains(string(stdout), metricName)).To(BeTrue())
40+
}).Should(Succeed())
41+
},
42+
Entry(`mantle_backup_duration_seconds_total`, `mantle_backup_duration_seconds_total`),
43+
Entry(`mantle_mantlebackupconfig_info`, `mantle_mantlebackupconfig_info`),
44+
Entry(`mantle_backup_duration_seconds_bucket`, `mantle_backup_duration_seconds_bucket`),
45+
Entry(`mantle_backup_duration_seconds_sum`, `mantle_backup_duration_seconds_sum`),
46+
Entry(`mantle_backup_duration_seconds_count`, `mantle_backup_duration_seconds_count`),
47+
)
48+
})
49+
1750
var _ = Describe("miscellaneous tests", func() {
1851
It("should succeed to back up if backup-transfer-part-size is changed during uploading", func(ctx SpecContext) {
1952
namespace := util.GetUniqueName("ns-")
@@ -348,25 +381,4 @@ spec:
348381
0, // reset an import Job to the original one to revive the Job.
349382
),
350383
)
351-
352-
It("should get metrics from the controller pod in the primary cluster", func(ctx SpecContext) {
353-
metrics := []string{
354-
`mantle_backup_creation_duration_seconds_count`,
355-
`mantle_backup_creation_duration_seconds_sum`,
356-
}
357-
ensureMetricsAreExposed(metrics)
358-
})
359384
})
360-
361-
func ensureMetricsAreExposed(metrics []string) {
362-
GinkgoHelper()
363-
controllerPod, err := GetControllerPodName(PrimaryK8sCluster)
364-
Expect(err).NotTo(HaveOccurred())
365-
366-
stdout, _, err := Kubectl(PrimaryK8sCluster, nil, "exec", "-n", CephClusterNamespace, controllerPod, "--",
367-
"curl", "-s", "http://localhost:8080/metrics")
368-
Expect(err).NotTo(HaveOccurred())
369-
for _, metric := range metrics {
370-
Expect(strings.Contains(string(stdout), metric)).To(BeTrue())
371-
}
372-
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
apiVersion: mantle.cybozu.io/v1
2+
kind: MantleBackupConfig
3+
metadata:
4+
name: %s
5+
namespace: %s
6+
spec:
7+
pvc: %s
8+
expire: "1d"
9+
schedule: "00 00 * * *"
10+
suspend: false

test/e2e/multik8s/testutil/util.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ var (
4646
testRBDPoolSCTemplate string
4747
//go:embed testdata/mantlebackup-template.yaml
4848
testMantleBackupTemplate string
49+
//go:embed testdata/mantlebackupconfig-template.yaml
50+
testMantleBackupConfigTemplate string
4951
//go:embed testdata/mantlerestore-template.yaml
5052
testMantleRestoreTemplate string
5153
//go:embed testdata/mount-deploy-template.yaml
@@ -137,6 +139,15 @@ func ApplyMantleBackupTemplate(clusterNo int, namespace, pvcName, backupName str
137139
return nil
138140
}
139141

142+
func ApplyMantleBackupConfigTemplate(clusterNo int, namespace, pvcName, backupConfigName string) error {
143+
manifest := fmt.Sprintf(testMantleBackupConfigTemplate, backupConfigName, namespace, pvcName)
144+
_, _, err := Kubectl(clusterNo, []byte(manifest), "apply", "-f", "-")
145+
if err != nil {
146+
return fmt.Errorf("kubectl apply mantlebackupconfig failed. err: %w", err)
147+
}
148+
return nil
149+
}
150+
140151
func ApplyMantleRestoreTemplate(clusterNo int, namespace, restoreName, backupName string) error {
141152
manifest := fmt.Sprintf(testMantleRestoreTemplate, restoreName, restoreName, namespace, backupName)
142153
_, _, err := Kubectl(clusterNo, []byte(manifest), "apply", "-f", "-")
@@ -487,6 +498,14 @@ func CreateMantleBackup(cluster int, namespace, pvcName, backupName string) {
487498
}).Should(Succeed())
488499
}
489500

501+
func CreateMantleBackupConfig(cluster int, namespace, pvcName, backupConfigName string) {
502+
GinkgoHelper()
503+
By("creating a MantleBackupConfig object")
504+
Eventually(func() error {
505+
return ApplyMantleBackupConfigTemplate(cluster, namespace, pvcName, backupConfigName)
506+
}).Should(Succeed())
507+
}
508+
490509
func WaitMantleBackupReadyToUse(cluster int, namespace, backupName string) {
491510
GinkgoHelper()
492511
By("checking MantleBackup's ReadyToUse status")

0 commit comments

Comments
 (0)