Add initial stats
This commit is contained in:
parent
9e40d88265
commit
9aad0aa428
@ -214,6 +214,8 @@ func genericCreateCommand(
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger.Ctx(ictx).Infow("graph api stats", "stats", bo.Results.APIStats)
|
||||||
|
|
||||||
bIDs = append(bIDs, string(bo.Results.BackupID))
|
bIDs = append(bIDs, string(bo.Results.BackupID))
|
||||||
|
|
||||||
if !DisplayJSONFormat() {
|
if !DisplayJSONFormat() {
|
||||||
|
|||||||
@ -191,6 +191,8 @@ func QueueRequest(ctx context.Context) {
|
|||||||
if err := limiter.WaitN(ctx, consume); err != nil {
|
if err := limiter.WaitN(ctx, consume); err != nil {
|
||||||
logger.CtxErr(ctx, err).Error("graph middleware waiting on the limiter")
|
logger.CtxErr(ctx, err).Error("graph middleware waiting on the limiter")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add to the count bus
|
||||||
}
|
}
|
||||||
|
|
||||||
// RateLimiterMiddleware is used to ensure we don't overstep per-min request limits.
|
// RateLimiterMiddleware is used to ensure we don't overstep per-min request limits.
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/alcionai/clues"
|
"github.com/alcionai/clues"
|
||||||
@ -325,6 +326,8 @@ func (mw RetryMiddleware) getRetryDelay(
|
|||||||
// MetricsMiddleware aggregates per-request metrics on the events bus
|
// MetricsMiddleware aggregates per-request metrics on the events bus
|
||||||
type MetricsMiddleware struct{}
|
type MetricsMiddleware struct{}
|
||||||
|
|
||||||
|
var xmCount int64
|
||||||
|
|
||||||
const xmruHeader = "x-ms-resource-unit"
|
const xmruHeader = "x-ms-resource-unit"
|
||||||
|
|
||||||
func (mw *MetricsMiddleware) Intercept(
|
func (mw *MetricsMiddleware) Intercept(
|
||||||
@ -362,6 +365,9 @@ func (mw *MetricsMiddleware) Intercept(
|
|||||||
xmrui = 1
|
xmrui = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
atomic.AddInt64(&xmCount, int64(xmrui))
|
||||||
|
logger.Ctx(req.Context()).Info("xmcount ", xmCount)
|
||||||
|
|
||||||
countBus := count.Ctx(req.Context())
|
countBus := count.Ctx(req.Context())
|
||||||
countBus.Add(count.APICallTokensConsumed, int64(xmrui))
|
countBus.Add(count.APICallTokensConsumed, int64(xmrui))
|
||||||
|
|
||||||
|
|||||||
@ -70,6 +70,7 @@ type BackupResults struct {
|
|||||||
BackupID model.StableID `json:"backupID"`
|
BackupID model.StableID `json:"backupID"`
|
||||||
// keys are found in /pkg/count/keys.go
|
// keys are found in /pkg/count/keys.go
|
||||||
Counts map[string]int64 `json:"counts"`
|
Counts map[string]int64 `json:"counts"`
|
||||||
|
stats.APIStats
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewBackupOperation constructs and validates a backup operation.
|
// NewBackupOperation constructs and validates a backup operation.
|
||||||
@ -846,6 +847,10 @@ func (op *BackupOperation) persistResults(
|
|||||||
|
|
||||||
op.Results.ItemsRead = opStats.ctrl.Successes
|
op.Results.ItemsRead = opStats.ctrl.Successes
|
||||||
|
|
||||||
|
// API stats
|
||||||
|
apiStats := stats.GetAPIStats(op.Counter)
|
||||||
|
op.Results.TokensConsumed = apiStats.TokensConsumed
|
||||||
|
|
||||||
// Only return non-recoverable errors at this point.
|
// Only return non-recoverable errors at this point.
|
||||||
return op.Errors.Failure()
|
return op.Errors.Failure()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,8 @@ package stats
|
|||||||
import (
|
import (
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/alcionai/corso/src/pkg/count"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ReadWrites tracks the total count of reads and writes. ItemsRead
|
// ReadWrites tracks the total count of reads and writes. ItemsRead
|
||||||
@ -43,3 +45,21 @@ type SkippedCounts struct {
|
|||||||
SkippedMalware int `json:"skippedMalware"`
|
SkippedMalware int `json:"skippedMalware"`
|
||||||
SkippedInvalidOneNoteFile int `json:"skippedInvalidOneNoteFile"`
|
SkippedInvalidOneNoteFile int `json:"skippedInvalidOneNoteFile"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type APIStats struct {
|
||||||
|
TokensConsumed int64 `json:"tokensConsumed"`
|
||||||
|
// PeakTokenUsage is the maximum number of tokens used during a
|
||||||
|
// rolling 1 minute window.
|
||||||
|
PeakTokenUsagePerMin int64 `json:"peakTokenUsage"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetAPIStats(
|
||||||
|
ctr *count.Bus,
|
||||||
|
) APIStats {
|
||||||
|
s := APIStats{}
|
||||||
|
|
||||||
|
s.TokensConsumed = ctr.Total(count.APICallTokensConsumed)
|
||||||
|
s.PeakTokenUsagePerMin = ctr.Get(count.PeakAPITokenUsagePerMin)
|
||||||
|
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|||||||
@ -4,7 +4,8 @@ type key string
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
// count of bucket-tokens consumed by api calls.
|
// count of bucket-tokens consumed by api calls.
|
||||||
APICallTokensConsumed key = "api-call-tokens-consumed"
|
APICallTokensConsumed key = "api-call-tokens-consumed"
|
||||||
|
PeakAPITokenUsagePerMin key = "peak-api-token-usage-per-min"
|
||||||
// count of api calls that resulted in failure due to throttling.
|
// count of api calls that resulted in failure due to throttling.
|
||||||
ThrottledAPICalls key = "throttled-api-calls"
|
ThrottledAPICalls key = "throttled-api-calls"
|
||||||
)
|
)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user