Alerting: Add command line parsing for historian options (#114865)

This commit is contained in:
Steve Simpson
2025-12-04 22:07:22 +01:00
committed by GitHub
parent ff33237052
commit f07cc211bd
3 changed files with 142 additions and 1 deletions
+1 -1
View File
@@ -9,6 +9,7 @@ require (
github.com/grafana/grafana-app-sdk v0.48.4
github.com/grafana/grafana-app-sdk/logging v0.48.3
github.com/prometheus/client_golang v1.23.2
github.com/spf13/pflag v1.0.10
github.com/stretchr/testify v1.11.1
go.opentelemetry.io/otel v1.38.0
go.opentelemetry.io/otel/trace v1.38.0
@@ -113,7 +114,6 @@ require (
github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c // indirect
github.com/shurcooL/vfsgen v0.0.0-20230704071429-0000e147ea92 // indirect
github.com/spf13/cast v1.10.0 // indirect
github.com/spf13/pflag v1.0.10 // indirect
github.com/stretchr/objx v0.5.2 // indirect
github.com/uber/jaeger-client-go v2.30.0+incompatible // indirect
github.com/uber/jaeger-lib v2.4.1+incompatible // indirect
@@ -1,10 +1,20 @@
package config
import (
"net/url"
"time"
"github.com/spf13/pflag"
"github.com/grafana/alerting/notify/historian/lokiclient"
"github.com/grafana/grafana-app-sdk/simple"
)
const (
lokiDefaultMaxQueryLength = 721 * time.Hour // 30d1h, matches the default value in Loki
lokiDefaultMaxQuerySize = 65536 // 64kb
)
type NotificationConfig struct {
Enabled bool
Loki lokiclient.LokiConfig
@@ -14,3 +24,49 @@ type RuntimeConfig struct {
GetAlertStateHistoryHandler simple.AppCustomRouteHandler
Notification NotificationConfig
}
func (n *NotificationConfig) AddFlagsWithPrefix(prefix string, flags *pflag.FlagSet) {
flags.BoolVar(&n.Enabled, prefix+".enabled", false, "Enable notification query endpoints")
addLokiFlags(&n.Loki, prefix+".loki", flags)
}
func (r *RuntimeConfig) AddFlagsWithPrefix(prefix string, flags *pflag.FlagSet) {
r.Notification.AddFlagsWithPrefix(prefix+".notification", flags)
}
func (r *RuntimeConfig) AddFlags(flags *pflag.FlagSet) {
r.AddFlagsWithPrefix("alerting.historian", flags)
}
type urlVar struct {
u **url.URL
}
// String implements flag.Value
func (v urlVar) String() string {
if v.u == nil || *v.u == nil {
return ""
}
return (*v.u).Redacted()
}
// Set implements flag.Value
func (v urlVar) Set(s string) error {
u, err := url.Parse(s)
if err != nil {
return err
}
*v.u = u
return nil
}
// Type implements flag.Value
func (v urlVar) Type() string {
return "url"
}
func addLokiFlags(l *lokiclient.LokiConfig, prefix string, flags *pflag.FlagSet) {
flags.Var(urlVar{&l.ReadPathURL}, prefix+".read-url", "URL to Loki instance for performing queries")
flags.DurationVar(&l.MaxQueryLength, prefix+".max-query-length", lokiDefaultMaxQueryLength, "Maximum allowed time range for queries")
flags.IntVar(&l.MaxQuerySize, prefix+".max-query-size", lokiDefaultMaxQuerySize, "Maximum allowed size of a query string passed to Loki")
}
@@ -0,0 +1,85 @@
package config
import (
"net/url"
"testing"
"time"
"github.com/grafana/alerting/notify/historian/lokiclient"
"github.com/spf13/pflag"
"github.com/stretchr/testify/require"
)
func TestRuntimeConfig(t *testing.T) {
lokiURL := mustParseURL("http://localhost:3100")
tests := []struct {
name string
args []string
expected RuntimeConfig
}{
{
name: "default config",
args: []string{},
expected: RuntimeConfig{
Notification: NotificationConfig{
Enabled: false,
Loki: lokiclient.LokiConfig{
ReadPathURL: nil,
MaxQueryLength: 721 * time.Hour,
MaxQuerySize: 65536,
},
},
},
},
{
name: "with notification enabled",
args: []string{"--alerting.historian.notification.enabled"},
expected: RuntimeConfig{
Notification: NotificationConfig{
Enabled: true,
Loki: lokiclient.LokiConfig{
ReadPathURL: nil,
MaxQueryLength: 721 * time.Hour,
MaxQuerySize: 65536,
},
},
},
},
{
name: "with loki read url",
args: []string{"--alerting.historian.notification.loki.read-url=http://localhost:3100"},
expected: RuntimeConfig{
Notification: NotificationConfig{
Enabled: false,
Loki: lokiclient.LokiConfig{
ReadPathURL: lokiURL,
MaxQueryLength: 721 * time.Hour,
MaxQuerySize: 65536,
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
cfg := &RuntimeConfig{}
flags := pflag.NewFlagSet("test", pflag.ContinueOnError)
cfg.AddFlags(flags)
err := flags.Parse(tt.args)
require.NoError(t, err)
require.Equal(t, tt.expected, *cfg)
})
}
}
func mustParseURL(s string) *url.URL {
u, err := url.Parse(s)
if err != nil {
panic(err)
}
return u
}