Add config options for metrics

This commit is contained in:
Daniel 2021-03-10 14:00:51 +01:00
parent 4a05c26339
commit aef3f26ad3
4 changed files with 89 additions and 16 deletions

View file

@ -90,7 +90,7 @@ func writeMetricsTo(ctx context.Context, url string) error {
}
// Create request
req, err := http.NewRequestWithContext(ctx, http.MethodPut, url, buf)
req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, buf)
if err != nil {
return fmt.Errorf("failed to create request: %w", err)
}
@ -118,6 +118,7 @@ func writeMetricsTo(ctx context.Context, url string) error {
}
func metricsWriter(ctx context.Context) error {
pushURL := pushOption()
ticker := time.NewTicker(10 * time.Second)
defer ticker.Stop()

69
metrics/config.go Normal file
View file

@ -0,0 +1,69 @@
package metrics
import (
"flag"
"github.com/safing/portbase/config"
)
// Configuration Keys
var (
CfgOptionInstanceKey = "core/metrics/instance"
instanceOption config.StringOption
cfgOptionInstanceOrder = 0
CfgOptionPushKey = "core/metrics/push"
pushOption config.StringOption
cfgOptionPushOrder = 0
pushFlag string
instanceFlag string
)
func init() {
flag.StringVar(&pushFlag, "push-metrics", "", "Set default URL to push prometheus metrics to.")
flag.StringVar(&instanceFlag, "metrics-instance", "", "Set the default global instance label.")
}
func prepConfig() error {
err := config.Register(&config.Option{
Name: "Metrics Instance Name",
Key: CfgOptionInstanceKey,
Description: "Define the prometheus instance label for exported metrics. Please note that changing the instance name will reset persisted metrics.",
OptType: config.OptTypeString,
ExpertiseLevel: config.ExpertiseLevelExpert,
ReleaseLevel: config.ReleaseLevelStable,
DefaultValue: instanceFlag,
RequiresRestart: true,
Annotations: config.Annotations{
config.DisplayOrderAnnotation: cfgOptionInstanceOrder,
config.CategoryAnnotation: "Metrics",
},
ValidationRegex: "^(" + prometheusBaseFormt + ")?$",
})
if err != nil {
return err
}
instanceOption = config.Concurrent.GetAsString(CfgOptionInstanceKey, instanceFlag)
err = config.Register(&config.Option{
Name: "Push Metrics",
Key: CfgOptionPushKey,
Description: "Push metrics to this URL in the prometheus format.",
OptType: config.OptTypeString,
ExpertiseLevel: config.ExpertiseLevelExpert,
ReleaseLevel: config.ReleaseLevelStable,
DefaultValue: pushFlag,
RequiresRestart: true,
Annotations: config.Annotations{
config.DisplayOrderAnnotation: cfgOptionPushOrder,
config.CategoryAnnotation: "Metrics",
},
})
if err != nil {
return err
}
pushOption = config.Concurrent.GetAsString(CfgOptionPushKey, pushFlag)
return nil
}

View file

@ -15,7 +15,8 @@ import (
// PrometheusFormatRequirement is required format defined by prometheus for
// metric and label names.
const PrometheusFormatRequirement = "[a-zA-Z_][a-zA-Z0-9_]*"
const prometheusBaseFormt = "[a-zA-Z_][a-zA-Z0-9_]*"
const PrometheusFormatRequirement = "^" + prometheusBaseFormt + "$"
var prometheusFormat = regexp.MustCompile(PrometheusFormatRequirement)
@ -60,7 +61,7 @@ type Options struct {
func newMetricBase(id string, labels map[string]string, opts Options) (*metricBase, error) {
// Check formats.
if !prometheusFormat.MatchString(id) {
if !prometheusFormat.MatchString(strings.ReplaceAll(id, "/", "_")) {
return nil, fmt.Errorf("metric name %q must match %s", id, PrometheusFormatRequirement)
}
for labelName := range labels {
@ -75,6 +76,11 @@ func newMetricBase(id string, labels map[string]string, opts Options) (*metricBa
opts.Permission = api.PermitUser
}
// Ensure that labels is a map.
if labels == nil {
labels = make(map[string]string)
}
// Create metric base.
base := &metricBase{
Identifier: id,

View file

@ -2,7 +2,6 @@ package metrics
import (
"errors"
"flag"
"fmt"
"sort"
"sync"
@ -20,9 +19,6 @@ var (
metricNamespace string
globalLabels = make(map[string]string)
pushURL string
metricInstance string
// ErrAlreadyStarted is returned when an operation is only valid before the
// first metric is registered, and is called after.
ErrAlreadyStarted = errors.New("can only be changed before first metric is registered")
@ -36,29 +32,30 @@ var (
)
func init() {
flag.StringVar(&pushURL, "push-metrics", "", "URL to push prometheus metrics to")
flag.StringVar(&metricInstance, "metrics-instance", "", "Set the global instance label")
module = modules.Register("metrics", prep, start, stop, "database", "api")
}
func prep() error {
return prepConfig()
}
func start() error {
// Add metric instance name as global variable if set.
if metricInstance != "" {
if err := AddGlobalLabel("instance", metricInstance); err != nil {
if instanceOption() != "" {
if err := AddGlobalLabel("instance", instanceOption()); err != nil {
return err
}
}
return registerInfoMetric()
}
if err := registerInfoMetric(); err != nil {
return err
}
func start() error {
if err := registerAPI(); err != nil {
return err
}
if pushURL != "" {
if pushOption() != "" {
module.StartServiceWorker("metric pusher", 0, metricsWriter)
}