[#373] blobstor: Add metrics
Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
This commit is contained in:
parent
8318d90ad0
commit
f54cc0b607
11 changed files with 134 additions and 19 deletions
|
@ -26,11 +26,11 @@ import (
|
||||||
func (b *Blobovniczas) Get(ctx context.Context, prm common.GetPrm) (res common.GetRes, err error) {
|
func (b *Blobovniczas) Get(ctx context.Context, prm common.GetPrm) (res common.GetRes, err error) {
|
||||||
var (
|
var (
|
||||||
startedAt = time.Now()
|
startedAt = time.Now()
|
||||||
found = false
|
success = false
|
||||||
size = 0
|
size = 0
|
||||||
)
|
)
|
||||||
defer func() {
|
defer func() {
|
||||||
b.metrics.Get(time.Since(startedAt), size, found, prm.StorageID != nil)
|
b.metrics.Get(time.Since(startedAt), size, success, prm.StorageID != nil)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
ctx, span := tracing.StartSpanFromContext(ctx, "Blobovniczas.Get",
|
ctx, span := tracing.StartSpanFromContext(ctx, "Blobovniczas.Get",
|
||||||
|
@ -54,7 +54,7 @@ func (b *Blobovniczas) Get(ctx context.Context, prm common.GetPrm) (res common.G
|
||||||
|
|
||||||
res, err = b.getObject(ctx, blz, bPrm)
|
res, err = b.getObject(ctx, blz, bPrm)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
found = true
|
success = true
|
||||||
size = len(res.RawData)
|
size = len(res.RawData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,7 @@ func (b *Blobovniczas) Get(ctx context.Context, prm common.GetPrm) (res common.G
|
||||||
return res, logicerr.Wrap(apistatus.ObjectNotFound{})
|
return res, logicerr.Wrap(apistatus.ObjectNotFound{})
|
||||||
}
|
}
|
||||||
|
|
||||||
found = true
|
success = true
|
||||||
size = len(res.RawData)
|
size = len(res.RawData)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
|
@ -27,11 +27,11 @@ import (
|
||||||
func (b *Blobovniczas) GetRange(ctx context.Context, prm common.GetRangePrm) (res common.GetRangeRes, err error) {
|
func (b *Blobovniczas) GetRange(ctx context.Context, prm common.GetRangePrm) (res common.GetRangeRes, err error) {
|
||||||
var (
|
var (
|
||||||
startedAt = time.Now()
|
startedAt = time.Now()
|
||||||
found = false
|
success = false
|
||||||
size = 0
|
size = 0
|
||||||
)
|
)
|
||||||
defer func() {
|
defer func() {
|
||||||
b.metrics.GetRange(time.Since(startedAt), size, found, prm.StorageID != nil)
|
b.metrics.GetRange(time.Since(startedAt), size, success, prm.StorageID != nil)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
ctx, span := tracing.StartSpanFromContext(ctx, "Blobovniczas.GetRange",
|
ctx, span := tracing.StartSpanFromContext(ctx, "Blobovniczas.GetRange",
|
||||||
|
@ -54,12 +54,13 @@ func (b *Blobovniczas) GetRange(ctx context.Context, prm common.GetRangePrm) (re
|
||||||
res, err := b.getObjectRange(ctx, blz, prm)
|
res, err := b.getObjectRange(ctx, blz, prm)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
size = len(res.Data)
|
size = len(res.Data)
|
||||||
found = true
|
success = true
|
||||||
}
|
}
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
activeCache := make(map[string]struct{})
|
activeCache := make(map[string]struct{})
|
||||||
|
objectFound := false
|
||||||
|
|
||||||
err = b.iterateSortedLeaves(ctx, &prm.Address, func(p string) (bool, error) {
|
err = b.iterateSortedLeaves(ctx, &prm.Address, func(p string) (bool, error) {
|
||||||
dirPath := filepath.Dir(p)
|
dirPath := filepath.Dir(p)
|
||||||
|
@ -82,18 +83,19 @@ func (b *Blobovniczas) GetRange(ctx context.Context, prm common.GetRangePrm) (re
|
||||||
|
|
||||||
activeCache[dirPath] = struct{}{}
|
activeCache[dirPath] = struct{}{}
|
||||||
|
|
||||||
found = err == nil
|
objectFound = err == nil
|
||||||
|
|
||||||
// abort iterator if found, otherwise process all Blobovniczas
|
// abort iterator if found, otherwise process all Blobovniczas
|
||||||
return err == nil, nil
|
return err == nil, nil
|
||||||
})
|
})
|
||||||
|
|
||||||
if err == nil && !found {
|
if err == nil && !objectFound {
|
||||||
// not found in any blobovnicza
|
// not found in any blobovnicza
|
||||||
return common.GetRangeRes{}, logicerr.Wrap(apistatus.ObjectNotFound{})
|
return common.GetRangeRes{}, logicerr.Wrap(apistatus.ObjectNotFound{})
|
||||||
}
|
}
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
success = true
|
||||||
size = len(res.Data)
|
size = len(res.Data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,10 +43,12 @@ type cfg struct {
|
||||||
compression compression.Config
|
compression compression.Config
|
||||||
log *logger.Logger
|
log *logger.Logger
|
||||||
storage []SubStorage
|
storage []SubStorage
|
||||||
|
metrics Metrics
|
||||||
}
|
}
|
||||||
|
|
||||||
func initConfig(c *cfg) {
|
func initConfig(c *cfg) {
|
||||||
c.log = &logger.Logger{Logger: zap.L()}
|
c.log = &logger.Logger{Logger: zap.L()}
|
||||||
|
c.metrics = &noopMetrics{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates, initializes and returns new BlobStor instance.
|
// New creates, initializes and returns new BlobStor instance.
|
||||||
|
@ -113,3 +115,9 @@ func (b *BlobStor) SetReportErrorFunc(f func(string, error)) {
|
||||||
b.storage[i].Storage.SetReportErrorFunc(f)
|
b.storage[i].Storage.SetReportErrorFunc(f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func WithMetrics(m Metrics) Option {
|
||||||
|
return func(c *cfg) {
|
||||||
|
c.metrics = m
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ func (b *BlobStor) Open(readOnly bool) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
b.metrics.SetMode(readOnly)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,5 +66,8 @@ func (b *BlobStor) Close() error {
|
||||||
if firstErr == nil {
|
if firstErr == nil {
|
||||||
firstErr = err
|
firstErr = err
|
||||||
}
|
}
|
||||||
|
if firstErr == nil {
|
||||||
|
b.metrics.Close()
|
||||||
|
}
|
||||||
return firstErr
|
return firstErr
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
|
"time"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
|
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
|
||||||
|
@ -13,6 +14,14 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func (b *BlobStor) Delete(ctx context.Context, prm common.DeletePrm) (common.DeleteRes, error) {
|
func (b *BlobStor) Delete(ctx context.Context, prm common.DeletePrm) (common.DeleteRes, error) {
|
||||||
|
var (
|
||||||
|
startedAt = time.Now()
|
||||||
|
success = false
|
||||||
|
)
|
||||||
|
defer func() {
|
||||||
|
b.metrics.Delete(time.Since(startedAt), success, prm.StorageID != nil)
|
||||||
|
}()
|
||||||
|
|
||||||
ctx, span := tracing.StartSpanFromContext(ctx, "BlobStor.Delete",
|
ctx, span := tracing.StartSpanFromContext(ctx, "BlobStor.Delete",
|
||||||
trace.WithAttributes(
|
trace.WithAttributes(
|
||||||
attribute.String("address", prm.Address.EncodeToString()),
|
attribute.String("address", prm.Address.EncodeToString()),
|
||||||
|
@ -28,6 +37,7 @@ func (b *BlobStor) Delete(ctx context.Context, prm common.DeletePrm) (common.Del
|
||||||
res, err := b.storage[i].Storage.Delete(ctx, prm)
|
res, err := b.storage[i].Storage.Delete(ctx, prm)
|
||||||
if err == nil || !errors.As(err, new(apistatus.ObjectNotFound)) {
|
if err == nil || !errors.As(err, new(apistatus.ObjectNotFound)) {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
success = true
|
||||||
logOp(b.log, deleteOp, prm.Address, b.storage[i].Storage.Type(), prm.StorageID)
|
logOp(b.log, deleteOp, prm.Address, b.storage[i].Storage.Type(), prm.StorageID)
|
||||||
}
|
}
|
||||||
return res, err
|
return res, err
|
||||||
|
@ -45,6 +55,7 @@ func (b *BlobStor) Delete(ctx context.Context, prm common.DeletePrm) (common.Del
|
||||||
|
|
||||||
res, err := st.Delete(ctx, prm)
|
res, err := st.Delete(ctx, prm)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
success = true
|
||||||
logOp(b.log, deleteOp, prm.Address, st.Type(), prm.StorageID)
|
logOp(b.log, deleteOp, prm.Address, st.Type(), prm.StorageID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ package blobstor
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
"time"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
||||||
|
@ -17,6 +18,14 @@ import (
|
||||||
// Returns any error encountered that did not allow
|
// Returns any error encountered that did not allow
|
||||||
// to completely check object existence.
|
// to completely check object existence.
|
||||||
func (b *BlobStor) Exists(ctx context.Context, prm common.ExistsPrm) (common.ExistsRes, error) {
|
func (b *BlobStor) Exists(ctx context.Context, prm common.ExistsPrm) (common.ExistsRes, error) {
|
||||||
|
var (
|
||||||
|
exists = false
|
||||||
|
startedAt = time.Now()
|
||||||
|
)
|
||||||
|
defer func() {
|
||||||
|
b.metrics.Exists(time.Since(startedAt), exists, prm.StorageID != nil)
|
||||||
|
}()
|
||||||
|
|
||||||
ctx, span := tracing.StartSpanFromContext(ctx, "BlobStor.Exists",
|
ctx, span := tracing.StartSpanFromContext(ctx, "BlobStor.Exists",
|
||||||
trace.WithAttributes(
|
trace.WithAttributes(
|
||||||
attribute.String("address", prm.Address.EncodeToString()),
|
attribute.String("address", prm.Address.EncodeToString()),
|
||||||
|
@ -29,9 +38,13 @@ func (b *BlobStor) Exists(ctx context.Context, prm common.ExistsPrm) (common.Exi
|
||||||
|
|
||||||
if prm.StorageID != nil {
|
if prm.StorageID != nil {
|
||||||
if len(prm.StorageID) == 0 {
|
if len(prm.StorageID) == 0 {
|
||||||
return b.storage[len(b.storage)-1].Storage.Exists(ctx, prm)
|
res, err := b.storage[len(b.storage)-1].Storage.Exists(ctx, prm)
|
||||||
|
exists = err == nil && res.Exists
|
||||||
|
return res, err
|
||||||
}
|
}
|
||||||
return b.storage[0].Storage.Exists(ctx, prm)
|
res, err := b.storage[0].Storage.Exists(ctx, prm)
|
||||||
|
exists = err == nil && res.Exists
|
||||||
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there was an error during existence check below,
|
// If there was an error during existence check below,
|
||||||
|
@ -47,6 +60,7 @@ func (b *BlobStor) Exists(ctx context.Context, prm common.ExistsPrm) (common.Exi
|
||||||
for i := range b.storage {
|
for i := range b.storage {
|
||||||
res, err := b.storage[i].Storage.Exists(ctx, prm)
|
res, err := b.storage[i].Storage.Exists(ctx, prm)
|
||||||
if err == nil && res.Exists {
|
if err == nil && res.Exists {
|
||||||
|
exists = true
|
||||||
return res, nil
|
return res, nil
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
errors = append(errors, err)
|
errors = append(errors, err)
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
|
"time"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/util/logicerr"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/util/logicerr"
|
||||||
|
@ -16,7 +17,14 @@ import (
|
||||||
// Get reads the object from b.
|
// Get reads the object from b.
|
||||||
// If the descriptor is present, only one sub-storage is tried,
|
// If the descriptor is present, only one sub-storage is tried,
|
||||||
// Otherwise, each sub-storage is tried in order.
|
// Otherwise, each sub-storage is tried in order.
|
||||||
func (b *BlobStor) Get(ctx context.Context, prm common.GetPrm) (common.GetRes, error) {
|
func (b *BlobStor) Get(ctx context.Context, prm common.GetPrm) (res common.GetRes, err error) {
|
||||||
|
var (
|
||||||
|
startedAt = time.Now()
|
||||||
|
)
|
||||||
|
defer func() {
|
||||||
|
b.metrics.Get(time.Since(startedAt), len(res.RawData), err == nil, prm.StorageID != nil)
|
||||||
|
}()
|
||||||
|
|
||||||
ctx, span := tracing.StartSpanFromContext(ctx, "BlobStor.Get",
|
ctx, span := tracing.StartSpanFromContext(ctx, "BlobStor.Get",
|
||||||
trace.WithAttributes(
|
trace.WithAttributes(
|
||||||
attribute.String("address", prm.Address.EncodeToString()),
|
attribute.String("address", prm.Address.EncodeToString()),
|
||||||
|
@ -30,7 +38,7 @@ func (b *BlobStor) Get(ctx context.Context, prm common.GetPrm) (common.GetRes, e
|
||||||
|
|
||||||
if prm.StorageID == nil {
|
if prm.StorageID == nil {
|
||||||
for i := range b.storage {
|
for i := range b.storage {
|
||||||
res, err := b.storage[i].Storage.Get(ctx, prm)
|
res, err = b.storage[i].Storage.Get(ctx, prm)
|
||||||
if err == nil || !errors.As(err, new(apistatus.ObjectNotFound)) {
|
if err == nil || !errors.As(err, new(apistatus.ObjectNotFound)) {
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
@ -39,7 +47,9 @@ func (b *BlobStor) Get(ctx context.Context, prm common.GetPrm) (common.GetRes, e
|
||||||
return common.GetRes{}, logicerr.Wrap(apistatus.ObjectNotFound{})
|
return common.GetRes{}, logicerr.Wrap(apistatus.ObjectNotFound{})
|
||||||
}
|
}
|
||||||
if len(prm.StorageID) == 0 {
|
if len(prm.StorageID) == 0 {
|
||||||
return b.storage[len(b.storage)-1].Storage.Get(ctx, prm)
|
res, err = b.storage[len(b.storage)-1].Storage.Get(ctx, prm)
|
||||||
|
} else {
|
||||||
|
res, err = b.storage[0].Storage.Get(ctx, prm)
|
||||||
}
|
}
|
||||||
return b.storage[0].Storage.Get(ctx, prm)
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/util/logicerr"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/util/logicerr"
|
||||||
|
@ -17,7 +18,14 @@ import (
|
||||||
// GetRange reads object payload data from b.
|
// GetRange reads object payload data from b.
|
||||||
// If the descriptor is present, only one sub-storage is tried,
|
// If the descriptor is present, only one sub-storage is tried,
|
||||||
// Otherwise, each sub-storage is tried in order.
|
// Otherwise, each sub-storage is tried in order.
|
||||||
func (b *BlobStor) GetRange(ctx context.Context, prm common.GetRangePrm) (common.GetRangeRes, error) {
|
func (b *BlobStor) GetRange(ctx context.Context, prm common.GetRangePrm) (res common.GetRangeRes, err error) {
|
||||||
|
var (
|
||||||
|
startedAt = time.Now()
|
||||||
|
)
|
||||||
|
defer func() {
|
||||||
|
b.metrics.GetRange(time.Since(startedAt), len(res.Data), err == nil, prm.StorageID != nil)
|
||||||
|
}()
|
||||||
|
|
||||||
ctx, span := tracing.StartSpanFromContext(ctx, "BlobStor.GetRange",
|
ctx, span := tracing.StartSpanFromContext(ctx, "BlobStor.GetRange",
|
||||||
trace.WithAttributes(
|
trace.WithAttributes(
|
||||||
attribute.String("address", prm.Address.EncodeToString()),
|
attribute.String("address", prm.Address.EncodeToString()),
|
||||||
|
@ -32,7 +40,7 @@ func (b *BlobStor) GetRange(ctx context.Context, prm common.GetRangePrm) (common
|
||||||
|
|
||||||
if prm.StorageID == nil {
|
if prm.StorageID == nil {
|
||||||
for i := range b.storage {
|
for i := range b.storage {
|
||||||
res, err := b.storage[i].Storage.GetRange(ctx, prm)
|
res, err = b.storage[i].Storage.GetRange(ctx, prm)
|
||||||
if err == nil || !errors.As(err, new(apistatus.ObjectNotFound)) {
|
if err == nil || !errors.As(err, new(apistatus.ObjectNotFound)) {
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
@ -41,7 +49,9 @@ func (b *BlobStor) GetRange(ctx context.Context, prm common.GetRangePrm) (common
|
||||||
return common.GetRangeRes{}, logicerr.Wrap(apistatus.ObjectNotFound{})
|
return common.GetRangeRes{}, logicerr.Wrap(apistatus.ObjectNotFound{})
|
||||||
}
|
}
|
||||||
if len(prm.StorageID) == 0 {
|
if len(prm.StorageID) == 0 {
|
||||||
return b.storage[len(b.storage)-1].Storage.GetRange(ctx, prm)
|
res, err = b.storage[len(b.storage)-1].Storage.GetRange(ctx, prm)
|
||||||
|
} else {
|
||||||
|
res, err = b.storage[0].Storage.GetRange(ctx, prm)
|
||||||
}
|
}
|
||||||
return b.storage[0].Storage.GetRange(ctx, prm)
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,10 +3,14 @@ package blobstor
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
|
||||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||||
|
"go.opentelemetry.io/otel/attribute"
|
||||||
|
"go.opentelemetry.io/otel/trace"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -18,6 +22,19 @@ import (
|
||||||
//
|
//
|
||||||
// If handler returns an error, method wraps and returns it immediately.
|
// If handler returns an error, method wraps and returns it immediately.
|
||||||
func (b *BlobStor) Iterate(ctx context.Context, prm common.IteratePrm) (common.IterateRes, error) {
|
func (b *BlobStor) Iterate(ctx context.Context, prm common.IteratePrm) (common.IterateRes, error) {
|
||||||
|
var (
|
||||||
|
startedAt = time.Now()
|
||||||
|
success = false
|
||||||
|
)
|
||||||
|
defer func() {
|
||||||
|
b.metrics.Iterate(time.Since(startedAt), success)
|
||||||
|
}()
|
||||||
|
ctx, span := tracing.StartSpanFromContext(ctx, "BlobStor.Iterate",
|
||||||
|
trace.WithAttributes(
|
||||||
|
attribute.Bool("ignore_errors", prm.IgnoreErrors),
|
||||||
|
))
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
b.modeMtx.RLock()
|
b.modeMtx.RLock()
|
||||||
defer b.modeMtx.RUnlock()
|
defer b.modeMtx.RUnlock()
|
||||||
|
|
||||||
|
@ -27,6 +44,7 @@ func (b *BlobStor) Iterate(ctx context.Context, prm common.IteratePrm) (common.I
|
||||||
return common.IterateRes{}, fmt.Errorf("blobstor iterator failure: %w", err)
|
return common.IterateRes{}, fmt.Errorf("blobstor iterator failure: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
success = true
|
||||||
return common.IterateRes{}, nil
|
return common.IterateRes{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
26
pkg/local_object_storage/blobstor/metrics.go
Normal file
26
pkg/local_object_storage/blobstor/metrics.go
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
package blobstor
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type Metrics interface {
|
||||||
|
SetMode(readOnly bool)
|
||||||
|
Close()
|
||||||
|
|
||||||
|
Delete(d time.Duration, success, withStorageID bool)
|
||||||
|
Exists(d time.Duration, success, withStorageID bool)
|
||||||
|
GetRange(d time.Duration, size int, success, withStorageID bool)
|
||||||
|
Get(d time.Duration, size int, success, withStorageID bool)
|
||||||
|
Iterate(d time.Duration, success bool)
|
||||||
|
Put(d time.Duration, size int, success bool)
|
||||||
|
}
|
||||||
|
|
||||||
|
type noopMetrics struct{}
|
||||||
|
|
||||||
|
func (m *noopMetrics) SetMode(bool) {}
|
||||||
|
func (m *noopMetrics) Close() {}
|
||||||
|
func (m *noopMetrics) Delete(time.Duration, bool, bool) {}
|
||||||
|
func (m *noopMetrics) Exists(time.Duration, bool, bool) {}
|
||||||
|
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) {}
|
|
@ -3,6 +3,7 @@ package blobstor
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/object"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/object"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
||||||
|
@ -26,6 +27,15 @@ var ErrNoPlaceFound = logicerr.New("couldn't find a place to store an object")
|
||||||
// Returns any error encountered that
|
// Returns any error encountered that
|
||||||
// did not allow to completely save the object.
|
// did not allow to completely save the object.
|
||||||
func (b *BlobStor) Put(ctx context.Context, prm common.PutPrm) (common.PutRes, error) {
|
func (b *BlobStor) Put(ctx context.Context, prm common.PutPrm) (common.PutRes, error) {
|
||||||
|
var (
|
||||||
|
startedAt = time.Now()
|
||||||
|
success = false
|
||||||
|
size = 0
|
||||||
|
)
|
||||||
|
defer func() {
|
||||||
|
b.metrics.Put(time.Since(startedAt), size, success)
|
||||||
|
}()
|
||||||
|
|
||||||
ctx, span := tracing.StartSpanFromContext(ctx, "BlobStor.Put",
|
ctx, span := tracing.StartSpanFromContext(ctx, "BlobStor.Put",
|
||||||
trace.WithAttributes(
|
trace.WithAttributes(
|
||||||
attribute.String("address", prm.Address.EncodeToString()),
|
attribute.String("address", prm.Address.EncodeToString()),
|
||||||
|
@ -47,11 +57,13 @@ func (b *BlobStor) Put(ctx context.Context, prm common.PutPrm) (common.PutRes, e
|
||||||
}
|
}
|
||||||
prm.RawData = data
|
prm.RawData = data
|
||||||
}
|
}
|
||||||
|
size = len(prm.RawData)
|
||||||
|
|
||||||
for i := range b.storage {
|
for i := range b.storage {
|
||||||
if b.storage[i].Policy == nil || b.storage[i].Policy(prm.Object, prm.RawData) {
|
if b.storage[i].Policy == nil || b.storage[i].Policy(prm.Object, prm.RawData) {
|
||||||
res, err := b.storage[i].Storage.Put(ctx, prm)
|
res, err := b.storage[i].Storage.Put(ctx, prm)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
success = true
|
||||||
logOp(b.log, putOp, prm.Address, b.storage[i].Storage.Type(), res.StorageID)
|
logOp(b.log, putOp, prm.Address, b.storage[i].Storage.Type(), res.StorageID)
|
||||||
}
|
}
|
||||||
return res, err
|
return res, err
|
||||||
|
|
Loading…
Reference in a new issue