Skip to content

Commit

Permalink
lib/periodic: add function to inject metrics in task (#4204)
Browse files Browse the repository at this point in the history
Add StartWithMetrics function to the periodic task library to have full control over the metrics that are exposed by the library.
  • Loading branch information
Hygster authored Jun 14, 2022
1 parent b836870 commit 93f69bd
Show file tree
Hide file tree
Showing 9 changed files with 218 additions and 366 deletions.
2 changes: 1 addition & 1 deletion gateway/gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ func (g *Gateway) Run(ctx context.Context) error {
}
revStore := &pathhealth.MemoryRevocationStore{}

// periodicly clean up the revocation store.
// periodically clean up the revocation store.
revCleaner := periodic.Start(periodic.Func{
Task: func(ctx context.Context) {
revStore.Cleanup(ctx)
Expand Down
4 changes: 3 additions & 1 deletion private/periodic/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ go_library(
visibility = ["//visibility:public"],
deps = [
"//pkg/log:go_default_library",
"//pkg/metrics:go_default_library",
"//private/periodic/internal/metrics:go_default_library",
"@com_github_opentracing_opentracing_go//:go_default_library",
],
Expand All @@ -15,8 +16,9 @@ go_library(
go_test(
name = "go_default_test",
srcs = ["periodic_test.go"],
embed = [":go_default_library"],
deps = [
":go_default_library",
"//pkg/metrics:go_default_library",
"//pkg/private/xtest:go_default_library",
"@com_github_stretchr_testify//assert:go_default_library",
],
Expand Down
16 changes: 2 additions & 14 deletions private/periodic/internal/metrics/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,25 +1,13 @@
load("//tools/lint:go.bzl", "go_library", "go_test")
load("//tools/lint:go.bzl", "go_library")

go_library(
name = "go_default_library",
srcs = ["metrics.go"],
importpath = "github.com/scionproto/scion/private/periodic/internal/metrics",
visibility = ["//visibility:public"],
deps = [
"//pkg/private/prom:go_default_library",
"//pkg/metrics:go_default_library",
"@com_github_iancoleman_strcase//:go_default_library",
"@com_github_prometheus_client_golang//prometheus:go_default_library",
],
)

go_test(
name = "go_default_test",
srcs = ["metrics_test.go"],
embed = [":go_default_library"],
deps = [
"//pkg/private/prom/promtest:go_default_library",
"@com_github_prometheus_client_golang//prometheus/testutil:go_default_library",
"@com_github_stretchr_testify//assert:go_default_library",
"@com_github_stretchr_testify//require:go_default_library",
],
)
149 changes: 53 additions & 96 deletions private/periodic/internal/metrics/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,113 +16,70 @@ package metrics

import (
"strings"
"time"

"github.com/iancoleman/strcase"
"github.com/prometheus/client_golang/prometheus"

"github.com/scionproto/scion/pkg/private/prom"
"github.com/scionproto/scion/pkg/metrics"
)

const (
// EventStop indicates a stop event took place.
EventStop = "stop"
// EventKill indicates a kill event took place.
EventKill = "kill"
// EventTrigger indicates a trigger event took place.
EventTrigger = "triggered"
)

// ExportMetric is the interface to export periodic metrics.
type ExportMetric interface {
Runtime(time.Duration)
StartTimestamp(time.Time)
Period(time.Duration)
Event(string)
}
// Metrics is the standard metrics used in periodic.Runner

// NewMetric returns the ExportMetric to be used for the exporting metrics.
func NewMetric(prefix string) ExportMetric {
return newExporter(prefix)
// Deprecated: Metrics is used only in the deprecated function periodic.Start
// which exists only for compatibility reasons. Use periodic.StartWithMetrics
// along with periodic.Metrics instead.
type Metrics struct {
Events func(string) metrics.Counter
Runtime metrics.Gauge
Timestamp metrics.Gauge
Period metrics.Gauge
}

type exporter struct {
events *prometheus.CounterVec
runtime prometheus.Counter
timestamp, period prometheus.Gauge
}

func newExporter(prefix string) exporter {
func NewMetric(prefix string) Metrics {
namespace := strcase.ToSnake(strings.Replace(prefix, ".", "_", -1))
subsystem := "periodic"

events := prom.NewCounterVecWithLabels(namespace, subsystem, "event_total",
"Total number of events.", EventLabels{EventTrigger})

runtime := prom.SafeRegister(
prometheus.NewCounter(prometheus.CounterOpts{
Namespace: namespace,
Subsystem: subsystem,
Name: "runtime_duration_seconds_total",
Help: "Total time spend on every periodic run.",
}),
).(prometheus.Counter)

timestamp := prom.SafeRegister(
prometheus.NewGauge(prometheus.GaugeOpts{
Namespace: namespace,
Subsystem: subsystem,
Name: "runtime_timestamp_seconds",
Help: "The unix timestamp when the periodic run started.",
}),
).(prometheus.Gauge)

period := prom.SafeRegister(
prometheus.NewGauge(prometheus.GaugeOpts{
Namespace: namespace,
Subsystem: subsystem,
Name: "period_duration_seconds",
Help: "The period of this job.",
}),
).(prometheus.Gauge)

return exporter{
events: events,
runtime: runtime,
timestamp: timestamp,
period: period,
events := prometheus.NewCounterVec(prometheus.CounterOpts{
Namespace: namespace,
Subsystem: subsystem,
Name: "event_total",
Help: "Total number of events.",
},
[]string{"event_type"},
)

runtime := prometheus.NewGaugeVec(prometheus.GaugeOpts{
Namespace: namespace,
Subsystem: subsystem,
Name: "runtime_duration_seconds_total",
Help: "Total time spend on every periodic run.",
},
[]string{},
)

timestamp := prometheus.NewGaugeVec(prometheus.GaugeOpts{
Namespace: namespace,
Subsystem: subsystem,
Name: "runtime_timestamp_seconds",
Help: "The unix timestamp when the periodic run started.",
},
[]string{},
)
period := prometheus.NewGaugeVec(prometheus.GaugeOpts{
Namespace: namespace,
Subsystem: subsystem,
Name: "period_duration_seconds",
Help: "The period of this job.",
},
[]string{},
)

return Metrics{
Events: func(s string) metrics.Counter {
return metrics.NewPromCounter(events).With("event_type", s)
},
Runtime: metrics.NewPromGauge(runtime),
Timestamp: metrics.NewPromGauge(timestamp),
Period: metrics.NewPromGauge(period),
}
}

func (e exporter) StartTimestamp(t time.Time) {
e.timestamp.Set(float64(t.UnixNano() / 1e9))
}

func (e exporter) Period(d time.Duration) {
e.period.Set(d.Seconds())
}

func (e exporter) Runtime(d time.Duration) {
e.runtime.Add(float64(d) / 1e9)
}

func (e exporter) Event(s string) {
l := EventLabels{s}
e.events.WithLabelValues(l.Values()...).Inc()
}

// EventLabels is used by clients to pass in a safe way labels
// values to prometheus metric types (e.g. counter).
type EventLabels struct {
eventType string
}

// Labels returns the name of the labels in correct order.
func (l EventLabels) Labels() []string {
return []string{"event_type"}
}

// Values returns the values of the label in correct order.
func (l EventLabels) Values() []string {
return []string{l.eventType}
}
133 changes: 0 additions & 133 deletions private/periodic/internal/metrics/metrics_test.go

This file was deleted.

18 changes: 0 additions & 18 deletions private/periodic/internal/metrics/mock_metrics/BUILD.bazel

This file was deleted.

Loading

0 comments on commit 93f69bd

Please sign in to comment.