108 lines
3.1 KiB
Go
108 lines
3.1 KiB
Go
// Copyright (C) 2019 Storj Labs, Inc.
|
|
// See LICENSE for copying information.
|
|
|
|
package satellitedb
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"github.com/skyrings/skyring-common/tools/uuid"
|
|
"github.com/zeebo/errs"
|
|
|
|
"storj.io/storj/internal/memory"
|
|
"storj.io/storj/pkg/pb"
|
|
"storj.io/storj/satellite/console"
|
|
dbx "storj.io/storj/satellite/satellitedb/dbx"
|
|
)
|
|
|
|
// usagerollups implements console.UsageRollups
|
|
type usagerollups struct {
|
|
db *dbx.DB
|
|
}
|
|
|
|
// GetProjectTotal retrieves project usage for a given period
|
|
func (db *usagerollups) GetProjectTotal(ctx context.Context, projectID uuid.UUID, since, before time.Time) (usage *console.ProjectUsage, err error) {
|
|
storageQuery := db.db.All_BucketStorageTally_By_ProjectId_And_BucketName_And_IntervalStart_GreaterOrEqual_And_IntervalStart_LessOrEqual_OrderBy_Desc_IntervalStart
|
|
|
|
roullupsQuery := `SELECT SUM(settled), SUM(inline), action
|
|
FROM bucket_bandwidth_rollups
|
|
WHERE project_id = ? AND interval_start >= ? AND interval_start <= ?
|
|
GROUP BY action`
|
|
|
|
rollupsRows, err := db.db.QueryContext(ctx, db.db.Rebind(roullupsQuery), []byte(projectID.String()), since, before)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer func() { err = errs.Combine(err, rollupsRows.Close()) }()
|
|
|
|
var totalEgress int64
|
|
for rollupsRows.Next() {
|
|
var action pb.PieceAction
|
|
var settled, inline int64
|
|
|
|
err = rollupsRows.Scan(&settled, &inline, &action)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// add values for egress
|
|
if action == pb.PieceAction_GET || action == pb.PieceAction_GET_AUDIT || action == pb.PieceAction_GET_REPAIR {
|
|
totalEgress += settled + inline
|
|
}
|
|
}
|
|
|
|
bucketsQuery := "SELECT DISTINCT bucket_name FROM bucket_bandwidth_rollups where project_id = ? and interval_start >= ? and interval_start <= ?"
|
|
bucketRows, err := db.db.QueryContext(ctx, db.db.Rebind(bucketsQuery), []byte(projectID.String()), since, before)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer func() { err = errs.Combine(err, bucketRows.Close()) }()
|
|
|
|
var buckets []string
|
|
for bucketRows.Next() {
|
|
var bucket string
|
|
err = bucketRows.Scan(&bucket)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
buckets = append(buckets, bucket)
|
|
}
|
|
|
|
bucketsTallies := make(map[string]*[]*dbx.BucketStorageTally)
|
|
for _, bucket := range buckets {
|
|
storageTallies, err := storageQuery(ctx,
|
|
dbx.BucketStorageTally_ProjectId([]byte(projectID.String())),
|
|
dbx.BucketStorageTally_BucketName([]byte(bucket)),
|
|
dbx.BucketStorageTally_IntervalStart(since),
|
|
dbx.BucketStorageTally_IntervalStart(before))
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
bucketsTallies[bucket] = &storageTallies
|
|
}
|
|
|
|
usage = new(console.ProjectUsage)
|
|
usage.Egress = memory.Size(totalEgress).GB()
|
|
|
|
// sum up storage and objects
|
|
for _, tallies := range bucketsTallies {
|
|
for i := len(*tallies) - 1; i > 0; i-- {
|
|
current := (*tallies)[i]
|
|
|
|
hours := (*tallies)[i-1].IntervalStart.Sub(current.IntervalStart).Hours()
|
|
|
|
usage.Storage += memory.Size(current.Inline).GB() * hours
|
|
usage.Storage += memory.Size(current.Remote).GB() * hours
|
|
usage.ObjectsCount += float64(current.ObjectCount) * hours
|
|
}
|
|
}
|
|
|
|
usage.Since = since
|
|
usage.Before = before
|
|
return usage, nil
|
|
}
|