mirror of
https://github.com/ferdzo/fs.git
synced 2026-04-05 14:06:25 +00:00
Initial metrics endpoint added in Prometheus style
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"fs/metrics"
|
||||
"fs/models"
|
||||
"net"
|
||||
"regexp"
|
||||
@@ -47,7 +48,7 @@ func NewMetadataHandler(dbPath string) (*MetadataHandler, error) {
|
||||
}
|
||||
h := &MetadataHandler{db: db}
|
||||
|
||||
err = h.db.Update(func(tx *bbolt.Tx) error {
|
||||
err = h.update(func(tx *bbolt.Tx) error {
|
||||
_, err := tx.CreateBucketIfNotExists(systemIndex)
|
||||
return err
|
||||
})
|
||||
@@ -55,7 +56,7 @@ func NewMetadataHandler(dbPath string) (*MetadataHandler, error) {
|
||||
_ = db.Close()
|
||||
return nil, err
|
||||
}
|
||||
err = h.db.Update(func(tx *bbolt.Tx) error {
|
||||
err = h.update(func(tx *bbolt.Tx) error {
|
||||
_, err := tx.CreateBucketIfNotExists(multipartUploadIndex)
|
||||
return err
|
||||
})
|
||||
@@ -63,7 +64,7 @@ func NewMetadataHandler(dbPath string) (*MetadataHandler, error) {
|
||||
_ = db.Close()
|
||||
return nil, err
|
||||
}
|
||||
err = h.db.Update(func(tx *bbolt.Tx) error {
|
||||
err = h.update(func(tx *bbolt.Tx) error {
|
||||
_, err := tx.CreateBucketIfNotExists(multipartUploadPartsIndex)
|
||||
return err
|
||||
})
|
||||
@@ -71,7 +72,7 @@ func NewMetadataHandler(dbPath string) (*MetadataHandler, error) {
|
||||
_ = db.Close()
|
||||
return nil, err
|
||||
}
|
||||
err = h.db.Update(func(tx *bbolt.Tx) error {
|
||||
err = h.update(func(tx *bbolt.Tx) error {
|
||||
_, err := tx.CreateBucketIfNotExists(authIdentitiesIndex)
|
||||
return err
|
||||
})
|
||||
@@ -79,7 +80,7 @@ func NewMetadataHandler(dbPath string) (*MetadataHandler, error) {
|
||||
_ = db.Close()
|
||||
return nil, err
|
||||
}
|
||||
err = h.db.Update(func(tx *bbolt.Tx) error {
|
||||
err = h.update(func(tx *bbolt.Tx) error {
|
||||
_, err := tx.CreateBucketIfNotExists(authPoliciesIndex)
|
||||
return err
|
||||
})
|
||||
@@ -119,6 +120,20 @@ func (h *MetadataHandler) Close() error {
|
||||
return h.db.Close()
|
||||
}
|
||||
|
||||
func (h *MetadataHandler) view(fn func(tx *bbolt.Tx) error) error {
|
||||
start := time.Now()
|
||||
err := h.db.View(fn)
|
||||
metrics.Default.ObserveMetadataTx("view", time.Since(start), err == nil)
|
||||
return err
|
||||
}
|
||||
|
||||
func (h *MetadataHandler) update(fn func(tx *bbolt.Tx) error) error {
|
||||
start := time.Now()
|
||||
err := h.db.Update(fn)
|
||||
metrics.Default.ObserveMetadataTx("update", time.Since(start), err == nil)
|
||||
return err
|
||||
}
|
||||
|
||||
func (h *MetadataHandler) PutAuthIdentity(identity *models.AuthIdentity) error {
|
||||
if identity == nil {
|
||||
return errors.New("auth identity is required")
|
||||
@@ -126,7 +141,7 @@ func (h *MetadataHandler) PutAuthIdentity(identity *models.AuthIdentity) error {
|
||||
if strings.TrimSpace(identity.AccessKeyID) == "" {
|
||||
return errors.New("access key id is required")
|
||||
}
|
||||
return h.db.Update(func(tx *bbolt.Tx) error {
|
||||
return h.update(func(tx *bbolt.Tx) error {
|
||||
bucket := tx.Bucket(authIdentitiesIndex)
|
||||
if bucket == nil {
|
||||
return errors.New("auth identities index not found")
|
||||
@@ -146,7 +161,7 @@ func (h *MetadataHandler) GetAuthIdentity(accessKeyID string) (*models.AuthIdent
|
||||
}
|
||||
|
||||
var identity *models.AuthIdentity
|
||||
err := h.db.View(func(tx *bbolt.Tx) error {
|
||||
err := h.view(func(tx *bbolt.Tx) error {
|
||||
bucket := tx.Bucket(authIdentitiesIndex)
|
||||
if bucket == nil {
|
||||
return errors.New("auth identities index not found")
|
||||
@@ -177,7 +192,7 @@ func (h *MetadataHandler) PutAuthPolicy(policy *models.AuthPolicy) error {
|
||||
return errors.New("auth policy principal is required")
|
||||
}
|
||||
policy.Principal = principal
|
||||
return h.db.Update(func(tx *bbolt.Tx) error {
|
||||
return h.update(func(tx *bbolt.Tx) error {
|
||||
bucket := tx.Bucket(authPoliciesIndex)
|
||||
if bucket == nil {
|
||||
return errors.New("auth policies index not found")
|
||||
@@ -197,7 +212,7 @@ func (h *MetadataHandler) GetAuthPolicy(accessKeyID string) (*models.AuthPolicy,
|
||||
}
|
||||
|
||||
var policy *models.AuthPolicy
|
||||
err := h.db.View(func(tx *bbolt.Tx) error {
|
||||
err := h.view(func(tx *bbolt.Tx) error {
|
||||
bucket := tx.Bucket(authPoliciesIndex)
|
||||
if bucket == nil {
|
||||
return errors.New("auth policies index not found")
|
||||
@@ -224,7 +239,7 @@ func (h *MetadataHandler) CreateBucket(bucketName string) error {
|
||||
return fmt.Errorf("%w: %s", ErrInvalidBucketName, bucketName)
|
||||
}
|
||||
|
||||
err := h.db.Update(func(tx *bbolt.Tx) error {
|
||||
err := h.update(func(tx *bbolt.Tx) error {
|
||||
indexBucket, err := tx.CreateBucketIfNotExists([]byte(systemIndex))
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -256,7 +271,7 @@ func (h *MetadataHandler) DeleteBucket(bucketName string) error {
|
||||
return fmt.Errorf("%w: %s", ErrInvalidBucketName, bucketName)
|
||||
}
|
||||
|
||||
err := h.db.Update(func(tx *bbolt.Tx) error {
|
||||
err := h.update(func(tx *bbolt.Tx) error {
|
||||
indexBucket, err := tx.CreateBucketIfNotExists([]byte(systemIndex))
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -303,7 +318,7 @@ func (h *MetadataHandler) DeleteBucket(bucketName string) error {
|
||||
|
||||
func (h *MetadataHandler) ListBuckets() ([]string, error) {
|
||||
buckets := []string{}
|
||||
err := h.db.View(func(tx *bbolt.Tx) error {
|
||||
err := h.view(func(tx *bbolt.Tx) error {
|
||||
systemIndexBucket := tx.Bucket([]byte(systemIndex))
|
||||
if systemIndexBucket == nil {
|
||||
return errors.New("system index not found")
|
||||
@@ -323,7 +338,7 @@ func (h *MetadataHandler) ListBuckets() ([]string, error) {
|
||||
func (h *MetadataHandler) GetBucketManifest(bucketName string) (*models.BucketManifest, error) {
|
||||
var manifest *models.BucketManifest
|
||||
|
||||
err := h.db.View(func(tx *bbolt.Tx) error {
|
||||
err := h.view(func(tx *bbolt.Tx) error {
|
||||
systemIndexBucket := tx.Bucket([]byte(systemIndex))
|
||||
if systemIndexBucket == nil {
|
||||
return errors.New("system index not found")
|
||||
@@ -353,7 +368,7 @@ func (h *MetadataHandler) PutManifest(manifest *models.ObjectManifest) error {
|
||||
return err
|
||||
}
|
||||
|
||||
err := h.db.Update(func(tx *bbolt.Tx) error {
|
||||
err := h.update(func(tx *bbolt.Tx) error {
|
||||
data, err := json.Marshal(manifest)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -373,7 +388,7 @@ func (h *MetadataHandler) PutManifest(manifest *models.ObjectManifest) error {
|
||||
func (h *MetadataHandler) GetManifest(bucket, key string) (*models.ObjectManifest, error) {
|
||||
var manifest *models.ObjectManifest
|
||||
|
||||
err := h.db.View(func(tx *bbolt.Tx) error {
|
||||
err := h.view(func(tx *bbolt.Tx) error {
|
||||
metadataBucket := tx.Bucket([]byte(bucket))
|
||||
if metadataBucket == nil {
|
||||
return fmt.Errorf("%w: %s", ErrBucketNotFound, bucket)
|
||||
@@ -400,7 +415,7 @@ func (h *MetadataHandler) ListObjects(bucket, prefix string) ([]*models.ObjectMa
|
||||
|
||||
var objects []*models.ObjectManifest
|
||||
|
||||
err := h.db.View(func(tx *bbolt.Tx) error {
|
||||
err := h.view(func(tx *bbolt.Tx) error {
|
||||
systemIndexBucket := tx.Bucket([]byte(systemIndex))
|
||||
if systemIndexBucket == nil {
|
||||
return errors.New("system index not found")
|
||||
@@ -440,7 +455,7 @@ func (h *MetadataHandler) ForEachObjectFrom(bucket, startKey string, fn func(*mo
|
||||
return errors.New("object callback is required")
|
||||
}
|
||||
|
||||
return h.db.View(func(tx *bbolt.Tx) error {
|
||||
return h.view(func(tx *bbolt.Tx) error {
|
||||
systemIndexBucket := tx.Bucket([]byte(systemIndex))
|
||||
if systemIndexBucket == nil {
|
||||
return errors.New("system index not found")
|
||||
@@ -480,7 +495,7 @@ func (h *MetadataHandler) DeleteManifest(bucket, key string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
err := h.db.Update(func(tx *bbolt.Tx) error {
|
||||
err := h.update(func(tx *bbolt.Tx) error {
|
||||
metadataBucket := tx.Bucket([]byte(bucket))
|
||||
if metadataBucket == nil {
|
||||
return fmt.Errorf("%w: %s", ErrBucketNotFound, bucket)
|
||||
@@ -497,7 +512,7 @@ func (h *MetadataHandler) DeleteManifest(bucket, key string) error {
|
||||
func (h *MetadataHandler) DeleteManifests(bucket string, keys []string) ([]string, error) {
|
||||
deleted := make([]string, 0, len(keys))
|
||||
|
||||
err := h.db.Update(func(tx *bbolt.Tx) error {
|
||||
err := h.update(func(tx *bbolt.Tx) error {
|
||||
metadataBucket := tx.Bucket([]byte(bucket))
|
||||
if metadataBucket == nil {
|
||||
return fmt.Errorf("%w: %s", ErrBucketNotFound, bucket)
|
||||
@@ -525,7 +540,7 @@ func (h *MetadataHandler) DeleteManifests(bucket string, keys []string) ([]strin
|
||||
func (h *MetadataHandler) CreateMultipartUpload(bucket, key string) (*models.MultipartUpload, error) {
|
||||
var upload *models.MultipartUpload
|
||||
|
||||
err := h.db.View(func(tx *bbolt.Tx) error {
|
||||
err := h.view(func(tx *bbolt.Tx) error {
|
||||
systemIndexBucket := tx.Bucket([]byte(systemIndex))
|
||||
if systemIndexBucket == nil {
|
||||
return errors.New("system index not found")
|
||||
@@ -548,7 +563,7 @@ func (h *MetadataHandler) CreateMultipartUpload(bucket, key string) (*models.Mul
|
||||
State: "pending",
|
||||
}
|
||||
|
||||
err = h.db.Update(func(tx *bbolt.Tx) error {
|
||||
err = h.update(func(tx *bbolt.Tx) error {
|
||||
multipartUploadBucket := tx.Bucket([]byte(multipartUploadIndex))
|
||||
if multipartUploadBucket == nil {
|
||||
return errors.New("multipart upload index not found")
|
||||
@@ -643,7 +658,7 @@ func deleteMultipartPartsByUploadID(tx *bbolt.Tx, uploadID string) error {
|
||||
|
||||
func (h *MetadataHandler) GetMultipartUpload(uploadID string) (*models.MultipartUpload, error) {
|
||||
var upload *models.MultipartUpload
|
||||
err := h.db.View(func(tx *bbolt.Tx) error {
|
||||
err := h.view(func(tx *bbolt.Tx) error {
|
||||
var err error
|
||||
upload, _, err = getMultipartUploadFromTx(tx, uploadID)
|
||||
if err != nil {
|
||||
@@ -661,7 +676,7 @@ func (h *MetadataHandler) PutMultipartPart(uploadID string, part models.Uploaded
|
||||
return fmt.Errorf("invalid part number: %d", part.PartNumber)
|
||||
}
|
||||
|
||||
err := h.db.Update(func(tx *bbolt.Tx) error {
|
||||
err := h.update(func(tx *bbolt.Tx) error {
|
||||
upload, _, err := getMultipartUploadFromTx(tx, uploadID)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -690,7 +705,7 @@ func (h *MetadataHandler) PutMultipartPart(uploadID string, part models.Uploaded
|
||||
func (h *MetadataHandler) ListMultipartParts(uploadID string) ([]models.UploadedPart, error) {
|
||||
parts := make([]models.UploadedPart, 0)
|
||||
|
||||
err := h.db.View(func(tx *bbolt.Tx) error {
|
||||
err := h.view(func(tx *bbolt.Tx) error {
|
||||
if _, _, err := getMultipartUploadFromTx(tx, uploadID); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -724,7 +739,7 @@ func (h *MetadataHandler) CompleteMultipartUpload(uploadID string, final *models
|
||||
return errors.New("final object manifest is required")
|
||||
}
|
||||
|
||||
err := h.db.Update(func(tx *bbolt.Tx) error {
|
||||
err := h.update(func(tx *bbolt.Tx) error {
|
||||
upload, multipartUploadBucket, err := getMultipartUploadFromTx(tx, uploadID)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -763,7 +778,7 @@ func (h *MetadataHandler) CompleteMultipartUpload(uploadID string, final *models
|
||||
return nil
|
||||
}
|
||||
func (h *MetadataHandler) AbortMultipartUpload(uploadID string) error {
|
||||
err := h.db.Update(func(tx *bbolt.Tx) error {
|
||||
err := h.update(func(tx *bbolt.Tx) error {
|
||||
upload, multipartUploadBucket, err := getMultipartUploadFromTx(tx, uploadID)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -793,7 +808,7 @@ func (h *MetadataHandler) CleanupMultipartUploads(retention time.Duration) (int,
|
||||
}
|
||||
|
||||
cleaned := 0
|
||||
err := h.db.Update(func(tx *bbolt.Tx) error {
|
||||
err := h.update(func(tx *bbolt.Tx) error {
|
||||
uploadsBucket, err := getMultipartUploadBucket(tx)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -843,7 +858,7 @@ func (h *MetadataHandler) GetReferencedChunkSet() (map[string]struct{}, error) {
|
||||
chunkSet := make(map[string]struct{})
|
||||
pendingUploadSet := make(map[string]struct{})
|
||||
|
||||
err := h.db.View(func(tx *bbolt.Tx) error {
|
||||
err := h.view(func(tx *bbolt.Tx) error {
|
||||
systemIndexBucket := tx.Bucket([]byte(systemIndex))
|
||||
if systemIndexBucket == nil {
|
||||
return errors.New("system index not found")
|
||||
|
||||
Reference in New Issue
Block a user