Skip to content

Commit f4cee98

Browse files
ChanYiLinc3y1huang
authored andcommitted
feat(metrics): add volume filesystem read only state metrics
ref: longhorn/longhorn 8508 Signed-off-by: Jack Lin <[email protected]>
1 parent 86a4416 commit f4cee98

File tree

3 files changed

+55
-24
lines changed

3 files changed

+55
-24
lines changed

controller/volume_controller.go

+4-19
Original file line numberDiff line numberDiff line change
@@ -1491,25 +1491,10 @@ func (c *VolumeController) requestRemountIfFileSystemReadOnly(v *longhorn.Volume
14911491
if v.Status.State == longhorn.VolumeStateAttached && e.Status.CurrentState == longhorn.InstanceStateRunning {
14921492
fileSystemReadOnlyCondition := types.GetCondition(e.Status.Conditions, imtypes.EngineConditionFilesystemReadOnly)
14931493

1494-
isPVMountOptionReadOnly := false
1495-
kubeStatus := v.Status.KubernetesStatus
1496-
if kubeStatus.PVName != "" {
1497-
pv, err := c.ds.GetPersistentVolumeRO(kubeStatus.PVName)
1498-
if err != nil {
1499-
if apierrors.IsNotFound(err) {
1500-
return
1501-
}
1502-
log.WithError(err).Warnf("Failed to get PV when checking the mount option of the volume")
1503-
return
1504-
}
1505-
if pv != nil {
1506-
for _, opt := range pv.Spec.MountOptions {
1507-
if opt == "ro" {
1508-
isPVMountOptionReadOnly = true
1509-
break
1510-
}
1511-
}
1512-
}
1494+
isPVMountOptionReadOnly, err := c.ds.IsPVMountOptionReadOnly(v)
1495+
if err != nil {
1496+
log.WithError(err).Warn("Failed to check if volume's PV mount option is read only")
1497+
return
15131498
}
15141499

15151500
if fileSystemReadOnlyCondition.Status == longhorn.ConditionStatusTrue && !isPVMountOptionReadOnly {

datastore/longhorn.go

+20
Original file line numberDiff line numberDiff line change
@@ -5556,3 +5556,23 @@ func (s *DataStore) GetOneBackingImageReadyNodeDisk(backingImage *longhorn.Backi
55565556

55575557
return nil, "", fmt.Errorf("failed to find one ready backing image %v", backingImage.Name)
55585558
}
5559+
5560+
func (s *DataStore) IsPVMountOptionReadOnly(volume *longhorn.Volume) (bool, error) {
5561+
kubeStatus := volume.Status.KubernetesStatus
5562+
if kubeStatus.PVName == "" {
5563+
return false, nil
5564+
}
5565+
5566+
pv, err := s.GetPersistentVolumeRO(kubeStatus.PVName)
5567+
if err != nil {
5568+
return false, err
5569+
}
5570+
if pv != nil {
5571+
for _, opt := range pv.Spec.MountOptions {
5572+
if opt == "ro" {
5573+
return true, nil
5574+
}
5575+
}
5576+
}
5577+
return false, nil
5578+
}

metrics_collector/volume_collector.go

+31-5
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@ package metricscollector
22

33
import (
44
"github.com/pkg/errors"
5+
"github.com/prometheus/client_golang/prometheus"
56
"github.com/sirupsen/logrus"
67

7-
"github.com/prometheus/client_golang/prometheus"
8+
imtypes "github.com/longhorn/longhorn-instance-manager/pkg/types"
89

910
"github.com/longhorn/longhorn-manager/controller"
1011
"github.com/longhorn/longhorn-manager/datastore"
1112
"github.com/longhorn/longhorn-manager/engineapi"
13+
"github.com/longhorn/longhorn-manager/types"
1214
"github.com/longhorn/longhorn-manager/util"
1315

1416
longhorn "github.com/longhorn/longhorn-manager/k8s/pkg/apis/longhorn/v1beta2"
@@ -19,10 +21,11 @@ type VolumeCollector struct {
1921

2022
proxyConnCounter util.Counter
2123

22-
capacityMetric metricInfo
23-
sizeMetric metricInfo
24-
stateMetric metricInfo
25-
robustnessMetric metricInfo
24+
capacityMetric metricInfo
25+
sizeMetric metricInfo
26+
stateMetric metricInfo
27+
robustnessMetric metricInfo
28+
fileSystemReadOnlyMetric metricInfo
2629

2730
volumePerfMetrics
2831
}
@@ -48,6 +51,16 @@ func NewVolumeCollector(
4851
proxyConnCounter: util.NewAtomicCounter(),
4952
}
5053

54+
vc.fileSystemReadOnlyMetric = metricInfo{
55+
Desc: prometheus.NewDesc(
56+
prometheus.BuildFQName(longhornName, subsystemVolume, "file_system_read_only"),
57+
"Volume whose mount point is in read-only mode",
58+
[]string{nodeLabel, volumeLabel, pvcLabel, pvcNamespaceLabel},
59+
nil,
60+
),
61+
Type: prometheus.GaugeValue,
62+
}
63+
5164
vc.capacityMetric = metricInfo{
5265
Desc: prometheus.NewDesc(
5366
prometheus.BuildFQName(longhornName, subsystemVolume, "capacity_bytes"),
@@ -156,6 +169,7 @@ func (vc *VolumeCollector) Describe(ch chan<- *prometheus.Desc) {
156169
ch <- vc.sizeMetric.Desc
157170
ch <- vc.stateMetric.Desc
158171
ch <- vc.robustnessMetric.Desc
172+
ch <- vc.fileSystemReadOnlyMetric.Desc
159173
}
160174

161175
func (vc *VolumeCollector) Collect(ch chan<- prometheus.Metric) {
@@ -214,6 +228,18 @@ func (vc *VolumeCollector) collectMetrics(ch chan<- prometheus.Metric, v *longho
214228
ch <- prometheus.MustNewConstMetric(vc.volumePerfMetrics.iopsMetrics.write.Desc, vc.volumePerfMetrics.iopsMetrics.write.Type, float64(vc.getVolumeWriteIOPS(metrics)), vc.currentNodeID, v.Name, v.Status.KubernetesStatus.PVCName, v.Status.KubernetesStatus.Namespace)
215229
ch <- prometheus.MustNewConstMetric(vc.volumePerfMetrics.latencyMetrics.read.Desc, vc.volumePerfMetrics.latencyMetrics.read.Type, float64(vc.getVolumeReadLatency(metrics)), vc.currentNodeID, v.Name, v.Status.KubernetesStatus.PVCName, v.Status.KubernetesStatus.Namespace)
216230
ch <- prometheus.MustNewConstMetric(vc.volumePerfMetrics.latencyMetrics.write.Desc, vc.volumePerfMetrics.latencyMetrics.write.Type, float64(vc.getVolumeWriteLatency(metrics)), vc.currentNodeID, v.Name, v.Status.KubernetesStatus.PVCName, v.Status.KubernetesStatus.Namespace)
231+
232+
fileSystemReadOnlyCondition := types.GetCondition(e.Status.Conditions, imtypes.EngineConditionFilesystemReadOnly)
233+
isPVMountOptionReadOnly, err := vc.ds.IsPVMountOptionReadOnly(v)
234+
if err != nil {
235+
vc.logger.WithError(err).Warn("Failed to check if volume's PV mount option is read only during metric collection")
236+
return
237+
}
238+
239+
if fileSystemReadOnlyCondition.Status == longhorn.ConditionStatusTrue && !isPVMountOptionReadOnly {
240+
ch <- prometheus.MustNewConstMetric(vc.fileSystemReadOnlyMetric.Desc, vc.fileSystemReadOnlyMetric.Type, float64(1), vc.currentNodeID, v.Name, v.Status.KubernetesStatus.PVCName, v.Status.KubernetesStatus.Namespace)
241+
}
242+
217243
}
218244

219245
func (vc *VolumeCollector) getEngineClientProxy(engine *longhorn.Engine) (c engineapi.EngineClientProxy, err error) {

0 commit comments

Comments
 (0)