feat(pkger): add metrics svc middleware

pull/16706/head
Johnny Steenbergen 2020-02-03 09:39:01 -08:00 committed by Johnny Steenbergen
parent d283a875e4
commit f9ed0ccb82
3 changed files with 120 additions and 0 deletions

View File

@ -831,6 +831,7 @@ func (m *Launcher) run(ctx context.Context) (err error) {
pkger.WithVariableSVC(authorizer.NewVariableService(b.VariableService)),
)
pkgSVC = pkger.MWTracing()(pkgSVC)
pkgSVC = pkger.MWMetrics(m.reg)(pkgSVC)
pkgSVC = pkger.MWLogging(pkgerLogger)(pkgSVC)
}

73
kit/metric/client.go Normal file
View File

@ -0,0 +1,73 @@
package metric
import (
"fmt"
"time"
"github.com/influxdata/influxdb"
"github.com/influxdata/influxdb/kit/prom"
"github.com/prometheus/client_golang/prometheus"
)
// REDClient is a metrics client for collection RED metrics.
type REDClient struct {
// RED metrics
reqs *prometheus.CounterVec
errs *prometheus.CounterVec
durs *prometheus.HistogramVec
}
// New creates a new REDClient.
func New(reg *prom.Registry, service string) *REDClient {
// MiddlewareMetrics is a metrics service middleware for the notification endpoint service.
const namespace = "service"
reqs := prometheus.NewCounterVec(prometheus.CounterOpts{
Namespace: namespace,
Subsystem: service,
Name: "call_total",
Help: fmt.Sprintf("Number of calls to the %s service", service),
}, []string{"method"})
errs := prometheus.NewCounterVec(prometheus.CounterOpts{
Namespace: namespace,
Subsystem: service,
Name: "error_total",
Help: fmt.Sprintf("Number of errors encountered when calling the %s service", service),
}, []string{"method", "code"})
durs := prometheus.NewHistogramVec(prometheus.HistogramOpts{
Namespace: namespace,
Subsystem: service,
Name: "duration",
Help: fmt.Sprintf("Duration of %s service calls", service),
}, []string{"method"})
reg.MustRegister(reqs, errs, durs)
return &REDClient{
reqs: reqs,
errs: errs,
durs: durs,
}
}
// Record returns a record fn that is called on any given return err. If an error is encountered
// it will register the err metric. The err is never altered.
func (c *REDClient) Record(method string) func(error) error {
start := time.Now()
return func(err error) error {
c.reqs.With(prometheus.Labels{"method": method})
if err != nil {
c.errs.With(prometheus.Labels{
"method": method,
"code": influxdb.ErrorCode(err),
}).Inc()
}
c.durs.With(prometheus.Labels{"method": method}).Observe(time.Since(start).Seconds())
return err
}
}

46
pkger/service_metrics.go Normal file
View File

@ -0,0 +1,46 @@
package pkger
import (
"context"
"github.com/influxdata/influxdb"
"github.com/influxdata/influxdb/kit/metric"
"github.com/influxdata/influxdb/kit/prom"
)
type mwMetrics struct {
// RED metrics
rec *metric.REDClient
next SVC
}
var _ SVC = (*mwMetrics)(nil)
// MWMetrics is a metrics service middleware for the notification endpoint service.
func MWMetrics(reg *prom.Registry) SVCMiddleware {
return func(svc SVC) SVC {
return &mwMetrics{
rec: metric.New(reg, "pkger"),
next: svc,
}
}
}
func (s *mwMetrics) CreatePkg(ctx context.Context, setters ...CreatePkgSetFn) (*Pkg, error) {
rec := s.rec.Record("create_pkg")
pkg, err := s.next.CreatePkg(ctx, setters...)
return pkg, rec(err)
}
func (s *mwMetrics) DryRun(ctx context.Context, orgID, userID influxdb.ID, pkg *Pkg) (Summary, Diff, error) {
rec := s.rec.Record("dry_run")
sum, diff, err := s.next.DryRun(ctx, orgID, userID, pkg)
return sum, diff, rec(err)
}
func (s *mwMetrics) Apply(ctx context.Context, orgID, userID influxdb.ID, pkg *Pkg, opts ...ApplyOptFn) (Summary, error) {
rec := s.rec.Record("apply")
sum, err := s.next.Apply(ctx, orgID, userID, pkg, opts...)
return sum, rec(err)
}