forked from TrueCloudLab/frostfs-node
[#373] metrics: Add FSTree metrics
Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>logs-linter
parent
d8ecc69d00
commit
16a142cd0c
|
@ -36,6 +36,7 @@ import (
|
|||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/fstree"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/engine"
|
||||
meta "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/metabase"
|
||||
lsmetrics "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/metrics"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/pilorama"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard"
|
||||
shardmode "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
|
||||
|
@ -752,12 +753,22 @@ func (c *cfg) getSubstorageOpts(shCfg shardCfg) []blobstor.SubStorage {
|
|||
},
|
||||
})
|
||||
case fstree.Type:
|
||||
ss = append(ss, blobstor.SubStorage{
|
||||
Storage: fstree.New(
|
||||
fstreeOpts := []fstree.Option{
|
||||
fstree.WithPath(sRead.path),
|
||||
fstree.WithPerm(sRead.perm),
|
||||
fstree.WithDepth(sRead.depth),
|
||||
fstree.WithNoSync(sRead.noSync)),
|
||||
fstree.WithNoSync(sRead.noSync),
|
||||
}
|
||||
if c.metricsCollector != nil {
|
||||
fstreeOpts = append(fstreeOpts,
|
||||
fstree.WithMetrics(
|
||||
lsmetrics.NewFSTreeMetricsWithoutShardID(sRead.path, c.metricsCollector.FSTree()),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
ss = append(ss, blobstor.SubStorage{
|
||||
Storage: fstree.New(fstreeOpts...),
|
||||
Policy: func(_ *objectSDK.Object, data []byte) bool {
|
||||
return true
|
||||
},
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
package metrics
|
||||
|
||||
const undefined = "undefined"
|
|
@ -0,0 +1,61 @@
|
|||
package metrics
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/fstree"
|
||||
metrics_impl "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/metrics"
|
||||
)
|
||||
|
||||
func NewFSTreeMetricsWithoutShardID(path string, m metrics_impl.FSTreeMetrics) fstree.Metrics {
|
||||
return &fstreeMetrics{
|
||||
shardID: undefined,
|
||||
path: path,
|
||||
m: m,
|
||||
}
|
||||
}
|
||||
|
||||
type fstreeMetrics struct {
|
||||
shardID string
|
||||
path string
|
||||
m metrics_impl.FSTreeMetrics
|
||||
}
|
||||
|
||||
func (m *fstreeMetrics) SetParentID(parentID string) {
|
||||
m.shardID = parentID
|
||||
}
|
||||
|
||||
func (m *fstreeMetrics) SetMode(readOnly bool) {
|
||||
m.m.SetMode(m.shardID, m.path, readOnly)
|
||||
}
|
||||
func (m *fstreeMetrics) Close() {
|
||||
m.m.Close(m.shardID, m.path)
|
||||
}
|
||||
|
||||
func (m *fstreeMetrics) Iterate(d time.Duration, success bool) {
|
||||
m.m.MethodDuration(m.shardID, m.path, "Iterate", d, success)
|
||||
}
|
||||
func (m *fstreeMetrics) Delete(d time.Duration, success bool) {
|
||||
m.m.MethodDuration(m.shardID, m.path, "Delete", d, success)
|
||||
}
|
||||
func (m *fstreeMetrics) Exists(d time.Duration, success bool) {
|
||||
m.m.MethodDuration(m.shardID, m.path, "Exists", d, success)
|
||||
}
|
||||
func (m *fstreeMetrics) Put(d time.Duration, size int, success bool) {
|
||||
m.m.MethodDuration(m.shardID, m.path, "Put", d, success)
|
||||
if success {
|
||||
m.m.AddPut(m.shardID, m.path, size)
|
||||
}
|
||||
}
|
||||
func (m *fstreeMetrics) Get(d time.Duration, size int, success bool) {
|
||||
m.m.MethodDuration(m.shardID, m.path, "Get", d, success)
|
||||
if success {
|
||||
m.m.AddGet(m.shardID, m.path, size)
|
||||
}
|
||||
}
|
||||
func (m *fstreeMetrics) GetRange(d time.Duration, size int, success bool) {
|
||||
m.m.MethodDuration(m.shardID, m.path, "GetRange", d, success)
|
||||
if success {
|
||||
m.m.AddGet(m.shardID, m.path, size)
|
||||
}
|
||||
}
|
|
@ -57,7 +57,9 @@ func (s *Shard) UpdateID() (err error) {
|
|||
}
|
||||
s.metaBase.SetParentID(s.info.ID.String())
|
||||
s.blobStor.SetParentID(s.info.ID.String())
|
||||
if s.pilorama != nil {
|
||||
s.pilorama.SetParentID(s.info.ID.String())
|
||||
}
|
||||
|
||||
if len(id) != 0 {
|
||||
return nil
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
package metrics
|
||||
|
||||
const (
|
||||
fstreeSubSystem = "fstree"
|
||||
|
||||
successLabel = "success"
|
||||
shardIDLabel = "shardID"
|
||||
modeLabel = "mode"
|
||||
pathLabel = "path"
|
||||
methodLabel = "method"
|
||||
|
||||
readWriteMode = "READ_WRITE"
|
||||
readOnlyMode = "READ_ONLY"
|
||||
closedMode = "CLOSED"
|
||||
)
|
|
@ -0,0 +1,96 @@
|
|||
package metrics
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-observability/metrics"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
type FSTreeMetrics interface {
|
||||
SetMode(shardID, path string, readOnly bool)
|
||||
Close(shardID, path string)
|
||||
|
||||
MethodDuration(shardID, path string, method string, d time.Duration, success bool)
|
||||
AddGet(shardID, path string, size int)
|
||||
AddPut(shardID, path string, size int)
|
||||
}
|
||||
|
||||
type fstreeMetrics struct {
|
||||
mode *shardIDPathModeValue
|
||||
reqDuration *prometheus.HistogramVec
|
||||
put *prometheus.CounterVec
|
||||
get *prometheus.CounterVec
|
||||
}
|
||||
|
||||
func newFSTreeMetrics() *fstreeMetrics {
|
||||
return &fstreeMetrics{
|
||||
mode: newShardIDPathMode(fstreeSubSystem, "mode", "FSTree mode value"),
|
||||
reqDuration: metrics.NewHistogramVec(prometheus.HistogramOpts{
|
||||
Namespace: namespace,
|
||||
Subsystem: fstreeSubSystem,
|
||||
Name: "request_duration_seconds",
|
||||
Help: "Accumulated FSTree request process duration",
|
||||
}, []string{shardIDLabel, successLabel, pathLabel, methodLabel}),
|
||||
put: metrics.NewCounterVec(prometheus.CounterOpts{
|
||||
Namespace: namespace,
|
||||
Subsystem: fstreeSubSystem,
|
||||
Name: "put_bytes",
|
||||
Help: "Accumulated payload size written to FSTree",
|
||||
}, []string{shardIDLabel, pathLabel}),
|
||||
get: metrics.NewCounterVec(prometheus.CounterOpts{
|
||||
Namespace: namespace,
|
||||
Subsystem: fstreeSubSystem,
|
||||
Name: "get_bytes",
|
||||
Help: "Accumulated payload size read from FSTree",
|
||||
}, []string{shardIDLabel, pathLabel}),
|
||||
}
|
||||
}
|
||||
|
||||
func (m *fstreeMetrics) SetMode(shardID, path string, readOnly bool) {
|
||||
modeValue := readWriteMode
|
||||
if readOnly {
|
||||
modeValue = readOnlyMode
|
||||
}
|
||||
m.mode.SetMode(shardID, path, modeValue)
|
||||
}
|
||||
|
||||
func (m *fstreeMetrics) Close(shardID, path string) {
|
||||
m.mode.SetMode(shardID, path, closedMode)
|
||||
m.reqDuration.DeletePartialMatch(prometheus.Labels{
|
||||
shardIDLabel: shardID,
|
||||
pathLabel: path,
|
||||
})
|
||||
m.get.DeletePartialMatch(prometheus.Labels{
|
||||
shardIDLabel: shardID,
|
||||
pathLabel: path,
|
||||
})
|
||||
m.put.DeletePartialMatch(prometheus.Labels{
|
||||
shardIDLabel: shardID,
|
||||
pathLabel: path,
|
||||
})
|
||||
}
|
||||
|
||||
func (m *fstreeMetrics) 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())
|
||||
}
|
||||
|
||||
func (m *fstreeMetrics) AddGet(shardID, path string, size int) {
|
||||
m.get.With(prometheus.Labels{
|
||||
shardIDLabel: shardID,
|
||||
pathLabel: path,
|
||||
}).Add(float64(size))
|
||||
}
|
||||
|
||||
func (m *fstreeMetrics) AddPut(shardID, path string, size int) {
|
||||
m.put.With(prometheus.Labels{
|
||||
shardIDLabel: shardID,
|
||||
pathLabel: path,
|
||||
}).Add(float64(size))
|
||||
}
|
|
@ -37,3 +37,39 @@ func (m *shardIDModeValue) Delete(shardID string) {
|
|||
wcShardID: shardID,
|
||||
})
|
||||
}
|
||||
|
||||
type shardIDPathModeValue struct {
|
||||
modeValue *prometheus.GaugeVec
|
||||
}
|
||||
|
||||
func newShardIDPathMode(subsystem, name, help string) *shardIDPathModeValue {
|
||||
return &shardIDPathModeValue{
|
||||
modeValue: metrics.NewGaugeVec(
|
||||
prometheus.GaugeOpts{
|
||||
Namespace: namespace,
|
||||
Subsystem: subsystem,
|
||||
Name: name,
|
||||
Help: help,
|
||||
}, []string{shardIDLabel, pathLabel, modeLabel}),
|
||||
}
|
||||
}
|
||||
|
||||
func (m *shardIDPathModeValue) SetMode(shardID, path string, mode string) {
|
||||
m.modeValue.DeletePartialMatch(prometheus.Labels{
|
||||
shardIDLabel: shardID,
|
||||
pathLabel: path,
|
||||
})
|
||||
|
||||
m.modeValue.With(prometheus.Labels{
|
||||
shardIDLabel: shardID,
|
||||
pathLabel: path,
|
||||
modeLabel: mode,
|
||||
}).Set(1)
|
||||
}
|
||||
|
||||
func (m *shardIDPathModeValue) Delete(shardID, path string) {
|
||||
m.modeValue.DeletePartialMatch(prometheus.Labels{
|
||||
shardIDLabel: shardID,
|
||||
pathLabel: path,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ type NodeMetrics struct {
|
|||
objectService *objectServiceMetrics
|
||||
treeService *treeServiceMetrics
|
||||
epoch prometheus.Gauge
|
||||
fstree *fstreeMetrics
|
||||
}
|
||||
|
||||
func NewNodeMetrics() *NodeMetrics {
|
||||
|
@ -41,6 +42,7 @@ func NewNodeMetrics() *NodeMetrics {
|
|||
replicator: replicator,
|
||||
treeService: treeService,
|
||||
epoch: epoch,
|
||||
fstree: newFSTreeMetrics(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -68,3 +70,7 @@ func (m *NodeMetrics) Engine() EngineMetrics {
|
|||
func (m *NodeMetrics) State() StateMetrics {
|
||||
return m.state
|
||||
}
|
||||
|
||||
func (m *NodeMetrics) FSTree() FSTreeMetrics {
|
||||
return m.fstree
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue