diff --git a/cmd/frostfs-node/config.go b/cmd/frostfs-node/config.go index 0f2db872..1c8c4960 100644 --- a/cmd/frostfs-node/config.go +++ b/cmd/frostfs-node/config.go @@ -805,6 +805,21 @@ func (c *cfg) getShardOpts(shCfg shardCfg) shardOptsWithID { blobstoreOpts = append(blobstoreOpts, blobstor.WithMetrics(lsmetrics.NewBlobstoreMetrics(c.metricsCollector.Blobstore()))) } + mbOptions := []meta.Option{ + meta.WithPath(shCfg.metaCfg.path), + meta.WithPermissions(shCfg.metaCfg.perm), + meta.WithMaxBatchSize(shCfg.metaCfg.maxBatchSize), + meta.WithMaxBatchDelay(shCfg.metaCfg.maxBatchDelay), + meta.WithBoltDBOptions(&bbolt.Options{ + Timeout: 100 * time.Millisecond, + }), + meta.WithLogger(c.log), + meta.WithEpochState(c.cfgNetmap.state), + } + if c.metricsCollector != nil { + mbOptions = append(mbOptions, meta.WithMetrics(lsmetrics.NewMetabaseMetrics(shCfg.metaCfg.path, c.metricsCollector.MetabaseMetrics()))) + } + var sh shardOptsWithID sh.configID = shCfg.id() sh.shOpts = []shard.Option{ @@ -812,18 +827,7 @@ func (c *cfg) getShardOpts(shCfg shardCfg) shardOptsWithID { shard.WithRefillMetabase(shCfg.refillMetabase), shard.WithMode(shCfg.mode), shard.WithBlobStorOptions(blobstoreOpts...), - shard.WithMetaBaseOptions( - meta.WithPath(shCfg.metaCfg.path), - meta.WithPermissions(shCfg.metaCfg.perm), - meta.WithMaxBatchSize(shCfg.metaCfg.maxBatchSize), - meta.WithMaxBatchDelay(shCfg.metaCfg.maxBatchDelay), - meta.WithBoltDBOptions(&bbolt.Options{ - Timeout: 100 * time.Millisecond, - }), - - meta.WithLogger(c.log), - meta.WithEpochState(c.cfgNetmap.state), - ), + shard.WithMetaBaseOptions(mbOptions...), shard.WithPiloramaOptions(piloramaOpts...), shard.WithWriteCache(shCfg.writecacheCfg.enabled), shard.WithWriteCacheOptions(writeCacheOpts...), diff --git a/pkg/local_object_storage/metabase/db.go b/pkg/local_object_storage/metabase/db.go index 33f27211..e7de46e1 100644 --- a/pkg/local_object_storage/metabase/db.go +++ b/pkg/local_object_storage/metabase/db.go @@ -356,3 +356,10 @@ func WithEpochState(s EpochState) Option { c.epochState = s } } + +// WithMetrics returns option to specify metrics collector. +func WithMetrics(m Metrics) Option { + return func(c *cfg) { + c.metrics = m + } +} diff --git a/pkg/local_object_storage/metrics/metabase.go b/pkg/local_object_storage/metrics/metabase.go new file mode 100644 index 00000000..d0fb3193 --- /dev/null +++ b/pkg/local_object_storage/metrics/metabase.go @@ -0,0 +1,39 @@ +package metrics + +import ( + "time" + + meta "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/metabase" + "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode" + metrics_impl "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/metrics" +) + +func NewMetabaseMetrics(path string, m metrics_impl.MetabaseMetrics) meta.Metrics { + return &metabaseMetrics{ + shardID: undefined, + path: path, + m: m, + } +} + +type metabaseMetrics struct { + shardID string + path string + m metrics_impl.MetabaseMetrics +} + +func (m *metabaseMetrics) SetParentID(parentID string) { + m.shardID = parentID +} + +func (m *metabaseMetrics) SetMode(mode mode.Mode) { + m.m.SetMode(m.shardID, m.path, mode.String()) +} + +func (m *metabaseMetrics) Close() { + m.m.Close(m.shardID, m.path) +} + +func (m *metabaseMetrics) AddMethodDuration(method string, d time.Duration, success bool) { + m.m.MethodDuration(m.shardID, m.path, method, d, success) +} diff --git a/pkg/metrics/consts.go b/pkg/metrics/consts.go index d79e1169..a9781abe 100644 --- a/pkg/metrics/consts.go +++ b/pkg/metrics/consts.go @@ -4,6 +4,7 @@ const ( fstreeSubSystem = "fstree" blobstoreSubSystem = "blobstore" blobovnizaTreeSubSystem = "blobovniza_tree" + metabaseSubSystem = "metabase" successLabel = "success" shardIDLabel = "shardID" diff --git a/pkg/metrics/metabase.go b/pkg/metrics/metabase.go new file mode 100644 index 00000000..640c7f72 --- /dev/null +++ b/pkg/metrics/metabase.go @@ -0,0 +1,54 @@ +package metrics + +import ( + "strconv" + "time" + + "git.frostfs.info/TrueCloudLab/frostfs-observability/metrics" + "github.com/prometheus/client_golang/prometheus" +) + +type MetabaseMetrics interface { + SetMode(shardID, path string, mode string) + Close(shardID, path string) + + MethodDuration(shardID, path string, method string, d time.Duration, success bool) +} + +func newMetabaseMetrics() *metabaseMetrics { + return &metabaseMetrics{ + mode: newShardIDPathMode(metabaseSubSystem, "mode", "Metabase mode"), + reqDuration: metrics.NewHistogramVec(prometheus.HistogramOpts{ + Namespace: namespace, + Subsystem: metabaseSubSystem, + Name: "request_duration_seconds", + Help: "Accumulated Metabase request process duration", + }, []string{shardIDLabel, successLabel, pathLabel, methodLabel}), + } +} + +type metabaseMetrics struct { + mode *shardIDPathModeValue + reqDuration *prometheus.HistogramVec +} + +func (m *metabaseMetrics) SetMode(shardID, path string, mode string) { + m.mode.SetMode(shardID, path, mode) +} + +func (m *metabaseMetrics) Close(shardID, path string) { + m.mode.SetMode(shardID, path, closedMode) + m.reqDuration.DeletePartialMatch(prometheus.Labels{ + shardIDLabel: shardID, + pathLabel: path, + }) +} + +func (m *metabaseMetrics) MethodDuration(shardID, path string, method string, d time.Duration, success bool) { + m.reqDuration.With(prometheus.Labels{ + shardIDLabel: shardID, + pathLabel: path, + successLabel: strconv.FormatBool(success), + methodLabel: method, + }).Observe(d.Seconds()) +} diff --git a/pkg/metrics/node.go b/pkg/metrics/node.go index babd6cdc..e4e98fe1 100644 --- a/pkg/metrics/node.go +++ b/pkg/metrics/node.go @@ -17,6 +17,7 @@ type NodeMetrics struct { fstree *fstreeMetrics blobstore *blobstoreMetrics blobobvnizca *blobovnizca + metabase *metabaseMetrics } func NewNodeMetrics() *NodeMetrics { @@ -35,6 +36,7 @@ func NewNodeMetrics() *NodeMetrics { fstree: newFSTreeMetrics(), blobstore: newBlobstoreMetrics(), blobobvnizca: newBlobovnizca(), + metabase: newMetabaseMetrics(), } } @@ -74,3 +76,7 @@ func (m *NodeMetrics) Blobstore() BlobstoreMetrics { func (m *NodeMetrics) BlobobvnizcaTreeMetrics() BlobobvnizcaMetrics { return m.blobobvnizca } + +func (m *NodeMetrics) MetabaseMetrics() MetabaseMetrics { + return m.metabase +}