2019-06-25 21:58:38 +01:00
|
|
|
// Copyright (C) 2019 Storj Labs, Inc.
|
|
|
|
// See LICENSE for copying information.
|
|
|
|
|
|
|
|
package reports
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"encoding/csv"
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"os"
|
|
|
|
"strconv"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/zeebo/errs"
|
|
|
|
"go.uber.org/zap"
|
|
|
|
|
2019-12-27 11:48:47 +00:00
|
|
|
"storj.io/common/memory"
|
2020-03-30 10:08:50 +01:00
|
|
|
"storj.io/common/uuid"
|
2019-06-25 21:58:38 +01:00
|
|
|
"storj.io/storj/satellite/attribution"
|
|
|
|
"storj.io/storj/satellite/satellitedb"
|
|
|
|
)
|
|
|
|
|
|
|
|
var headers = []string{
|
|
|
|
"projectID",
|
|
|
|
"bucketName",
|
|
|
|
"byte-hours:Remote",
|
|
|
|
"byte-hours:Inline",
|
|
|
|
"bytes:BWEgress",
|
|
|
|
}
|
|
|
|
|
2020-07-16 15:18:02 +01:00
|
|
|
// GenerateAttributionCSV creates a report with.
|
2019-06-25 21:58:38 +01:00
|
|
|
func GenerateAttributionCSV(ctx context.Context, database string, partnerID uuid.UUID, start time.Time, end time.Time, output io.Writer) error {
|
|
|
|
log := zap.L().Named("db")
|
2020-01-10 01:12:27 +00:00
|
|
|
db, err := satellitedb.New(log, database, satellitedb.Options{})
|
2019-06-25 21:58:38 +01:00
|
|
|
if err != nil {
|
|
|
|
return errs.New("error connecting to master database on satellite: %+v", err)
|
|
|
|
}
|
|
|
|
defer func() {
|
|
|
|
err = errs.Combine(err, db.Close())
|
|
|
|
if err != nil {
|
2020-04-13 10:31:17 +01:00
|
|
|
log.Error("Error closing satellite DB connection after retrieving partner value attribution data.", zap.Error(err))
|
2019-06-25 21:58:38 +01:00
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
|
|
|
rows, err := db.Attribution().QueryAttribution(ctx, partnerID, start, end)
|
|
|
|
if err != nil {
|
|
|
|
return errs.Wrap(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
w := csv.NewWriter(output)
|
|
|
|
defer func() {
|
|
|
|
w.Flush()
|
|
|
|
}()
|
|
|
|
|
|
|
|
if err := w.Write(headers); err != nil {
|
|
|
|
return errs.Wrap(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, row := range rows {
|
|
|
|
record, err := csvRowToStringSlice(row)
|
|
|
|
if err != nil {
|
|
|
|
return errs.Wrap(err)
|
|
|
|
}
|
|
|
|
if err := w.Write(record); err != nil {
|
|
|
|
return errs.Wrap(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if err := w.Error(); err != nil {
|
|
|
|
return errs.Wrap(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if output != os.Stdout {
|
|
|
|
fmt.Println("Generated report for partner attribution")
|
|
|
|
}
|
|
|
|
return errs.Wrap(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
func csvRowToStringSlice(p *attribution.CSVRow) ([]string, error) {
|
2020-03-31 17:49:16 +01:00
|
|
|
projectID, err := uuid.FromBytes(p.ProjectID)
|
2019-06-25 21:58:38 +01:00
|
|
|
if err != nil {
|
|
|
|
return nil, errs.New("Invalid Project ID")
|
|
|
|
}
|
|
|
|
remoteGBPerHour := memory.Size(p.RemoteBytesPerHour).GB()
|
|
|
|
inlineGBPerHour := memory.Size(p.InlineBytesPerHour).GB()
|
|
|
|
egressGBData := memory.Size(p.EgressData).GB()
|
|
|
|
record := []string{
|
|
|
|
projectID.String(),
|
|
|
|
string(p.BucketName),
|
|
|
|
strconv.FormatFloat(remoteGBPerHour, 'f', 4, 64),
|
|
|
|
strconv.FormatFloat(inlineGBPerHour, 'f', 4, 64),
|
|
|
|
strconv.FormatFloat(egressGBData, 'f', 4, 64),
|
|
|
|
}
|
|
|
|
return record, nil
|
|
|
|
}
|