forked from TrueCloudLab/frostfs-node
[#1029] metabase: Add refill metrics
Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
This commit is contained in:
parent
e3d9dd6ee8
commit
1b17258c04
23 changed files with 366 additions and 47 deletions
38
pkg/local_object_storage/blobstor/blobovniczatree/count.go
Normal file
38
pkg/local_object_storage/blobstor/blobovniczatree/count.go
Normal file
|
@ -0,0 +1,38 @@
|
|||
package blobovniczatree
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
|
||||
)
|
||||
|
||||
func (b *Blobovniczas) ObjectsCount(ctx context.Context) (uint64, error) {
|
||||
var (
|
||||
success bool
|
||||
startedAt = time.Now()
|
||||
)
|
||||
defer func() {
|
||||
b.metrics.ObjectsCount(time.Since(startedAt), success)
|
||||
}()
|
||||
|
||||
_, span := tracing.StartSpanFromContext(ctx, "Blobovniczas.ObjectsCount")
|
||||
defer span.End()
|
||||
|
||||
var result uint64
|
||||
err := b.iterateExistingDBPaths(ctx, func(p string) (bool, error) {
|
||||
shDB := b.getBlobovniczaWithoutCaching(p)
|
||||
blz, err := shDB.Open()
|
||||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
defer shDB.Close()
|
||||
|
||||
result += blz.ObjectsCount()
|
||||
return false, nil
|
||||
})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
|
@ -24,6 +24,7 @@ type Metrics interface {
|
|||
SetRebuildStatus(status string)
|
||||
ObjectMoved(d time.Duration)
|
||||
SetRebuildPercent(value uint32)
|
||||
ObjectsCount(d time.Duration, success bool)
|
||||
|
||||
Delete(d time.Duration, success, withStorageID bool)
|
||||
Exists(d time.Duration, success, withStorageID bool)
|
||||
|
@ -47,6 +48,7 @@ func (m *noopMetrics) GetRange(time.Duration, int, bool, bool) {}
|
|||
func (m *noopMetrics) Get(time.Duration, int, bool, bool) {}
|
||||
func (m *noopMetrics) Iterate(time.Duration, bool) {}
|
||||
func (m *noopMetrics) Put(time.Duration, int, bool) {}
|
||||
func (m *noopMetrics) ObjectsCount(time.Duration, bool) {}
|
||||
func (m *noopMetrics) Blobovnicza() blobovnicza.Metrics {
|
||||
return &blobovnicza.NoopMetrics{}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ type Storage interface {
|
|||
|
||||
Type() string
|
||||
Path() string
|
||||
ObjectsCount(ctx context.Context) (uint64, error)
|
||||
|
||||
SetCompressor(cc *compression.Config)
|
||||
Compressor() *compression.Config
|
||||
|
|
|
@ -467,6 +467,45 @@ func (t *FSTree) countFiles() (uint64, error) {
|
|||
return counter, nil
|
||||
}
|
||||
|
||||
func (t *FSTree) ObjectsCount(ctx context.Context) (uint64, error) {
|
||||
var (
|
||||
startedAt = time.Now()
|
||||
success = false
|
||||
)
|
||||
defer func() {
|
||||
t.metrics.ObjectsCount(time.Since(startedAt), success)
|
||||
}()
|
||||
|
||||
ctx, span := tracing.StartSpanFromContext(ctx, "FSTree.ObjectsCount",
|
||||
trace.WithAttributes(
|
||||
attribute.String("path", t.RootPath),
|
||||
))
|
||||
defer span.End()
|
||||
|
||||
var result uint64
|
||||
|
||||
err := filepath.WalkDir(t.RootPath,
|
||||
func(_ string, d fs.DirEntry, _ error) error {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
default:
|
||||
}
|
||||
|
||||
if !d.IsDir() {
|
||||
result++
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("could not walk through %s directory: %w", t.RootPath, err)
|
||||
}
|
||||
success = true
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// Type is fstree storage type used in logs and configuration.
|
||||
const Type = "fstree"
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ type Metrics interface {
|
|||
Put(d time.Duration, size int, success bool)
|
||||
Get(d time.Duration, size int, success bool)
|
||||
GetRange(d time.Duration, size int, success bool)
|
||||
ObjectsCount(d time.Duration, success bool)
|
||||
}
|
||||
|
||||
type noopMetrics struct{}
|
||||
|
@ -27,3 +28,4 @@ func (m *noopMetrics) Exists(time.Duration, bool) {}
|
|||
func (m *noopMetrics) Put(time.Duration, int, bool) {}
|
||||
func (m *noopMetrics) Get(time.Duration, int, bool) {}
|
||||
func (m *noopMetrics) GetRange(time.Duration, int, bool) {}
|
||||
func (m *noopMetrics) ObjectsCount(time.Duration, bool) {}
|
||||
|
|
|
@ -1,5 +1,14 @@
|
|||
package blobstor
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
|
||||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
|
||||
// DumpInfo returns information about blob stor.
|
||||
func (b *BlobStor) DumpInfo() Info {
|
||||
b.modeMtx.RLock()
|
||||
|
@ -15,3 +24,39 @@ func (b *BlobStor) DumpInfo() Info {
|
|||
SubStorages: sub,
|
||||
}
|
||||
}
|
||||
|
||||
// ObjectsCount returns Blobstore's total objects count.
|
||||
func (b *BlobStor) ObjectsCount(ctx context.Context) (uint64, error) {
|
||||
var err error
|
||||
startedAt := time.Now()
|
||||
defer func() {
|
||||
b.metrics.ObjectsCount(time.Since(startedAt), err == nil)
|
||||
}()
|
||||
|
||||
ctx, span := tracing.StartSpanFromContext(ctx, "BlobStor.ObjectsCount")
|
||||
defer span.End()
|
||||
|
||||
b.modeMtx.RLock()
|
||||
defer b.modeMtx.RUnlock()
|
||||
|
||||
var result atomic.Uint64
|
||||
|
||||
eg, egCtx := errgroup.WithContext(ctx)
|
||||
for i := range b.storage {
|
||||
i := i
|
||||
eg.Go(func() error {
|
||||
v, e := b.storage[i].Storage.ObjectsCount(egCtx)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
result.Add(v)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
if err = eg.Wait(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return result.Load(), nil
|
||||
}
|
||||
|
|
|
@ -163,3 +163,10 @@ func (s *memstoreImpl) Iterate(_ context.Context, req common.IteratePrm) (common
|
|||
func (s *memstoreImpl) Rebuild(_ context.Context, _ common.RebuildPrm) (common.RebuildRes, error) {
|
||||
return common.RebuildRes{}, nil
|
||||
}
|
||||
|
||||
func (s *memstoreImpl) ObjectsCount(_ context.Context) (uint64, error) {
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
|
||||
return uint64(len(s.objs)), nil
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ type Metrics interface {
|
|||
Get(d time.Duration, size int, success, withStorageID bool)
|
||||
Iterate(d time.Duration, success bool)
|
||||
Put(d time.Duration, size int, success bool)
|
||||
ObjectsCount(d time.Duration, success bool)
|
||||
}
|
||||
|
||||
type noopMetrics struct{}
|
||||
|
@ -26,3 +27,4 @@ func (m *noopMetrics) GetRange(time.Duration, int, bool, bool) {}
|
|||
func (m *noopMetrics) Get(time.Duration, int, bool, bool) {}
|
||||
func (m *noopMetrics) Iterate(time.Duration, bool) {}
|
||||
func (m *noopMetrics) Put(time.Duration, int, bool) {}
|
||||
func (m *noopMetrics) ObjectsCount(time.Duration, bool) {}
|
||||
|
|
|
@ -233,3 +233,10 @@ func (s *TestStore) SetParentID(string) {}
|
|||
func (s *TestStore) Rebuild(_ context.Context, _ common.RebuildPrm) (common.RebuildRes, error) {
|
||||
return common.RebuildRes{}, nil
|
||||
}
|
||||
|
||||
func (s *TestStore) ObjectsCount(ctx context.Context) (uint64, error) {
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
|
||||
return s.st.ObjectsCount(ctx)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue