Skip to content

Commit 2d0b1a1

Browse files
easyCZroboquat
authored andcommitted
[usage] Report upload/download metrics for usage report
1 parent 1c3090f commit 2d0b1a1

File tree

3 files changed

+80
-3
lines changed

3 files changed

+80
-3
lines changed

components/usage/pkg/contentservice/client.go

+13-3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"encoding/json"
1212
"fmt"
1313
"net/http"
14+
"time"
1415

1516
"github.com/gitpod-io/gitpod/common-go/log"
1617
"github.com/gitpod-io/gitpod/content-service/api"
@@ -29,7 +30,12 @@ func New(service api.UsageReportServiceClient) *Client {
2930
return &Client{service: service}
3031
}
3132

32-
func (c *Client) UploadUsageReport(ctx context.Context, filename string, report UsageReport) error {
33+
func (c *Client) UploadUsageReport(ctx context.Context, filename string, report UsageReport) (err error) {
34+
start := time.Now()
35+
defer func() {
36+
observeReportUploadDuration(time.Since(start), err)
37+
}()
38+
3339
uploadURLResp, err := c.service.UploadURL(ctx, &api.UsageReportUploadURLRequest{Name: filename})
3440
if err != nil {
3541
return fmt.Errorf("failed to get upload URL from usage report service: %w", err)
@@ -67,7 +73,12 @@ func (c *Client) UploadUsageReport(ctx context.Context, filename string, report
6773
return nil
6874
}
6975

70-
func (c *Client) DownloadUsageReport(ctx context.Context, filename string) (UsageReport, error) {
76+
func (c *Client) DownloadUsageReport(ctx context.Context, filename string) (report UsageReport, err error) {
77+
start := time.Now()
78+
defer func() {
79+
observeReportDownloadDuration(time.Since(start), err)
80+
}()
81+
7182
downloadURlResp, err := c.service.DownloadURL(ctx, &api.UsageReportDownloadURLRequest{
7283
Name: filename,
7384
})
@@ -104,7 +115,6 @@ func (c *Client) DownloadUsageReport(ctx context.Context, filename string) (Usag
104115
defer decompressor.Close()
105116

106117
decoder := json.NewDecoder(decompressor)
107-
var report UsageReport
108118
if err := decoder.Decode(&report); err != nil {
109119
return UsageReport{}, fmt.Errorf("failed to deserialize report: %w", err)
110120
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// Copyright (c) 2022 Gitpod GmbH. All rights reserved.
2+
// Licensed under the GNU Affero General Public License (AGPL).
3+
// See License-AGPL.txt in the project root for license information.
4+
5+
package contentservice
6+
7+
import (
8+
"fmt"
9+
"github.com/prometheus/client_golang/prometheus"
10+
"time"
11+
)
12+
13+
const (
14+
namespace = "gitpod"
15+
subsystem = "usage"
16+
)
17+
18+
var (
19+
reportUploadDurationSeconds = prometheus.NewHistogramVec(prometheus.HistogramOpts{
20+
Namespace: namespace,
21+
Subsystem: subsystem,
22+
Name: "report_upload_duration_seconds",
23+
Help: "Histogram of time it takes (in seconds) to upload a usage report to content service",
24+
}, []string{"outcome"})
25+
26+
reportDownloadDurationSeconds = prometheus.NewHistogramVec(prometheus.HistogramOpts{
27+
Namespace: namespace,
28+
Subsystem: subsystem,
29+
Name: "report_download_duration_seconds",
30+
Help: "Histogram of time it takes (in seconds) to download usage report from content service",
31+
}, []string{"outcome"})
32+
)
33+
34+
func RegisterMetrics(reg *prometheus.Registry) error {
35+
metrics := []prometheus.Collector{
36+
reportUploadDurationSeconds,
37+
reportDownloadDurationSeconds,
38+
}
39+
for _, metric := range metrics {
40+
err := reg.Register(metric)
41+
if err != nil {
42+
return fmt.Errorf("failed to register metric: %w", err)
43+
}
44+
}
45+
46+
return nil
47+
}
48+
49+
func observeReportUploadDuration(d time.Duration, err error) {
50+
outcome := "ok"
51+
if err != nil {
52+
outcome = "error"
53+
}
54+
reportUploadDurationSeconds.WithLabelValues(outcome).Observe(d.Seconds())
55+
}
56+
57+
func observeReportDownloadDuration(d time.Duration, err error) {
58+
outcome := "ok"
59+
if err != nil {
60+
outcome = "error"
61+
}
62+
reportDownloadDurationSeconds.WithLabelValues(outcome).Observe(d.Seconds())
63+
}

components/usage/pkg/server/server.go

+4
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,10 @@ func Start(cfg Config) error {
130130
log.Info("No controller schedule specified, controller will be disabled.")
131131
}
132132

133+
err = contentservice.RegisterMetrics(srv.MetricsRegistry())
134+
if err != nil {
135+
return fmt.Errorf("failed to register content service metrics: %w", err)
136+
}
133137
var contentService contentservice.Interface = &contentservice.NoOpClient{}
134138
if cfg.ContentServiceAddress != "" {
135139
contentServiceConn, err := grpc.Dial(cfg.ContentServiceAddress, grpc.WithTransportCredentials(insecure.NewCredentials()))

0 commit comments

Comments
 (0)