From edb1428248ff54660eb2519f6b2a101452eb8367 Mon Sep 17 00:00:00 2001 From: Anton Nikiforov Date: Fri, 9 Dec 2022 16:52:13 +0300 Subject: [PATCH] [#2022] Add metric `readonly` to get shards mode Signed-off-by: Anton Nikiforov --- CHANGELOG.md | 1 + pkg/local_object_storage/engine/metrics.go | 2 ++ pkg/local_object_storage/engine/shards.go | 8 ++++++ .../shard/metrics_test.go | 20 ++++++++++++-- pkg/local_object_storage/shard/mode.go | 3 +++ pkg/local_object_storage/shard/shard.go | 2 ++ pkg/metrics/object.go | 26 ++++++++++++++++++- 7 files changed, 59 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index abf1aa01f0..303f17a229 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ Changelog for NeoFS Node - Fix NNS hash parsing in morph client (#2063) - `neofs-cli neofs-cli acl basic/extended print` commands (#2012) - `neofs_node_object_*_req_count_success` prometheus metrics for tracking successfully executed requests (#1984) +- Metric 'readonly' to get shards mode (#2022) ### Changed - `object lock` command reads CID and OID the same way other commands do (#1971) diff --git a/pkg/local_object_storage/engine/metrics.go b/pkg/local_object_storage/engine/metrics.go index f9bb67d072..f2f16c631e 100644 --- a/pkg/local_object_storage/engine/metrics.go +++ b/pkg/local_object_storage/engine/metrics.go @@ -19,6 +19,8 @@ type MetricRegister interface { SetObjectCounter(shardID, objectType string, v uint64) AddToObjectCounter(shardID, objectType string, delta int) + + SetReadonly(shardID string, readonly bool) } func elapsed(addFunc func(d time.Duration)) func() { diff --git a/pkg/local_object_storage/engine/shards.go b/pkg/local_object_storage/engine/shards.go index e0510e359c..b6bb4201a5 100644 --- a/pkg/local_object_storage/engine/shards.go +++ b/pkg/local_object_storage/engine/shards.go @@ -45,6 +45,10 @@ func (m *metricsWithID) DecObjectCounter(objectType string) { m.mw.AddToObjectCounter(m.id, objectType, -1) } +func (m *metricsWithID) SetReadonly(readonly bool) { + m.mw.SetReadonly(m.id, readonly) +} + // AddShard adds a new shard to the storage engine. // // Returns any error encountered that did not allow adding a shard. @@ -60,6 +64,10 @@ func (e *StorageEngine) AddShard(opts ...shard.Option) (*shard.ID, error) { return nil, fmt.Errorf("could not add %s shard: %w", sh.ID().String(), err) } + if e.cfg.metrics != nil { + e.cfg.metrics.SetReadonly(sh.ID().String(), sh.GetMode() != mode.ReadWrite) + } + return sh.ID(), nil } diff --git a/pkg/local_object_storage/shard/metrics_test.go b/pkg/local_object_storage/shard/metrics_test.go index 72db4d99ee..9500da5f47 100644 --- a/pkg/local_object_storage/shard/metrics_test.go +++ b/pkg/local_object_storage/shard/metrics_test.go @@ -10,6 +10,7 @@ import ( meta "github.com/TrueCloudLab/frostfs-node/pkg/local_object_storage/metabase" "github.com/TrueCloudLab/frostfs-node/pkg/local_object_storage/pilorama" "github.com/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard" + "github.com/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode" "github.com/TrueCloudLab/frostfs-sdk-go/object" oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id" "github.com/stretchr/testify/require" @@ -50,13 +51,27 @@ func (m metricsStore) DecObjectCounter(objectType string) { m.AddToObjectCounter(objectType, -1) } +func (m metricsStore) SetReadonly(r bool) { + if r { + m.s[readonly] = 1 + } else { + m.s[readonly] = 0 + } +} + const physical = "phy" const logical = "logic" +const readonly = "readonly" func TestCounters(t *testing.T) { dir := t.TempDir() sh, mm := shardWithMetrics(t, dir) + sh.SetMode(mode.ReadOnly) + require.Equal(t, mm.s[readonly], uint64(1)) + sh.SetMode(mode.ReadWrite) + require.Equal(t, mm.s[readonly], uint64(0)) + const objNumber = 10 oo := make([]*object.Object, objNumber) for i := 0; i < objNumber; i++ { @@ -149,8 +164,9 @@ func shardWithMetrics(t *testing.T, path string) (*shard.Shard, *metricsStore) { mm := &metricsStore{ s: map[string]uint64{ - "phy": 0, - "logic": 0, + "phy": 0, + "logic": 0, + "readonly": 1, }, } diff --git a/pkg/local_object_storage/shard/mode.go b/pkg/local_object_storage/shard/mode.go index 426ed3b064..4f45136313 100644 --- a/pkg/local_object_storage/shard/mode.go +++ b/pkg/local_object_storage/shard/mode.go @@ -57,6 +57,9 @@ func (s *Shard) setMode(m mode.Mode) error { } s.info.Mode = m + if s.metricsWriter != nil { + s.metricsWriter.SetReadonly(s.info.Mode != mode.ReadWrite) + } return nil } diff --git a/pkg/local_object_storage/shard/shard.go b/pkg/local_object_storage/shard/shard.go index c7a67a8faf..921a4221e7 100644 --- a/pkg/local_object_storage/shard/shard.go +++ b/pkg/local_object_storage/shard/shard.go @@ -62,6 +62,8 @@ type MetricsWriter interface { // SetShardID must set (update) the shard identifier that will be used in // metrics. SetShardID(id string) + // SetReadonly must set shard readonly state. + SetReadonly(readonly bool) } type cfg struct { diff --git a/pkg/metrics/object.go b/pkg/metrics/object.go index f8cecd17cd..bb8f6c261c 100644 --- a/pkg/metrics/object.go +++ b/pkg/metrics/object.go @@ -35,7 +35,8 @@ type ( putPayload prometheus.Counter getPayload prometheus.Counter - shardMetrics *prometheus.GaugeVec + shardMetrics *prometheus.GaugeVec + shardsReadonly *prometheus.GaugeVec } ) @@ -158,6 +159,15 @@ func newObjectServiceMetrics() objectServiceMetrics { }, []string{shardIDLabelKey, counterTypeLabelKey}, ) + + shardsReadonly = prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Namespace: namespace, + Subsystem: objectSubsystem, + Name: "readonly", + Help: "Shard state", + }, + []string{shardIDLabelKey}, + ) ) return objectServiceMetrics{ @@ -178,6 +188,7 @@ func newObjectServiceMetrics() objectServiceMetrics { putPayload: putPayload, getPayload: getPayload, shardMetrics: shardsMetrics, + shardsReadonly: shardsReadonly, } } @@ -202,6 +213,7 @@ func (m objectServiceMetrics) register() { prometheus.MustRegister(m.getPayload) prometheus.MustRegister(m.shardMetrics) + prometheus.MustRegister(m.shardsReadonly) } func (m objectServiceMetrics) IncGetReqCounter(success bool) { @@ -285,3 +297,15 @@ func (m objectServiceMetrics) SetObjectCounter(shardID, objectType string, v uin }, ).Set(float64(v)) } + +func (m objectServiceMetrics) SetReadonly(shardID string, readonly bool) { + var flag float64 + if readonly { + flag = 1 + } + m.shardsReadonly.With( + prometheus.Labels{ + shardIDLabelKey: shardID, + }, + ).Set(flag) +}