[#602] metrics: Add blobovnicza items counter
All checks were successful
Vulncheck / Vulncheck (pull_request) Successful in 1m29s
Build / Build Components (1.21) (pull_request) Successful in 3m23s
DCO action / DCO (pull_request) Successful in 3m50s
Tests and linters / Tests (1.21) (pull_request) Successful in 4m27s
Tests and linters / Lint (pull_request) Successful in 4m48s
Tests and linters / Tests (1.20) (pull_request) Successful in 5m6s
Tests and linters / Staticcheck (pull_request) Successful in 5m8s
Tests and linters / Tests with -race (pull_request) Successful in 5m38s
Build / Build Components (1.20) (pull_request) Successful in 7m46s

Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
This commit is contained in:
Dmitrii Stepanov 2023-08-18 13:01:27 +03:00
parent c4e1d8eb07
commit f2811f8585
8 changed files with 70 additions and 18 deletions

View file

@ -16,7 +16,8 @@ import (
type Blobovnicza struct { type Blobovnicza struct {
cfg cfg
dataSize atomic.Uint64 dataSize atomic.Uint64
itemsCount atomic.Uint64
boltDB *bbolt.DB boltDB *bbolt.DB

View file

@ -68,8 +68,10 @@ func (b *Blobovnicza) Init() error {
zap.Uint64("storage size limit", b.fullSizeLimit), zap.Uint64("storage size limit", b.fullSizeLimit),
) )
if size := b.dataSize.Load(); size != 0 { size := b.dataSize.Load()
b.log.Debug(logs.BlobovniczaAlreadyInitialized, zap.Uint64("size", size)) items := b.itemsCount.Load()
if size != 0 || items != 0 {
b.log.Debug(logs.BlobovniczaAlreadyInitialized, zap.Uint64("size", size), zap.Uint64("items", items))
return nil return nil
} }
@ -96,14 +98,17 @@ func (b *Blobovnicza) Init() error {
} }
} }
return b.initializeSize() return b.initializeCounters()
} }
func (b *Blobovnicza) initializeSize() error { func (b *Blobovnicza) initializeCounters() error {
var size uint64 var size uint64
var items uint64
err := b.boltDB.View(func(tx *bbolt.Tx) error { err := b.boltDB.View(func(tx *bbolt.Tx) error {
return b.iterateAllBuckets(tx, func(lower, upper uint64, b *bbolt.Bucket) (bool, error) { return b.iterateAllBuckets(tx, func(lower, upper uint64, b *bbolt.Bucket) (bool, error) {
size += uint64(b.Stats().KeyN) * upper keysN := uint64(b.Stats().KeyN)
size += keysN * upper
items += keysN
return false, nil return false, nil
}) })
}) })
@ -111,7 +116,9 @@ func (b *Blobovnicza) initializeSize() error {
return fmt.Errorf("can't determine DB size: %w", err) return fmt.Errorf("can't determine DB size: %w", err)
} }
b.dataSize.Store(size) b.dataSize.Store(size)
b.itemsCount.Store(items)
b.metrics.AddOpenBlobovniczaSize(size) b.metrics.AddOpenBlobovniczaSize(size)
b.metrics.AddOpenBlobovniczaItems(items)
return nil return nil
} }
@ -136,7 +143,9 @@ func (b *Blobovnicza) Close() error {
b.metrics.DecOpenBlobovniczaCount() b.metrics.DecOpenBlobovniczaCount()
b.metrics.SubOpenBlobovniczaSize(b.dataSize.Load()) b.metrics.SubOpenBlobovniczaSize(b.dataSize.Load())
b.metrics.SubOpenBlobovniczaItems(b.itemsCount.Load())
b.dataSize.Store(0) b.dataSize.Store(0)
b.itemsCount.Store(0)
b.opened = false b.opened = false

View file

@ -74,7 +74,7 @@ func (b *Blobovnicza) Delete(ctx context.Context, prm DeletePrm) (DeleteRes, err
zap.String("binary size", stringifyByteSize(dataSize)), zap.String("binary size", stringifyByteSize(dataSize)),
zap.String("range", stringifyBounds(sizeLowerBound, sizeUpperBound)), zap.String("range", stringifyBounds(sizeLowerBound, sizeUpperBound)),
) )
b.decSize(sizeUpperBound) b.itemDeleted(sizeUpperBound)
} }
return DeleteRes{}, err return DeleteRes{}, err

View file

@ -6,11 +6,16 @@ type Metrics interface {
AddOpenBlobovniczaSize(size uint64) AddOpenBlobovniczaSize(size uint64)
SubOpenBlobovniczaSize(size uint64) SubOpenBlobovniczaSize(size uint64)
AddOpenBlobovniczaItems(items uint64)
SubOpenBlobovniczaItems(items uint64)
} }
type NoopMetrics struct{} type NoopMetrics struct{}
func (m *NoopMetrics) IncOpenBlobovniczaCount() {} func (m *NoopMetrics) IncOpenBlobovniczaCount() {}
func (m *NoopMetrics) DecOpenBlobovniczaCount() {} func (m *NoopMetrics) DecOpenBlobovniczaCount() {}
func (m *NoopMetrics) AddOpenBlobovniczaSize(uint64) {} func (m *NoopMetrics) AddOpenBlobovniczaSize(uint64) {}
func (m *NoopMetrics) SubOpenBlobovniczaSize(uint64) {} func (m *NoopMetrics) SubOpenBlobovniczaSize(uint64) {}
func (m *NoopMetrics) AddOpenBlobovniczaItems(uint64) {}
func (m *NoopMetrics) SubOpenBlobovniczaItems(uint64) {}

View file

@ -85,7 +85,7 @@ func (b *Blobovnicza) Put(ctx context.Context, prm PutPrm) (PutRes, error) {
return nil return nil
}) })
if err == nil { if err == nil {
b.incSize(upperBound) b.itemAdded(upperBound)
} }
return PutRes{}, err return PutRes{}, err

View file

@ -3,6 +3,7 @@ package blobovnicza
import ( import (
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"math"
"math/bits" "math/bits"
"strconv" "strconv"
) )
@ -40,14 +41,18 @@ func upperPowerOfTwo(v uint64) uint64 {
return 1 << bits.Len64(v-1) return 1 << bits.Len64(v-1)
} }
func (b *Blobovnicza) incSize(sz uint64) { func (b *Blobovnicza) itemAdded(itemSize uint64) {
b.dataSize.Add(sz) b.dataSize.Add(itemSize)
b.metrics.AddOpenBlobovniczaSize(sz) b.itemsCount.Add(1)
b.metrics.AddOpenBlobovniczaSize(itemSize)
b.metrics.AddOpenBlobovniczaItems(1)
} }
func (b *Blobovnicza) decSize(sz uint64) { func (b *Blobovnicza) itemDeleted(itemSize uint64) {
b.dataSize.Add(^(sz - 1)) b.dataSize.Add(^(itemSize - 1))
b.metrics.SubOpenBlobovniczaSize(sz) b.itemsCount.Add(math.MaxUint64)
b.metrics.SubOpenBlobovniczaSize(itemSize)
b.metrics.SubOpenBlobovniczaItems(1)
} }
func (b *Blobovnicza) full() bool { func (b *Blobovnicza) full() bool {

View file

@ -96,3 +96,11 @@ func (m *blobovniczaMetrics) IncOpenBlobovniczaCount() {
func (m *blobovniczaMetrics) DecOpenBlobovniczaCount() { func (m *blobovniczaMetrics) DecOpenBlobovniczaCount() {
m.m.DecOpenBlobovniczaCount(m.shardID(), m.path) m.m.DecOpenBlobovniczaCount(m.shardID(), m.path)
} }
func (m *blobovniczaMetrics) AddOpenBlobovniczaItems(items uint64) {
m.m.AddOpenBlobovniczaItems(m.shardID(), m.path, items)
}
func (m *blobovniczaMetrics) SubOpenBlobovniczaItems(items uint64) {
m.m.SubOpenBlobovniczaItems(m.shardID(), m.path, items)
}

View file

@ -18,6 +18,9 @@ type BlobobvnizcaMetrics interface {
AddOpenBlobovniczaSize(shardID, path string, size uint64) AddOpenBlobovniczaSize(shardID, path string, size uint64)
SubOpenBlobovniczaSize(shardID, path string, size uint64) SubOpenBlobovniczaSize(shardID, path string, size uint64)
AddOpenBlobovniczaItems(shardID, path string, items uint64)
SubOpenBlobovniczaItems(shardID, path string, items uint64)
IncOpenBlobovniczaCount(shardID, path string) IncOpenBlobovniczaCount(shardID, path string)
DecOpenBlobovniczaCount(shardID, path string) DecOpenBlobovniczaCount(shardID, path string)
} }
@ -28,6 +31,7 @@ type blobovnicza struct {
treePut *prometheus.CounterVec treePut *prometheus.CounterVec
treeGet *prometheus.CounterVec treeGet *prometheus.CounterVec
treeOpenSize *prometheus.GaugeVec treeOpenSize *prometheus.GaugeVec
treeOpenItems *prometheus.GaugeVec
treeOpenCounter *prometheus.GaugeVec treeOpenCounter *prometheus.GaugeVec
} }
@ -59,6 +63,12 @@ func newBlobovnicza() *blobovnicza {
Name: "open_blobovnicza_size_bytes", Name: "open_blobovnicza_size_bytes",
Help: "Size of opened blobovniczas of Blobovnicza tree", Help: "Size of opened blobovniczas of Blobovnicza tree",
}, []string{shardIDLabel, pathLabel}), }, []string{shardIDLabel, pathLabel}),
treeOpenItems: metrics.NewGaugeVec(prometheus.GaugeOpts{
Namespace: namespace,
Subsystem: blobovniczaTreeSubSystem,
Name: "open_blobovnicza_items_total",
Help: "Count of items in opened blobovniczas of Blobovnicza tree",
}, []string{shardIDLabel, pathLabel}),
treeOpenCounter: metrics.NewGaugeVec(prometheus.GaugeOpts{ treeOpenCounter: metrics.NewGaugeVec(prometheus.GaugeOpts{
Namespace: namespace, Namespace: namespace,
Subsystem: blobovniczaTreeSubSystem, Subsystem: blobovniczaTreeSubSystem,
@ -139,3 +149,17 @@ func (b *blobovnicza) DecOpenBlobovniczaCount(shardID, path string) {
pathLabel: path, pathLabel: path,
}).Dec() }).Dec()
} }
func (b *blobovnicza) AddOpenBlobovniczaItems(shardID, path string, items uint64) {
b.treeOpenItems.With(prometheus.Labels{
shardIDLabel: shardID,
pathLabel: path,
}).Add(float64(items))
}
func (b *blobovnicza) SubOpenBlobovniczaItems(shardID, path string, items uint64) {
b.treeOpenItems.With(prometheus.Labels{
shardIDLabel: shardID,
pathLabel: path,
}).Sub(float64(items))
}