From 81f34b4cc59d140142867d3f2caa0eaacbbb7cc2 Mon Sep 17 00:00:00 2001 From: Vadim Stepanov Date: Tue, 15 Jul 2025 14:04:16 +0100 Subject: [PATCH] unify loki settings --- .../annotationsimpl/loki/historian_store.go | 2 +- pkg/services/ngalert/lokiclient/client.go | 40 +++++++++ pkg/services/ngalert/ngalert.go | 4 +- pkg/services/ngalert/ngalert_test.go | 59 ++++++++++++- pkg/services/ngalert/notifier/historian.go | 42 --------- pkg/services/ngalert/state/historian/loki.go | 41 --------- .../ngalert/state/historian/loki_test.go | 42 ++++----- pkg/setting/setting_unified_alerting.go | 85 +++++++++---------- 8 files changed, 162 insertions(+), 153 deletions(-) diff --git a/pkg/services/annotations/annotationsimpl/loki/historian_store.go b/pkg/services/annotations/annotationsimpl/loki/historian_store.go index b77e96f8320..59ed1494c41 100644 --- a/pkg/services/annotations/annotationsimpl/loki/historian_store.go +++ b/pkg/services/annotations/annotationsimpl/loki/historian_store.go @@ -61,7 +61,7 @@ func NewLokiHistorianStore(cfg setting.UnifiedAlertingStateHistorySettings, db d if !useStore(cfg) { return nil } - lokiCfg, err := historian.NewLokiConfig(cfg) + lokiCfg, err := lokiclient.NewLokiConfig(cfg.LokiSettings) if err != nil { // this config error is already handled elsewhere return nil diff --git a/pkg/services/ngalert/lokiclient/client.go b/pkg/services/ngalert/lokiclient/client.go index e9a0c8b8baa..0b1fca30daf 100644 --- a/pkg/services/ngalert/lokiclient/client.go +++ b/pkg/services/ngalert/lokiclient/client.go @@ -15,6 +15,7 @@ import ( "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/infra/tracing" "github.com/grafana/grafana/pkg/services/ngalert/client" + "github.com/grafana/grafana/pkg/setting" "github.com/prometheus/client_golang/prometheus" ) @@ -45,6 +46,45 @@ type LokiConfig struct { MaxQuerySize int } +func NewLokiConfig(cfg setting.UnifiedAlertingLokiSettings) (LokiConfig, error) { + read, write := cfg.LokiReadURL, cfg.LokiWriteURL + if read == "" { + read = cfg.LokiRemoteURL + } + if write == "" { + write = cfg.LokiRemoteURL + } + + if read == "" { + return LokiConfig{}, fmt.Errorf("either read path URL or remote Loki URL must be provided") + } + if write == "" { + return LokiConfig{}, fmt.Errorf("either write path URL or remote Loki URL must be provided") + } + + readURL, err := url.Parse(read) + if err != nil { + return LokiConfig{}, fmt.Errorf("failed to parse loki remote read URL: %w", err) + } + writeURL, err := url.Parse(write) + if err != nil { + return LokiConfig{}, fmt.Errorf("failed to parse loki remote write URL: %w", err) + } + + return LokiConfig{ + ReadPathURL: readURL, + WritePathURL: writeURL, + BasicAuthUser: cfg.LokiBasicAuthUsername, + BasicAuthPassword: cfg.LokiBasicAuthPassword, + TenantID: cfg.LokiTenantID, + ExternalLabels: cfg.ExternalLabels, + MaxQueryLength: cfg.LokiMaxQueryLength, + MaxQuerySize: cfg.LokiMaxQuerySize, + // Snappy-compressed protobuf is the default, same goes for Promtail. + Encoder: SnappyProtoEncoder{}, + }, nil +} + type HttpLokiClient struct { client client.Requester encoder encoder diff --git a/pkg/services/ngalert/ngalert.go b/pkg/services/ngalert/ngalert.go index 352e1e020d1..dcb3b571bee 100644 --- a/pkg/services/ngalert/ngalert.go +++ b/pkg/services/ngalert/ngalert.go @@ -691,7 +691,7 @@ func configureHistorianBackend( return historian.NewAnnotationBackend(annotationBackendLogger, store, rs, met, ac), nil } if backend == historian.BackendTypeLoki { - lcfg, err := historian.NewLokiConfig(cfg) + lcfg, err := lokiclient.NewLokiConfig(cfg.LokiSettings) if err != nil { return nil, fmt.Errorf("invalid remote loki configuration: %w", err) } @@ -743,7 +743,7 @@ func configureNotificationHistorian( } met.Info.Set(1) - lcfg, err := notifier.NewLokiConfig(cfg) + lcfg, err := lokiclient.NewLokiConfig(cfg.LokiSettings) if err != nil { return nil, fmt.Errorf("invalid remote loki configuration: %w", err) } diff --git a/pkg/services/ngalert/ngalert_test.go b/pkg/services/ngalert/ngalert_test.go index a0b42309f47..64d11d9204f 100644 --- a/pkg/services/ngalert/ngalert_test.go +++ b/pkg/services/ngalert/ngalert_test.go @@ -137,9 +137,11 @@ func TestConfigureHistorianBackend(t *testing.T) { cfg := setting.UnifiedAlertingStateHistorySettings{ Enabled: true, Backend: "loki", - // Should never resolve at the DNS level: https://www.rfc-editor.org/rfc/rfc6761#section-6.4 - LokiReadURL: "http://gone.invalid", - LokiWriteURL: "http://gone.invalid", + LokiSettings: setting.UnifiedAlertingLokiSettings{ + // Should never resolve at the DNS level: https://www.rfc-editor.org/rfc/rfc6761#section-6.4 + LokiReadURL: "http://gone.invalid", + LokiWriteURL: "http://gone.invalid", + }, } ac := &acfakes.FakeRuleService{} @@ -232,6 +234,57 @@ grafana_alerting_state_history_info{backend="noop"} 0 }) } +func TestConfigureNotificationHistorian(t *testing.T) { + t.Run("do not fail initialization if pinging Loki fails", func(t *testing.T) { + reg := prometheus.NewRegistry() + met := metrics.NewNotificationHistorianMetrics(reg) + logger := log.NewNopLogger() + tracer := tracing.InitializeTracerForTest() + cfg := setting.UnifiedAlertingNotificationHistorySettings{ + Enabled: true, + LokiSettings: setting.UnifiedAlertingLokiSettings{ + // Should never resolve at the DNS level: https://www.rfc-editor.org/rfc/rfc6761#section-6.4 + LokiRemoteURL: "http://gone.invalid", + }, + } + + h, err := configureNotificationHistorian(context.Background(), cfg, met, logger, tracer) + require.NotNil(t, h) + require.NoError(t, err) + + // Verify that the metric value is set to 1, indicating that notification history is enabled. + exp := bytes.NewBufferString(` +# HELP grafana_alerting_notification_history_info Information about the notification history store. +# TYPE grafana_alerting_notification_history_info gauge +grafana_alerting_notification_history_info 1 +`) + err = testutil.GatherAndCompare(reg, exp, "grafana_alerting_notification_history_info") + require.NoError(t, err) + }) + + t.Run("emit special zero metric if notification history disabled", func(t *testing.T) { + reg := prometheus.NewRegistry() + met := metrics.NewNotificationHistorianMetrics(reg) + logger := log.NewNopLogger() + tracer := tracing.InitializeTracerForTest() + cfg := setting.UnifiedAlertingNotificationHistorySettings{ + Enabled: false, + } + + h, err := configureNotificationHistorian(context.Background(), cfg, met, logger, tracer) + require.Nil(t, h) + require.NoError(t, err) + + exp := bytes.NewBufferString(` +# HELP grafana_alerting_notification_history_info Information about the notification history store. +# TYPE grafana_alerting_notification_history_info gauge +grafana_alerting_notification_history_info 0 +`) + err = testutil.GatherAndCompare(reg, exp, "grafana_alerting_notification_history_info") + require.NoError(t, err) + }) +} + type mockDB struct { db.DB } diff --git a/pkg/services/ngalert/notifier/historian.go b/pkg/services/ngalert/notifier/historian.go index 4799606dea2..f635b97b2c6 100644 --- a/pkg/services/ngalert/notifier/historian.go +++ b/pkg/services/ngalert/notifier/historian.go @@ -4,7 +4,6 @@ import ( "context" "encoding/json" "fmt" - "net/url" "strings" "time" @@ -14,7 +13,6 @@ import ( "github.com/grafana/grafana/pkg/services/ngalert/client" "github.com/grafana/grafana/pkg/services/ngalert/lokiclient" "github.com/grafana/grafana/pkg/services/ngalert/metrics" - "github.com/grafana/grafana/pkg/setting" "github.com/prometheus/alertmanager/notify" "github.com/prometheus/alertmanager/types" prometheusModel "github.com/prometheus/common/model" @@ -105,46 +103,6 @@ func (h *NotificationHistorian) Record(ctx context.Context, alerts []*types.Aler return errCh } -// NewLokiConfig is a copy of historian.NewLokiConfig -func NewLokiConfig(cfg setting.UnifiedAlertingNotificationHistorySettings) (lokiclient.LokiConfig, error) { - read, write := cfg.LokiReadURL, cfg.LokiWriteURL - if read == "" { - read = cfg.LokiRemoteURL - } - if write == "" { - write = cfg.LokiRemoteURL - } - - if read == "" { - return lokiclient.LokiConfig{}, fmt.Errorf("either read path URL or remote Loki URL must be provided") - } - if write == "" { - return lokiclient.LokiConfig{}, fmt.Errorf("either write path URL or remote Loki URL must be provided") - } - - readURL, err := url.Parse(read) - if err != nil { - return lokiclient.LokiConfig{}, fmt.Errorf("failed to parse loki remote read URL: %w", err) - } - writeURL, err := url.Parse(write) - if err != nil { - return lokiclient.LokiConfig{}, fmt.Errorf("failed to parse loki remote write URL: %w", err) - } - - return lokiclient.LokiConfig{ - ReadPathURL: readURL, - WritePathURL: writeURL, - BasicAuthUser: cfg.LokiBasicAuthUsername, - BasicAuthPassword: cfg.LokiBasicAuthPassword, - TenantID: cfg.LokiTenantID, - ExternalLabels: cfg.ExternalLabels, - MaxQueryLength: cfg.LokiMaxQueryLength, - MaxQuerySize: cfg.LokiMaxQuerySize, - // Snappy-compressed protobuf is the default, same goes for Promtail. - Encoder: lokiclient.SnappyProtoEncoder{}, - }, nil -} - func (h *NotificationHistorian) prepareStream(ctx context.Context, alerts []*types.Alert, notificationError error) (lokiclient.Stream, error) { receiverName, ok := notify.ReceiverName(ctx) if !ok { diff --git a/pkg/services/ngalert/state/historian/loki.go b/pkg/services/ngalert/state/historian/loki.go index 22f220ec285..c8e9b356552 100644 --- a/pkg/services/ngalert/state/historian/loki.go +++ b/pkg/services/ngalert/state/historian/loki.go @@ -5,7 +5,6 @@ import ( "encoding/json" "fmt" "math" - "net/url" "regexp" "sort" "strconv" @@ -15,7 +14,6 @@ import ( "github.com/benbjohnson/clock" "github.com/grafana/grafana-plugin-sdk-go/data" "github.com/grafana/grafana/pkg/services/ngalert/lokiclient" - "github.com/grafana/grafana/pkg/setting" "go.opentelemetry.io/otel/trace" "github.com/grafana/grafana/pkg/apimachinery/errutil" @@ -541,42 +539,3 @@ func (h *RemoteLokiBackend) getFolderUIDsForFilter(ctx context.Context, query mo sort.Strings(uids) return uids, nil } - -func NewLokiConfig(cfg setting.UnifiedAlertingStateHistorySettings) (lokiclient.LokiConfig, error) { - read, write := cfg.LokiReadURL, cfg.LokiWriteURL - if read == "" { - read = cfg.LokiRemoteURL - } - if write == "" { - write = cfg.LokiRemoteURL - } - - if read == "" { - return lokiclient.LokiConfig{}, fmt.Errorf("either read path URL or remote Loki URL must be provided") - } - if write == "" { - return lokiclient.LokiConfig{}, fmt.Errorf("either write path URL or remote Loki URL must be provided") - } - - readURL, err := url.Parse(read) - if err != nil { - return lokiclient.LokiConfig{}, fmt.Errorf("failed to parse loki remote read URL: %w", err) - } - writeURL, err := url.Parse(write) - if err != nil { - return lokiclient.LokiConfig{}, fmt.Errorf("failed to parse loki remote write URL: %w", err) - } - - return lokiclient.LokiConfig{ - ReadPathURL: readURL, - WritePathURL: writeURL, - BasicAuthUser: cfg.LokiBasicAuthUsername, - BasicAuthPassword: cfg.LokiBasicAuthPassword, - TenantID: cfg.LokiTenantID, - ExternalLabels: cfg.ExternalLabels, - MaxQueryLength: cfg.LokiMaxQueryLength, - MaxQuerySize: cfg.LokiMaxQuerySize, - // Snappy-compressed protobuf is the default, same goes for Promtail. - Encoder: lokiclient.SnappyProtoEncoder{}, - }, nil -} diff --git a/pkg/services/ngalert/state/historian/loki_test.go b/pkg/services/ngalert/state/historian/loki_test.go index 7bdf80a81a6..8fcf2ad16db 100644 --- a/pkg/services/ngalert/state/historian/loki_test.go +++ b/pkg/services/ngalert/state/historian/loki_test.go @@ -42,7 +42,7 @@ func TestLokiConfig(t *testing.T) { t.Run("test URL options", func(t *testing.T) { type testCase struct { name string - in setting.UnifiedAlertingStateHistorySettings + in setting.UnifiedAlertingLokiSettings expRead string expWrite string expErr string @@ -51,7 +51,7 @@ func TestLokiConfig(t *testing.T) { cases := []testCase{ { name: "remote url only", - in: setting.UnifiedAlertingStateHistorySettings{ + in: setting.UnifiedAlertingLokiSettings{ LokiRemoteURL: "http://url.com", }, expRead: "http://url.com", @@ -59,7 +59,7 @@ func TestLokiConfig(t *testing.T) { }, { name: "separate urls", - in: setting.UnifiedAlertingStateHistorySettings{ + in: setting.UnifiedAlertingLokiSettings{ LokiReadURL: "http://read.url.com", LokiWriteURL: "http://write.url.com", }, @@ -68,7 +68,7 @@ func TestLokiConfig(t *testing.T) { }, { name: "single fallback", - in: setting.UnifiedAlertingStateHistorySettings{ + in: setting.UnifiedAlertingLokiSettings{ LokiRemoteURL: "http://url.com", LokiReadURL: "http://read.url.com", }, @@ -77,21 +77,21 @@ func TestLokiConfig(t *testing.T) { }, { name: "missing read", - in: setting.UnifiedAlertingStateHistorySettings{ + in: setting.UnifiedAlertingLokiSettings{ LokiWriteURL: "http://url.com", }, expErr: "either read path URL or remote", }, { name: "missing write", - in: setting.UnifiedAlertingStateHistorySettings{ + in: setting.UnifiedAlertingLokiSettings{ LokiReadURL: "http://url.com", }, expErr: "either write path URL or remote", }, { name: "invalid", - in: setting.UnifiedAlertingStateHistorySettings{ + in: setting.UnifiedAlertingLokiSettings{ LokiRemoteURL: "://://", }, expErr: "failed to parse", @@ -100,7 +100,7 @@ func TestLokiConfig(t *testing.T) { for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { - res, err := NewLokiConfig(tc.in) + res, err := lokiclient.NewLokiConfig(tc.in) if tc.expErr != "" { require.ErrorContains(t, err, tc.expErr) } else { @@ -112,12 +112,12 @@ func TestLokiConfig(t *testing.T) { }) t.Run("captures external labels", func(t *testing.T) { - set := setting.UnifiedAlertingStateHistorySettings{ + set := setting.UnifiedAlertingLokiSettings{ LokiRemoteURL: "http://url.com", ExternalLabels: map[string]string{"a": "b"}, } - res, err := NewLokiConfig(set) + res, err := lokiclient.NewLokiConfig(set) require.NoError(t, err) require.Contains(t, res.ExternalLabels, "a") @@ -454,7 +454,7 @@ func TestMerge(t *testing.T) { "extra": "label", }, Values: []lokiclient.Sample{ - {time.Unix(1, 0), `{"schemaVersion": 1, "previous": "normal", "current": "pending", "values":{"a": 1.5}, "ruleUID": "test-rule-1"}`}, + {T: time.Unix(1, 0), V: `{"schemaVersion": 1, "previous": "normal", "current": "pending", "values":{"a": 1.5}, "ruleUID": "test-rule-1"}`}, }, }, { @@ -465,7 +465,7 @@ func TestMerge(t *testing.T) { "folderUID": "test-folder-1", }, Values: []lokiclient.Sample{ - {time.Unix(2, 0), `{"schemaVersion": 1, "previous": "pending", "current": "firing", "values":{"a": 2.5}, "ruleUID": "test-rule-2"}`}, + {T: time.Unix(2, 0), V: `{"schemaVersion": 1, "previous": "pending", "current": "firing", "values":{"a": 2.5}, "ruleUID": "test-rule-2"}`}, }, }, }, @@ -530,8 +530,8 @@ func TestMerge(t *testing.T) { "folderUID": "test-folder-1", }, Values: []lokiclient.Sample{ - {time.Unix(1, 0), `{"schemaVersion": 1, "previous": "normal", "current": "pending", "values":{"a": 1.5}, "ruleUID": "test-rule-1"}`}, - {time.Unix(5, 0), `{"schemaVersion": 1, "previous": "pending", "current": "normal", "values":{"a": 0.5}, "ruleUID": "test-rule-2"}`}, + {T: time.Unix(1, 0), V: `{"schemaVersion": 1, "previous": "normal", "current": "pending", "values":{"a": 1.5}, "ruleUID": "test-rule-1"}`}, + {T: time.Unix(5, 0), V: `{"schemaVersion": 1, "previous": "pending", "current": "normal", "values":{"a": 0.5}, "ruleUID": "test-rule-2"}`}, }, }, { @@ -542,7 +542,7 @@ func TestMerge(t *testing.T) { "folderUID": "test-folder-1", }, Values: []lokiclient.Sample{ - {time.Unix(2, 0), `{"schemaVersion": 1, "previous": "pending", "current": "firing", "values":{"a": 2.5}, "ruleUID": "test-rule-3"}`}, + {T: time.Unix(2, 0), V: `{"schemaVersion": 1, "previous": "pending", "current": "firing", "values":{"a": 2.5}, "ruleUID": "test-rule-3"}`}, }, }, }, @@ -595,8 +595,8 @@ func TestMerge(t *testing.T) { "folderUID": "test-folder-1", }, Values: []lokiclient.Sample{ - {time.Unix(1, 0), `{"schemaVersion": 1, "previous": "normal", "current": "pending", "values":{"a": 1.5}, "ruleUID": "test-rule-1"}`}, - {time.Unix(5, 0), `{"schemaVersion": 1, "previous": "pending", "current": "normal", "values":{"a": 0.5}, "ruleUID": "test-rule-2"}`}, + {T: time.Unix(1, 0), V: `{"schemaVersion": 1, "previous": "normal", "current": "pending", "values":{"a": 1.5}, "ruleUID": "test-rule-1"}`}, + {T: time.Unix(5, 0), V: `{"schemaVersion": 1, "previous": "pending", "current": "normal", "values":{"a": 0.5}, "ruleUID": "test-rule-2"}`}, }, }, { @@ -607,7 +607,7 @@ func TestMerge(t *testing.T) { "folderUID": "test-folder-2", }, Values: []lokiclient.Sample{ - {time.Unix(2, 0), `{"schemaVersion": 1, "previous": "pending", "current": "firing", "values":{"a": 2.5}, "ruleUID": "test-rule-3"}`}, + {T: time.Unix(2, 0), V: `{"schemaVersion": 1, "previous": "pending", "current": "firing", "values":{"a": 2.5}, "ruleUID": "test-rule-3"}`}, }, }, }, @@ -649,8 +649,8 @@ func TestMerge(t *testing.T) { "group": "test-group-1", }, Values: []lokiclient.Sample{ - {time.Unix(1, 0), `{"schemaVersion": 1, "previous": "normal", "current": "pending", "values":{"a": 1.5}, "ruleUID": "test-rule-1"}`}, - {time.Unix(5, 0), `{"schemaVersion": 1, "previous": "pending", "current": "normal", "values":{"a": 0.5}, "ruleUID": "test-rule-2"}`}, + {T: time.Unix(1, 0), V: `{"schemaVersion": 1, "previous": "normal", "current": "pending", "values":{"a": 1.5}, "ruleUID": "test-rule-1"}`}, + {T: time.Unix(5, 0), V: `{"schemaVersion": 1, "previous": "pending", "current": "normal", "values":{"a": 0.5}, "ruleUID": "test-rule-2"}`}, }, }, }, @@ -673,7 +673,7 @@ func TestMerge(t *testing.T) { "group": "test-group-1", }, Values: []lokiclient.Sample{ - {time.Unix(1, 0), `{"schemaVersion": 1, "previous": "normal", "current": "pending", "values":{"a": 1.5}, "ruleUID": "test-rule-1"}`}, + {T: time.Unix(1, 0), V: `{"schemaVersion": 1, "previous": "normal", "current": "pending", "values":{"a": 1.5}, "ruleUID": "test-rule-1"}`}, }, }, }, diff --git a/pkg/setting/setting_unified_alerting.go b/pkg/setting/setting_unified_alerting.go index c8d71f0e5d9..665c751532f 100644 --- a/pkg/setting/setting_unified_alerting.go +++ b/pkg/setting/setting_unified_alerting.go @@ -183,29 +183,7 @@ type UnifiedAlertingPrometheusConversionSettings struct { RuleQueryOffset time.Duration } -type UnifiedAlertingStateHistorySettings struct { - Enabled bool - Backend string - LokiRemoteURL string - LokiReadURL string - LokiWriteURL string - LokiTenantID string - // LokiBasicAuthUsername and LokiBasicAuthPassword are used for basic auth - // if one of them is set. - LokiBasicAuthPassword string - LokiBasicAuthUsername string - LokiMaxQueryLength time.Duration - LokiMaxQuerySize int - PrometheusMetricName string - PrometheusTargetDatasourceUID string - PrometheusWriteTimeout time.Duration - MultiPrimary string - MultiSecondaries []string - ExternalLabels map[string]string -} - -type UnifiedAlertingNotificationHistorySettings struct { - Enabled bool +type UnifiedAlertingLokiSettings struct { LokiRemoteURL string LokiReadURL string LokiWriteURL string @@ -219,6 +197,23 @@ type UnifiedAlertingNotificationHistorySettings struct { ExternalLabels map[string]string } +type UnifiedAlertingStateHistorySettings struct { + Enabled bool + Backend string + LokiSettings UnifiedAlertingLokiSettings + PrometheusMetricName string + PrometheusTargetDatasourceUID string + PrometheusWriteTimeout time.Duration + MultiPrimary string + MultiSecondaries []string + ExternalLabels map[string]string +} + +type UnifiedAlertingNotificationHistorySettings struct { + Enabled bool + LokiSettings UnifiedAlertingLokiSettings +} + // IsEnabled returns true if UnifiedAlertingSettings.Enabled is either nil or true. // It hides the implementation details of the Enabled and simplifies its usage. func (u *UnifiedAlertingSettings) IsEnabled() bool { @@ -470,16 +465,18 @@ func (cfg *Cfg) ReadUnifiedAlertingSettings(iniFile *ini.File) error { stateHistory := iniFile.Section("unified_alerting.state_history") stateHistoryLabels := iniFile.Section("unified_alerting.state_history.external_labels") uaCfgStateHistory := UnifiedAlertingStateHistorySettings{ - Enabled: stateHistory.Key("enabled").MustBool(stateHistoryDefaultEnabled), - Backend: stateHistory.Key("backend").MustString("annotations"), - LokiRemoteURL: stateHistory.Key("loki_remote_url").MustString(""), - LokiReadURL: stateHistory.Key("loki_remote_read_url").MustString(""), - LokiWriteURL: stateHistory.Key("loki_remote_write_url").MustString(""), - LokiTenantID: stateHistory.Key("loki_tenant_id").MustString(""), - LokiBasicAuthUsername: stateHistory.Key("loki_basic_auth_username").MustString(""), - LokiBasicAuthPassword: stateHistory.Key("loki_basic_auth_password").MustString(""), - LokiMaxQueryLength: stateHistory.Key("loki_max_query_length").MustDuration(lokiDefaultMaxQueryLength), - LokiMaxQuerySize: stateHistory.Key("loki_max_query_size").MustInt(lokiDefaultMaxQuerySize), + Enabled: stateHistory.Key("enabled").MustBool(stateHistoryDefaultEnabled), + Backend: stateHistory.Key("backend").MustString("annotations"), + LokiSettings: UnifiedAlertingLokiSettings{ + LokiRemoteURL: stateHistory.Key("loki_remote_url").MustString(""), + LokiReadURL: stateHistory.Key("loki_remote_read_url").MustString(""), + LokiWriteURL: stateHistory.Key("loki_remote_write_url").MustString(""), + LokiTenantID: stateHistory.Key("loki_tenant_id").MustString(""), + LokiBasicAuthUsername: stateHistory.Key("loki_basic_auth_username").MustString(""), + LokiBasicAuthPassword: stateHistory.Key("loki_basic_auth_password").MustString(""), + LokiMaxQueryLength: stateHistory.Key("loki_max_query_length").MustDuration(lokiDefaultMaxQueryLength), + LokiMaxQuerySize: stateHistory.Key("loki_max_query_size").MustInt(lokiDefaultMaxQuerySize), + }, MultiPrimary: stateHistory.Key("primary").MustString(""), MultiSecondaries: splitTrim(stateHistory.Key("secondaries").MustString(""), ","), PrometheusMetricName: stateHistory.Key("prometheus_metric_name").MustString(defaultHistorianPrometheusMetricName), @@ -492,16 +489,18 @@ func (cfg *Cfg) ReadUnifiedAlertingSettings(iniFile *ini.File) error { notificationHistory := iniFile.Section("unified_alerting.notification_history") notificationHistoryLabels := iniFile.Section("unified_alerting.notification_history.external_labels") uaCfgNotificationHistory := UnifiedAlertingNotificationHistorySettings{ - Enabled: notificationHistory.Key("enabled").MustBool(notificationHistoryDefaultEnabled), - LokiRemoteURL: notificationHistory.Key("loki_remote_url").MustString(""), - LokiReadURL: notificationHistory.Key("loki_remote_read_url").MustString(""), - LokiWriteURL: notificationHistory.Key("loki_remote_write_url").MustString(""), - LokiTenantID: notificationHistory.Key("loki_tenant_id").MustString(""), - LokiBasicAuthUsername: notificationHistory.Key("loki_basic_auth_username").MustString(""), - LokiBasicAuthPassword: notificationHistory.Key("loki_basic_auth_password").MustString(""), - LokiMaxQueryLength: notificationHistory.Key("loki_max_query_length").MustDuration(lokiDefaultMaxQueryLength), - LokiMaxQuerySize: notificationHistory.Key("loki_max_query_size").MustInt(lokiDefaultMaxQuerySize), - ExternalLabels: notificationHistoryLabels.KeysHash(), + Enabled: notificationHistory.Key("enabled").MustBool(notificationHistoryDefaultEnabled), + LokiSettings: UnifiedAlertingLokiSettings{ + LokiRemoteURL: notificationHistory.Key("loki_remote_url").MustString(""), + LokiReadURL: notificationHistory.Key("loki_remote_read_url").MustString(""), + LokiWriteURL: notificationHistory.Key("loki_remote_write_url").MustString(""), + LokiTenantID: notificationHistory.Key("loki_tenant_id").MustString(""), + LokiBasicAuthUsername: notificationHistory.Key("loki_basic_auth_username").MustString(""), + LokiBasicAuthPassword: notificationHistory.Key("loki_basic_auth_password").MustString(""), + LokiMaxQueryLength: notificationHistory.Key("loki_max_query_length").MustDuration(lokiDefaultMaxQueryLength), + LokiMaxQuerySize: notificationHistory.Key("loki_max_query_size").MustInt(lokiDefaultMaxQuerySize), + ExternalLabels: notificationHistoryLabels.KeysHash(), + }, } uaCfg.NotificationHistory = uaCfgNotificationHistory