[#373] metrics: Add blobstor metrics
Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
This commit is contained in:
parent
16a142cd0c
commit
56f320dd85
7 changed files with 198 additions and 42 deletions
|
@ -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),
|
||||||
|
|
65
pkg/local_object_storage/metrics/blobstore.go
Normal file
65
pkg/local_object_storage/metrics/blobstore.go
Normal 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
87
pkg/metrics/blobstore.go
Normal 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))
|
||||||
|
}
|
|
@ -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"
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue