[#373] metrics: Add blobstor metrics

Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
This commit is contained in:
Dmitrii Stepanov 2023-06-07 18:04:23 +03:00
parent 16a142cd0c
commit 56f320dd85
7 changed files with 198 additions and 42 deletions

View file

@ -786,19 +786,23 @@ func (c *cfg) getShardOpts(shCfg shardCfg) shardOptsWithID {
piloramaOpts := c.getPiloramaOpts(shCfg) piloramaOpts := c.getPiloramaOpts(shCfg)
ss := c.getSubstorageOpts(shCfg) ss := c.getSubstorageOpts(shCfg)
blobstoreOpts := []blobstor.Option{
blobstor.WithCompressObjects(shCfg.compress),
blobstor.WithUncompressableContentTypes(shCfg.uncompressableContentType),
blobstor.WithStorages(ss),
blobstor.WithLogger(c.log),
}
if c.metricsCollector != nil {
blobstoreOpts = append(blobstoreOpts, blobstor.WithMetrics(lsmetrics.NewBlobstoreMetrics(c.metricsCollector.Blobstore())))
}
var sh shardOptsWithID var sh shardOptsWithID
sh.configID = shCfg.id() sh.configID = shCfg.id()
sh.shOpts = []shard.Option{ sh.shOpts = []shard.Option{
shard.WithLogger(c.log), shard.WithLogger(c.log),
shard.WithRefillMetabase(shCfg.refillMetabase), shard.WithRefillMetabase(shCfg.refillMetabase),
shard.WithMode(shCfg.mode), shard.WithMode(shCfg.mode),
shard.WithBlobStorOptions( shard.WithBlobStorOptions(blobstoreOpts...),
blobstor.WithCompressObjects(shCfg.compress),
blobstor.WithUncompressableContentTypes(shCfg.uncompressableContentType),
blobstor.WithStorages(ss),
blobstor.WithLogger(c.log),
),
shard.WithMetaBaseOptions( shard.WithMetaBaseOptions(
meta.WithPath(shCfg.metaCfg.path), meta.WithPath(shCfg.metaCfg.path),
meta.WithPermissions(shCfg.metaCfg.perm), meta.WithPermissions(shCfg.metaCfg.perm),

View file

@ -0,0 +1,65 @@
package metrics
import (
"time"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor"
metrics_impl "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/metrics"
)
type blobstoreMetrics struct {
shardID string
m metrics_impl.BlobstoreMetrics
}
func NewBlobstoreMetrics(m metrics_impl.BlobstoreMetrics) blobstor.Metrics {
return &blobstoreMetrics{
shardID: undefined,
m: m,
}
}
func (m *blobstoreMetrics) SetParentID(parentID string) {
m.shardID = parentID
}
func (m *blobstoreMetrics) SetMode(readOnly bool) {
m.m.SetMode(m.shardID, readOnly)
}
func (m *blobstoreMetrics) Close() {
m.m.Close(m.shardID)
}
func (m *blobstoreMetrics) Delete(d time.Duration, success, withStorageID bool) {
m.m.MethodDuration(m.shardID, "Delete", d, success, metrics_impl.NullBool{Bool: withStorageID, Valid: true})
}
func (m *blobstoreMetrics) Exists(d time.Duration, success, withStorageID bool) {
m.m.MethodDuration(m.shardID, "Exists", d, success, metrics_impl.NullBool{Bool: withStorageID, Valid: true})
}
func (m *blobstoreMetrics) GetRange(d time.Duration, size int, success, withStorageID bool) {
m.m.MethodDuration(m.shardID, "GetRange", d, success, metrics_impl.NullBool{Bool: withStorageID, Valid: true})
if success {
m.m.AddGet(m.shardID, size)
}
}
func (m *blobstoreMetrics) Get(d time.Duration, size int, success, withStorageID bool) {
m.m.MethodDuration(m.shardID, "Get", d, success, metrics_impl.NullBool{Bool: withStorageID, Valid: true})
if success {
m.m.AddGet(m.shardID, size)
}
}
func (m *blobstoreMetrics) Iterate(d time.Duration, success bool) {
m.m.MethodDuration(m.shardID, "Iterate", d, success, metrics_impl.NullBool{})
}
func (m *blobstoreMetrics) Put(d time.Duration, size int, success bool) {
m.m.MethodDuration(m.shardID, "Put", d, success, metrics_impl.NullBool{})
if success {
m.m.AddPut(m.shardID, size)
}
}

87
pkg/metrics/blobstore.go Normal file
View file

@ -0,0 +1,87 @@
package metrics
import (
"strconv"
"time"
"git.frostfs.info/TrueCloudLab/frostfs-observability/metrics"
"github.com/prometheus/client_golang/prometheus"
)
type BlobstoreMetrics interface {
SetMode(shardID string, readOnly bool)
Close(shardID string)
MethodDuration(shardID string, method string, d time.Duration, success bool, withStorageID NullBool)
AddPut(shardID string, size int)
AddGet(shardID string, size int)
}
type blobstoreMetrics struct {
mode *shardIDModeValue
reqDuration *prometheus.HistogramVec
put *prometheus.CounterVec
get *prometheus.CounterVec
}
func newBlobstoreMetrics() *blobstoreMetrics {
return &blobstoreMetrics{
mode: newShardIDMode(blobstoreSubSystem, "mode", "Blobstore mode value"),
reqDuration: metrics.NewHistogramVec(prometheus.HistogramOpts{
Namespace: namespace,
Subsystem: blobstoreSubSystem,
Name: "request_duration_seconds",
Help: "Accumulated Blobstore request process duration",
}, []string{shardIDLabel, successLabel, methodLabel, withStorageIDLabel}),
put: metrics.NewCounterVec(prometheus.CounterOpts{
Namespace: namespace,
Subsystem: blobstoreSubSystem,
Name: "put_bytes",
Help: "Accumulated payload size written to Blobstore",
}, []string{shardIDLabel}),
get: metrics.NewCounterVec(prometheus.CounterOpts{
Namespace: namespace,
Subsystem: blobstoreSubSystem,
Name: "get_bytes",
Help: "Accumulated payload size read from Blobstore",
}, []string{shardIDLabel}),
}
}
func (m *blobstoreMetrics) SetMode(shardID string, readOnly bool) {
m.mode.SetMode(shardID, modeFromBool(readOnly))
}
func (m *blobstoreMetrics) Close(shardID string) {
m.mode.SetMode(shardID, closedMode)
m.reqDuration.DeletePartialMatch(prometheus.Labels{
shardIDLabel: shardID,
})
m.get.DeletePartialMatch(prometheus.Labels{
shardIDLabel: shardID,
})
m.put.DeletePartialMatch(prometheus.Labels{
shardIDLabel: shardID,
})
}
func (m *blobstoreMetrics) MethodDuration(shardID string, method string, d time.Duration, success bool, withStorageID NullBool) {
m.reqDuration.With(prometheus.Labels{
shardIDLabel: shardID,
successLabel: strconv.FormatBool(success),
methodLabel: method,
withStorageIDLabel: withStorageID.String(),
}).Observe(d.Seconds())
}
func (m *blobstoreMetrics) AddPut(shardID string, size int) {
m.put.With(prometheus.Labels{
shardIDLabel: shardID,
}).Add(float64(size))
}
func (m *blobstoreMetrics) AddGet(shardID string, size int) {
m.get.With(prometheus.Labels{
shardIDLabel: shardID,
}).Add(float64(size))
}

View file

@ -2,12 +2,14 @@ package metrics
const ( const (
fstreeSubSystem = "fstree" fstreeSubSystem = "fstree"
blobstoreSubSystem = "blobstore"
successLabel = "success" successLabel = "success"
shardIDLabel = "shardID" shardIDLabel = "shardID"
modeLabel = "mode" modeLabel = "mode"
pathLabel = "path" pathLabel = "path"
methodLabel = "method" methodLabel = "method"
withStorageIDLabel = "withStorageID"
readWriteMode = "READ_WRITE" readWriteMode = "READ_WRITE"
readOnlyMode = "READ_ONLY" readOnlyMode = "READ_ONLY"

View file

@ -49,11 +49,7 @@ func newFSTreeMetrics() *fstreeMetrics {
} }
func (m *fstreeMetrics) SetMode(shardID, path string, readOnly bool) { func (m *fstreeMetrics) SetMode(shardID, path string, readOnly bool) {
modeValue := readWriteMode m.mode.SetMode(shardID, path, modeFromBool(readOnly))
if readOnly {
modeValue = readOnlyMode
}
m.mode.SetMode(shardID, path, modeValue)
} }
func (m *fstreeMetrics) Close(shardID, path string) { func (m *fstreeMetrics) Close(shardID, path string) {

View file

@ -73,3 +73,11 @@ func (m *shardIDPathModeValue) Delete(shardID, path string) {
pathLabel: path, pathLabel: path,
}) })
} }
func modeFromBool(readOnly bool) string {
modeValue := readWriteMode
if readOnly {
modeValue = readOnlyMode
}
return modeValue
}

View file

@ -15,34 +15,24 @@ type NodeMetrics struct {
treeService *treeServiceMetrics treeService *treeServiceMetrics
epoch prometheus.Gauge epoch prometheus.Gauge
fstree *fstreeMetrics fstree *fstreeMetrics
blobstore *blobstoreMetrics
} }
func NewNodeMetrics() *NodeMetrics { func NewNodeMetrics() *NodeMetrics {
objectService := newObjectServiceMetrics() return &NodeMetrics{
objectService: newObjectServiceMetrics(),
engine := newEngineMetrics() engine: newEngineMetrics(),
state: newStateMetrics(),
state := newStateMetrics() replicator: newReplicatorMetrics(),
treeService: newTreeServiceMetrics(),
replicator := newReplicatorMetrics() epoch: metrics.NewGauge(prometheus.GaugeOpts{
treeService := newTreeServiceMetrics()
epoch := metrics.NewGauge(prometheus.GaugeOpts{
Namespace: namespace, Namespace: namespace,
Subsystem: innerRingSubsystem, Subsystem: innerRingSubsystem,
Name: "epoch", Name: "epoch",
Help: "Current epoch as seen by inner-ring node.", Help: "Current epoch as seen by inner-ring node.",
}) }),
return &NodeMetrics{
objectService: objectService,
engine: engine,
state: state,
replicator: replicator,
treeService: treeService,
epoch: epoch,
fstree: newFSTreeMetrics(), fstree: newFSTreeMetrics(),
blobstore: newBlobstoreMetrics(),
} }
} }
@ -74,3 +64,7 @@ func (m *NodeMetrics) State() StateMetrics {
func (m *NodeMetrics) FSTree() FSTreeMetrics { func (m *NodeMetrics) FSTree() FSTreeMetrics {
return m.fstree return m.fstree
} }
func (m *NodeMetrics) Blobstore() BlobstoreMetrics {
return m.blobstore
}