@@ -32,6 +32,7 @@ import (
32
32
33
33
crdv1alpha1 "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumegroupsnapshot/v1alpha1"
34
34
crdv1 "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumesnapshot/v1"
35
+ "github.com/kubernetes-csi/external-snapshotter/v8/pkg/metrics"
35
36
"github.com/kubernetes-csi/external-snapshotter/v8/pkg/utils"
36
37
)
37
38
@@ -263,6 +264,14 @@ func (ctrl *csiSnapshotCommonController) deleteGroupSnapshot(groupSnapshot *crdv
263
264
_ = ctrl .snapshotStore .Delete (groupSnapshot )
264
265
klog .V (4 ).Infof ("group snapshot %q deleted" , utils .GroupSnapshotKey (groupSnapshot ))
265
266
267
+ driverName , err := ctrl .getGroupSnapshotDriverName (groupSnapshot )
268
+ if err != nil {
269
+ klog .Errorf ("failed to getGroupSnapshotDriverName while recording metrics for group snapshot %q: %v" , utils .GroupSnapshotKey (groupSnapshot ), err )
270
+ } else {
271
+ deleteOperationKey := metrics .NewOperationKey (metrics .DeleteGroupSnapshotOperationName , groupSnapshot .UID )
272
+ ctrl .metricsManager .RecordMetrics (deleteOperationKey , metrics .NewSnapshotOperationStatus (metrics .SnapshotStatusTypeSuccess ), driverName )
273
+ }
274
+
266
275
groupSnapshotContentName := ""
267
276
if groupSnapshot .Status != nil && groupSnapshot .Status .BoundVolumeGroupSnapshotContentName != nil {
268
277
groupSnapshotContentName = * groupSnapshot .Status .BoundVolumeGroupSnapshotContentName
@@ -376,9 +385,28 @@ func (ctrl *csiSnapshotCommonController) getGroupSnapshotContentFromStore(conten
376
385
func (ctrl * csiSnapshotCommonController ) syncUnreadyGroupSnapshot (groupSnapshot * crdv1alpha1.VolumeGroupSnapshot ) error {
377
386
uniqueGroupSnapshotName := utils .GroupSnapshotKey (groupSnapshot )
378
387
klog .V (5 ).Infof ("syncUnreadyGroupSnapshot %s" , uniqueGroupSnapshotName )
379
- /*
380
- TODO: Add metrics
381
- */
388
+ driverName , err := ctrl .getGroupSnapshotDriverName (groupSnapshot )
389
+ if err != nil {
390
+ klog .Errorf ("failed to getGroupSnapshotDriverName while recording metrics for groupsnapshot %q: %s" , utils .GroupSnapshotKey (groupSnapshot ), err )
391
+ }
392
+
393
+ groupSnapshotProvisionType := metrics .DynamicGroupSnapshotType
394
+ if groupSnapshot .Spec .Source .VolumeGroupSnapshotContentName != nil {
395
+ groupSnapshotProvisionType = metrics .PreProvisionedGroupSnapshotType
396
+ }
397
+
398
+ // Start metrics operations for volumegroupsnapshot
399
+ if ! utils .IsGroupSnapshotCreated (groupSnapshot ) {
400
+ // Only start CreateGroupSnapshot operation if the groupsnapshot has not been cut
401
+ ctrl .metricsManager .OperationStart (
402
+ metrics .NewOperationKey (metrics .CreateGroupSnapshotOperationName , groupSnapshot .UID ),
403
+ metrics .NewOperationValue (driverName , groupSnapshotProvisionType ),
404
+ )
405
+ }
406
+ ctrl .metricsManager .OperationStart (
407
+ metrics .NewOperationKey (metrics .CreateGroupSnapshotAndReadyOperationName , groupSnapshot .UID ),
408
+ metrics .NewOperationValue (driverName , groupSnapshotProvisionType ),
409
+ )
382
410
383
411
// Pre-provisioned snapshot
384
412
if groupSnapshot .Spec .Source .VolumeGroupSnapshotContentName != nil {
@@ -664,12 +692,20 @@ func (ctrl *csiSnapshotCommonController) updateGroupSnapshotStatus(groupSnapshot
664
692
groupSnapshotClone := groupSnapshotObj .DeepCopy ()
665
693
groupSnapshotClone .Status = newStatus
666
694
695
+ // We need to record metrics before updating the status due to a bug causing cache entries after a failed UpdateStatus call.
696
+ // Must meet the following criteria to emit a successful CreateGroupSnapshot status
697
+ // 1. Previous status was nil OR Previous status had a nil CreationTime
698
+ // 2. New status must be non-nil with a non-nil CreationTime
699
+ driverName := groupSnapshotContent .Spec .Driver
700
+ createOperationKey := metrics .NewOperationKey (metrics .CreateGroupSnapshotOperationName , groupSnapshot .UID )
701
+
667
702
// Must meet the following criteria to emit a successful CreateGroupSnapshot status
668
703
// 1. Previous status was nil OR Previous status had a nil CreationTime
669
704
// 2. New status must be non-nil with a non-nil CreationTime
670
705
if ! utils .IsGroupSnapshotCreated (groupSnapshotObj ) && utils .IsGroupSnapshotCreated (groupSnapshotClone ) {
671
706
msg := fmt .Sprintf ("GroupSnapshot %s was successfully created by the CSI driver." , utils .GroupSnapshotKey (groupSnapshot ))
672
707
ctrl .eventRecorder .Event (groupSnapshot , v1 .EventTypeNormal , "GroupSnapshotCreated" , msg )
708
+ ctrl .metricsManager .RecordVolumeGroupSnapshotMetrics (createOperationKey , metrics .NewSnapshotOperationStatus (metrics .SnapshotStatusTypeSuccess ), driverName )
673
709
}
674
710
675
711
// Must meet the following criteria to emit a successful CreateGroupSnapshotAndReady status
@@ -678,6 +714,8 @@ func (ctrl *csiSnapshotCommonController) updateGroupSnapshotStatus(groupSnapshot
678
714
if ! utils .IsGroupSnapshotReady (groupSnapshotObj ) && utils .IsGroupSnapshotReady (groupSnapshotClone ) {
679
715
msg := fmt .Sprintf ("GroupSnapshot %s is ready to use." , utils .GroupSnapshotKey (groupSnapshot ))
680
716
ctrl .eventRecorder .Event (groupSnapshot , v1 .EventTypeNormal , "GroupSnapshotReady" , msg )
717
+ createAndReadyOperation := metrics .NewOperationKey (metrics .CreateGroupSnapshotAndReadyOperationName , groupSnapshot .UID )
718
+ ctrl .metricsManager .RecordMetrics (createAndReadyOperation , metrics .NewSnapshotOperationStatus (metrics .SnapshotStatusTypeSuccess ), driverName )
681
719
}
682
720
683
721
newGroupSnapshotObj , err := ctrl .clientset .GroupsnapshotV1alpha1 ().VolumeGroupSnapshots (groupSnapshotClone .Namespace ).UpdateStatus (context .TODO (), groupSnapshotClone , metav1.UpdateOptions {})
@@ -1126,6 +1164,21 @@ func (ctrl *csiSnapshotCommonController) addGroupSnapshotFinalizer(groupSnapshot
1126
1164
func (ctrl * csiSnapshotCommonController ) processGroupSnapshotWithDeletionTimestamp (groupSnapshot * crdv1alpha1.VolumeGroupSnapshot ) error {
1127
1165
klog .V (5 ).Infof ("processGroupSnapshotWithDeletionTimestamp VolumeGroupSnapshot[%s]: %s" , utils .GroupSnapshotKey (groupSnapshot ), utils .GetGroupSnapshotStatusForLogging (groupSnapshot ))
1128
1166
1167
+ driverName , err := ctrl .getGroupSnapshotDriverName (groupSnapshot )
1168
+ if err != nil {
1169
+ klog .Errorf ("failed to getGroupSnapshotDriverName while recording metrics for group snapshot %q: %v" , utils .GroupSnapshotKey (groupSnapshot ), err )
1170
+ }
1171
+
1172
+ groupSnapshotProvisionType := metrics .DynamicGroupSnapshotType
1173
+ if groupSnapshot .Spec .Source .VolumeGroupSnapshotContentName != nil {
1174
+ groupSnapshotProvisionType = metrics .PreProvisionedGroupSnapshotType
1175
+ }
1176
+
1177
+ // Processing delete, start operation metric
1178
+ deleteOperationKey := metrics .NewOperationKey (metrics .DeleteGroupSnapshotOperationName , groupSnapshot .UID )
1179
+ deleteOperationValue := metrics .NewOperationValue (driverName , groupSnapshotProvisionType )
1180
+ ctrl .metricsManager .OperationStart (deleteOperationKey , deleteOperationValue )
1181
+
1129
1182
var groupSnapshotContentName string
1130
1183
if groupSnapshot .Status != nil && groupSnapshot .Status .BoundVolumeGroupSnapshotContentName != nil {
1131
1184
groupSnapshotContentName = * groupSnapshot .Status .BoundVolumeGroupSnapshotContentName
@@ -1297,3 +1350,42 @@ func (ctrl *csiSnapshotCommonController) removeGroupSnapshotFinalizer(groupSnaps
1297
1350
klog .V (5 ).Infof ("Removed protection finalizer from volume group snapshot %s" , utils .GroupSnapshotKey (groupSnapshot ))
1298
1351
return nil
1299
1352
}
1353
+
1354
+ // getGroupSnapshotDriverName is a helper function to get driver from the VolumeGroupSnapshot.
1355
+ // We try to get the driverName in multiple ways, as snapshot controller metrics depend on the correct driverName.
1356
+ func (ctrl * csiSnapshotCommonController ) getGroupSnapshotDriverName (vgs * crdv1alpha1.VolumeGroupSnapshot ) (string , error ) {
1357
+ klog .V (5 ).Infof ("getSnapshotDriverName: VolumeSnapshot[%s]" , vgs .Name )
1358
+ var driverName string
1359
+
1360
+ // Pre-Provisioned groupsnapshots have contentName as source
1361
+ var contentName string
1362
+ if vgs .Spec .Source .VolumeGroupSnapshotContentName != nil {
1363
+ contentName = * vgs .Spec .Source .VolumeGroupSnapshotContentName
1364
+ }
1365
+
1366
+ // Get Driver name from GroupSnapshotContent if we found a contentName
1367
+ if contentName != "" {
1368
+ content , err := ctrl .groupSnapshotContentLister .Get (contentName )
1369
+ if err != nil {
1370
+ klog .Errorf ("getGroupSnapshotDriverName: failed to get groupSnapshotContent: %v" , contentName )
1371
+ } else {
1372
+ driverName = content .Spec .Driver
1373
+ }
1374
+
1375
+ if driverName != "" {
1376
+ return driverName , nil
1377
+ }
1378
+ }
1379
+
1380
+ // Dynamic groupsnapshots will have a groupsnapshotclass with a driver
1381
+ if vgs .Spec .VolumeGroupSnapshotClassName != nil {
1382
+ class , err := ctrl .getSnapshotClass (* vgs .Spec .VolumeGroupSnapshotClassName )
1383
+ if err != nil {
1384
+ klog .Errorf ("getGroupSnapshotDriverName: failed to get groupsnapshotClass: %v" , * vgs .Spec .VolumeGroupSnapshotClassName )
1385
+ } else {
1386
+ driverName = class .Driver
1387
+ }
1388
+ }
1389
+
1390
+ return driverName , nil
1391
+ }
0 commit comments