Alerting: Instrument outbound requests for Loki Historian and Remote Alertmanager with tracing (#89185)
* Add TracedClient * Handle errors and status codes * Wire up tracing to normal ASH and loki annotation mapping * Add tracing to remote alertmanager * one more spot * and not or * More consistency with other grafana traces, lower cardinality name
This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
|||||||
|
|
||||||
"github.com/grafana/grafana/pkg/infra/db"
|
"github.com/grafana/grafana/pkg/infra/db"
|
||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
|
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||||
"github.com/grafana/grafana/pkg/services/annotations"
|
"github.com/grafana/grafana/pkg/services/annotations"
|
||||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||||
"github.com/grafana/grafana/pkg/services/tag"
|
"github.com/grafana/grafana/pkg/services/tag"
|
||||||
@@ -27,6 +28,7 @@ func ProvideService(
|
|||||||
cfg *setting.Cfg,
|
cfg *setting.Cfg,
|
||||||
features featuremgmt.FeatureToggles,
|
features featuremgmt.FeatureToggles,
|
||||||
tagService tag.Service,
|
tagService tag.Service,
|
||||||
|
tracer tracing.Tracer,
|
||||||
) *RepositoryImpl {
|
) *RepositoryImpl {
|
||||||
l := log.New("annotations")
|
l := log.New("annotations")
|
||||||
l.Debug("Initializing annotations service")
|
l.Debug("Initializing annotations service")
|
||||||
@@ -35,7 +37,7 @@ func ProvideService(
|
|||||||
write := xormStore
|
write := xormStore
|
||||||
|
|
||||||
var read readStore
|
var read readStore
|
||||||
historianStore := loki.NewLokiHistorianStore(cfg.UnifiedAlerting.StateHistory, features, db, log.New("annotations.loki"))
|
historianStore := loki.NewLokiHistorianStore(cfg.UnifiedAlerting.StateHistory, features, db, log.New("annotations.loki"), tracer)
|
||||||
if historianStore != nil {
|
if historianStore != nil {
|
||||||
l.Debug("Using composite read store")
|
l.Debug("Using composite read store")
|
||||||
read = NewCompositeStore(log.New("annotations.composite"), xormStore, historianStore)
|
read = NewCompositeStore(log.New("annotations.composite"), xormStore, historianStore)
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ func TestIntegrationAnnotationListingWithRBAC(t *testing.T) {
|
|||||||
features := featuremgmt.WithFeatures()
|
features := featuremgmt.WithFeatures()
|
||||||
tagService := tagimpl.ProvideService(sql)
|
tagService := tagimpl.ProvideService(sql)
|
||||||
|
|
||||||
repo := ProvideService(sql, cfg, features, tagService)
|
repo := ProvideService(sql, cfg, features, tagService, tracing.InitializeTracerForTest())
|
||||||
|
|
||||||
dashboard1 := testutil.CreateDashboard(t, sql, cfg, features, dashboards.SaveDashboardCommand{
|
dashboard1 := testutil.CreateDashboard(t, sql, cfg, features, dashboards.SaveDashboardCommand{
|
||||||
UserID: 1,
|
UserID: 1,
|
||||||
@@ -317,7 +317,7 @@ func TestIntegrationAnnotationListingWithInheritedRBAC(t *testing.T) {
|
|||||||
cfg := setting.NewCfg()
|
cfg := setting.NewCfg()
|
||||||
cfg.AnnotationMaximumTagsLength = 60
|
cfg.AnnotationMaximumTagsLength = 60
|
||||||
|
|
||||||
repo := ProvideService(sql, cfg, tc.features, tagimpl.ProvideService(sql))
|
repo := ProvideService(sql, cfg, tc.features, tagimpl.ProvideService(sql), tracing.InitializeTracerForTest())
|
||||||
|
|
||||||
usr.Permissions = map[int64]map[string][]string{1: tc.permissions}
|
usr.Permissions = map[int64]map[string][]string{1: tc.permissions}
|
||||||
testutil.SetupRBACPermission(t, sql, role, usr)
|
testutil.SetupRBACPermission(t, sql, role, usr)
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import (
|
|||||||
|
|
||||||
"github.com/grafana/grafana/pkg/infra/db"
|
"github.com/grafana/grafana/pkg/infra/db"
|
||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
|
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||||
ngmetrics "github.com/grafana/grafana/pkg/services/ngalert/metrics"
|
ngmetrics "github.com/grafana/grafana/pkg/services/ngalert/metrics"
|
||||||
ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models"
|
ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models"
|
||||||
"github.com/grafana/grafana/pkg/services/ngalert/state"
|
"github.com/grafana/grafana/pkg/services/ngalert/state"
|
||||||
@@ -53,7 +54,7 @@ type LokiHistorianStore struct {
|
|||||||
log log.Logger
|
log log.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewLokiHistorianStore(cfg setting.UnifiedAlertingStateHistorySettings, ft featuremgmt.FeatureToggles, db db.DB, log log.Logger) *LokiHistorianStore {
|
func NewLokiHistorianStore(cfg setting.UnifiedAlertingStateHistorySettings, ft featuremgmt.FeatureToggles, db db.DB, log log.Logger, tracer tracing.Tracer) *LokiHistorianStore {
|
||||||
if !useStore(cfg, ft) {
|
if !useStore(cfg, ft) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -64,7 +65,7 @@ func NewLokiHistorianStore(cfg setting.UnifiedAlertingStateHistorySettings, ft f
|
|||||||
}
|
}
|
||||||
|
|
||||||
return &LokiHistorianStore{
|
return &LokiHistorianStore{
|
||||||
client: historian.NewLokiClient(lokiCfg, historian.NewRequester(), ngmetrics.NewHistorianMetrics(prometheus.DefaultRegisterer, subsystem), log),
|
client: historian.NewLokiClient(lokiCfg, historian.NewRequester(), ngmetrics.NewHistorianMetrics(prometheus.DefaultRegisterer, subsystem), log, tracer),
|
||||||
db: db,
|
db: db,
|
||||||
log: log,
|
log: log,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,11 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/grafana/dskit/instrument"
|
"github.com/grafana/dskit/instrument"
|
||||||
|
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||||
|
"go.opentelemetry.io/otel/attribute"
|
||||||
|
"go.opentelemetry.io/otel/codes"
|
||||||
|
semconv "go.opentelemetry.io/otel/semconv/v1.17.0"
|
||||||
|
"go.opentelemetry.io/otel/trace"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Requester executes an HTTP request.
|
// Requester executes an HTTP request.
|
||||||
@@ -14,7 +19,7 @@ type Requester interface {
|
|||||||
Do(req *http.Request) (*http.Response, error)
|
Do(req *http.Request) (*http.Response, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TimedClient instruments a request. It implements Requester.
|
// TimedClient instruments a request with metrics. It implements Requester.
|
||||||
type TimedClient struct {
|
type TimedClient struct {
|
||||||
client Requester
|
client Requester
|
||||||
collector instrument.Collector
|
collector instrument.Collector
|
||||||
@@ -70,3 +75,51 @@ func TimeRequest(ctx context.Context, operation string, coll instrument.Collecto
|
|||||||
coll, toStatusCode, doRequest)
|
coll, toStatusCode, doRequest)
|
||||||
return response, err
|
return response, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TracedClient instruments a request with tracing. It implements Requester.
|
||||||
|
type TracedClient struct {
|
||||||
|
client Requester
|
||||||
|
tracer tracing.Tracer
|
||||||
|
name string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTracedClient(client Requester, tracer tracing.Tracer, name string) *TracedClient {
|
||||||
|
return &TracedClient{
|
||||||
|
client: client,
|
||||||
|
tracer: tracer,
|
||||||
|
name: name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do executes the request.
|
||||||
|
func (c TracedClient) Do(r *http.Request) (*http.Response, error) {
|
||||||
|
ctx, span := c.tracer.Start(r.Context(), c.name, trace.WithSpanKind(trace.SpanKindClient))
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
|
span.SetAttributes(semconv.HTTPURL(r.URL.String()))
|
||||||
|
span.SetAttributes(semconv.HTTPMethod(r.Method))
|
||||||
|
|
||||||
|
c.tracer.Inject(ctx, r.Header, span)
|
||||||
|
|
||||||
|
r = r.WithContext(ctx)
|
||||||
|
resp, err := c.client.Do(r)
|
||||||
|
if err != nil {
|
||||||
|
span.SetStatus(codes.Error, "request failed")
|
||||||
|
span.RecordError(err)
|
||||||
|
} else {
|
||||||
|
if resp.ContentLength > 0 {
|
||||||
|
span.SetAttributes(attribute.Int64("http.content_length", resp.ContentLength))
|
||||||
|
}
|
||||||
|
span.SetAttributes(semconv.HTTPStatusCode(resp.StatusCode))
|
||||||
|
if resp.StatusCode >= 400 && resp.StatusCode < 600 {
|
||||||
|
span.RecordError(fmt.Errorf("error with HTTP status code %d", resp.StatusCode))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// RoundTrip implements the RoundTripper interface.
|
||||||
|
func (c TracedClient) RoundTrip(r *http.Request) (*http.Response, error) {
|
||||||
|
return c.Do(r)
|
||||||
|
}
|
||||||
|
|||||||
@@ -200,7 +200,7 @@ func (ng *AlertNG) init() error {
|
|||||||
PromoteConfig: true,
|
PromoteConfig: true,
|
||||||
SyncInterval: ng.Cfg.UnifiedAlerting.RemoteAlertmanager.SyncInterval,
|
SyncInterval: ng.Cfg.UnifiedAlerting.RemoteAlertmanager.SyncInterval,
|
||||||
}
|
}
|
||||||
remoteAM, err := createRemoteAlertmanager(cfg, ng.KVStore, ng.SecretsService.Decrypt, autogenFn, m)
|
remoteAM, err := createRemoteAlertmanager(cfg, ng.KVStore, ng.SecretsService.Decrypt, autogenFn, m, ng.tracer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
moaLogger.Error("Failed to create remote Alertmanager", "err", err)
|
moaLogger.Error("Failed to create remote Alertmanager", "err", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -234,7 +234,7 @@ func (ng *AlertNG) init() error {
|
|||||||
TenantID: ng.Cfg.UnifiedAlerting.RemoteAlertmanager.TenantID,
|
TenantID: ng.Cfg.UnifiedAlerting.RemoteAlertmanager.TenantID,
|
||||||
URL: ng.Cfg.UnifiedAlerting.RemoteAlertmanager.URL,
|
URL: ng.Cfg.UnifiedAlerting.RemoteAlertmanager.URL,
|
||||||
}
|
}
|
||||||
remoteAM, err := createRemoteAlertmanager(cfg, ng.KVStore, ng.SecretsService.Decrypt, autogenFn, m)
|
remoteAM, err := createRemoteAlertmanager(cfg, ng.KVStore, ng.SecretsService.Decrypt, autogenFn, m, ng.tracer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
moaLogger.Error("Failed to create remote Alertmanager, falling back to using only the internal one", "err", err)
|
moaLogger.Error("Failed to create remote Alertmanager, falling back to using only the internal one", "err", err)
|
||||||
return internalAM, nil
|
return internalAM, nil
|
||||||
@@ -270,7 +270,7 @@ func (ng *AlertNG) init() error {
|
|||||||
URL: ng.Cfg.UnifiedAlerting.RemoteAlertmanager.URL,
|
URL: ng.Cfg.UnifiedAlerting.RemoteAlertmanager.URL,
|
||||||
SyncInterval: ng.Cfg.UnifiedAlerting.RemoteAlertmanager.SyncInterval,
|
SyncInterval: ng.Cfg.UnifiedAlerting.RemoteAlertmanager.SyncInterval,
|
||||||
}
|
}
|
||||||
remoteAM, err := createRemoteAlertmanager(cfg, ng.KVStore, ng.SecretsService.Decrypt, autogenFn, m)
|
remoteAM, err := createRemoteAlertmanager(cfg, ng.KVStore, ng.SecretsService.Decrypt, autogenFn, m, ng.tracer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
moaLogger.Error("Failed to create remote Alertmanager, falling back to using only the internal one", "err", err)
|
moaLogger.Error("Failed to create remote Alertmanager, falling back to using only the internal one", "err", err)
|
||||||
return internalAM, nil
|
return internalAM, nil
|
||||||
@@ -359,7 +359,7 @@ func (ng *AlertNG) init() error {
|
|||||||
// There are a set of feature toggles available that act as short-circuits for common configurations.
|
// There are a set of feature toggles available that act as short-circuits for common configurations.
|
||||||
// If any are set, override the config accordingly.
|
// If any are set, override the config accordingly.
|
||||||
ApplyStateHistoryFeatureToggles(&ng.Cfg.UnifiedAlerting.StateHistory, ng.FeatureToggles, ng.Log)
|
ApplyStateHistoryFeatureToggles(&ng.Cfg.UnifiedAlerting.StateHistory, ng.FeatureToggles, ng.Log)
|
||||||
history, err := configureHistorianBackend(initCtx, ng.Cfg.UnifiedAlerting.StateHistory, ng.annotationsRepo, ng.dashboardService, ng.store, ng.Metrics.GetHistorianMetrics(), ng.Log)
|
history, err := configureHistorianBackend(initCtx, ng.Cfg.UnifiedAlerting.StateHistory, ng.annotationsRepo, ng.dashboardService, ng.store, ng.Metrics.GetHistorianMetrics(), ng.Log, ng.tracer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -523,7 +523,7 @@ type Historian interface {
|
|||||||
state.Historian
|
state.Historian
|
||||||
}
|
}
|
||||||
|
|
||||||
func configureHistorianBackend(ctx context.Context, cfg setting.UnifiedAlertingStateHistorySettings, ar annotations.Repository, ds dashboards.DashboardService, rs historian.RuleStore, met *metrics.Historian, l log.Logger) (Historian, error) {
|
func configureHistorianBackend(ctx context.Context, cfg setting.UnifiedAlertingStateHistorySettings, ar annotations.Repository, ds dashboards.DashboardService, rs historian.RuleStore, met *metrics.Historian, l log.Logger, tracer tracing.Tracer) (Historian, error) {
|
||||||
if !cfg.Enabled {
|
if !cfg.Enabled {
|
||||||
met.Info.WithLabelValues("noop").Set(0)
|
met.Info.WithLabelValues("noop").Set(0)
|
||||||
return historian.NewNopHistorian(), nil
|
return historian.NewNopHistorian(), nil
|
||||||
@@ -538,7 +538,7 @@ func configureHistorianBackend(ctx context.Context, cfg setting.UnifiedAlertingS
|
|||||||
if backend == historian.BackendTypeMultiple {
|
if backend == historian.BackendTypeMultiple {
|
||||||
primaryCfg := cfg
|
primaryCfg := cfg
|
||||||
primaryCfg.Backend = cfg.MultiPrimary
|
primaryCfg.Backend = cfg.MultiPrimary
|
||||||
primary, err := configureHistorianBackend(ctx, primaryCfg, ar, ds, rs, met, l)
|
primary, err := configureHistorianBackend(ctx, primaryCfg, ar, ds, rs, met, l, tracer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("multi-backend target \"%s\" was misconfigured: %w", cfg.MultiPrimary, err)
|
return nil, fmt.Errorf("multi-backend target \"%s\" was misconfigured: %w", cfg.MultiPrimary, err)
|
||||||
}
|
}
|
||||||
@@ -547,7 +547,7 @@ func configureHistorianBackend(ctx context.Context, cfg setting.UnifiedAlertingS
|
|||||||
for _, b := range cfg.MultiSecondaries {
|
for _, b := range cfg.MultiSecondaries {
|
||||||
secCfg := cfg
|
secCfg := cfg
|
||||||
secCfg.Backend = b
|
secCfg.Backend = b
|
||||||
sec, err := configureHistorianBackend(ctx, secCfg, ar, ds, rs, met, l)
|
sec, err := configureHistorianBackend(ctx, secCfg, ar, ds, rs, met, l, tracer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("multi-backend target \"%s\" was miconfigured: %w", b, err)
|
return nil, fmt.Errorf("multi-backend target \"%s\" was miconfigured: %w", b, err)
|
||||||
}
|
}
|
||||||
@@ -569,7 +569,7 @@ func configureHistorianBackend(ctx context.Context, cfg setting.UnifiedAlertingS
|
|||||||
}
|
}
|
||||||
req := historian.NewRequester()
|
req := historian.NewRequester()
|
||||||
lokiBackendLogger := log.New("ngalert.state.historian", "backend", "loki")
|
lokiBackendLogger := log.New("ngalert.state.historian", "backend", "loki")
|
||||||
backend := historian.NewRemoteLokiBackend(lokiBackendLogger, lcfg, req, met)
|
backend := historian.NewRemoteLokiBackend(lokiBackendLogger, lcfg, req, met, tracer)
|
||||||
|
|
||||||
testConnCtx, cancelFunc := context.WithTimeout(ctx, 10*time.Second)
|
testConnCtx, cancelFunc := context.WithTimeout(ctx, 10*time.Second)
|
||||||
defer cancelFunc()
|
defer cancelFunc()
|
||||||
@@ -627,8 +627,8 @@ func ApplyStateHistoryFeatureToggles(cfg *setting.UnifiedAlertingStateHistorySet
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func createRemoteAlertmanager(cfg remote.AlertmanagerConfig, kvstore kvstore.KVStore, decryptFn remote.DecryptFn, autogenFn remote.AutogenFn, m *metrics.RemoteAlertmanager) (*remote.Alertmanager, error) {
|
func createRemoteAlertmanager(cfg remote.AlertmanagerConfig, kvstore kvstore.KVStore, decryptFn remote.DecryptFn, autogenFn remote.AutogenFn, m *metrics.RemoteAlertmanager, tracer tracing.Tracer) (*remote.Alertmanager, error) {
|
||||||
return remote.NewAlertmanager(cfg, notifier.NewFileStore(cfg.OrgID, kvstore), decryptFn, autogenFn, m)
|
return remote.NewAlertmanager(cfg, notifier.NewFileStore(cfg.OrgID, kvstore), decryptFn, autogenFn, m, tracer)
|
||||||
}
|
}
|
||||||
|
|
||||||
func createRecordingWriter(featureToggles featuremgmt.FeatureToggles, settings setting.RecordingRuleSettings) (schedule.RecordingWriter, error) {
|
func createRecordingWriter(featureToggles featuremgmt.FeatureToggles, settings setting.RecordingRuleSettings) (schedule.RecordingWriter, error) {
|
||||||
|
|||||||
@@ -62,12 +62,13 @@ func TestConfigureHistorianBackend(t *testing.T) {
|
|||||||
t.Run("fail initialization if invalid backend", func(t *testing.T) {
|
t.Run("fail initialization if invalid backend", func(t *testing.T) {
|
||||||
met := metrics.NewHistorianMetrics(prometheus.NewRegistry(), metrics.Subsystem)
|
met := metrics.NewHistorianMetrics(prometheus.NewRegistry(), metrics.Subsystem)
|
||||||
logger := log.NewNopLogger()
|
logger := log.NewNopLogger()
|
||||||
|
tracer := tracing.InitializeTracerForTest()
|
||||||
cfg := setting.UnifiedAlertingStateHistorySettings{
|
cfg := setting.UnifiedAlertingStateHistorySettings{
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
Backend: "invalid-backend",
|
Backend: "invalid-backend",
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := configureHistorianBackend(context.Background(), cfg, nil, nil, nil, met, logger)
|
_, err := configureHistorianBackend(context.Background(), cfg, nil, nil, nil, met, logger, tracer)
|
||||||
|
|
||||||
require.ErrorContains(t, err, "unrecognized")
|
require.ErrorContains(t, err, "unrecognized")
|
||||||
})
|
})
|
||||||
@@ -75,13 +76,14 @@ func TestConfigureHistorianBackend(t *testing.T) {
|
|||||||
t.Run("fail initialization if invalid multi-backend primary", func(t *testing.T) {
|
t.Run("fail initialization if invalid multi-backend primary", func(t *testing.T) {
|
||||||
met := metrics.NewHistorianMetrics(prometheus.NewRegistry(), metrics.Subsystem)
|
met := metrics.NewHistorianMetrics(prometheus.NewRegistry(), metrics.Subsystem)
|
||||||
logger := log.NewNopLogger()
|
logger := log.NewNopLogger()
|
||||||
|
tracer := tracing.InitializeTracerForTest()
|
||||||
cfg := setting.UnifiedAlertingStateHistorySettings{
|
cfg := setting.UnifiedAlertingStateHistorySettings{
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
Backend: "multiple",
|
Backend: "multiple",
|
||||||
MultiPrimary: "invalid-backend",
|
MultiPrimary: "invalid-backend",
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := configureHistorianBackend(context.Background(), cfg, nil, nil, nil, met, logger)
|
_, err := configureHistorianBackend(context.Background(), cfg, nil, nil, nil, met, logger, tracer)
|
||||||
|
|
||||||
require.ErrorContains(t, err, "multi-backend target")
|
require.ErrorContains(t, err, "multi-backend target")
|
||||||
require.ErrorContains(t, err, "unrecognized")
|
require.ErrorContains(t, err, "unrecognized")
|
||||||
@@ -90,6 +92,7 @@ func TestConfigureHistorianBackend(t *testing.T) {
|
|||||||
t.Run("fail initialization if invalid multi-backend secondary", func(t *testing.T) {
|
t.Run("fail initialization if invalid multi-backend secondary", func(t *testing.T) {
|
||||||
met := metrics.NewHistorianMetrics(prometheus.NewRegistry(), metrics.Subsystem)
|
met := metrics.NewHistorianMetrics(prometheus.NewRegistry(), metrics.Subsystem)
|
||||||
logger := log.NewNopLogger()
|
logger := log.NewNopLogger()
|
||||||
|
tracer := tracing.InitializeTracerForTest()
|
||||||
cfg := setting.UnifiedAlertingStateHistorySettings{
|
cfg := setting.UnifiedAlertingStateHistorySettings{
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
Backend: "multiple",
|
Backend: "multiple",
|
||||||
@@ -97,7 +100,7 @@ func TestConfigureHistorianBackend(t *testing.T) {
|
|||||||
MultiSecondaries: []string{"annotations", "invalid-backend"},
|
MultiSecondaries: []string{"annotations", "invalid-backend"},
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := configureHistorianBackend(context.Background(), cfg, nil, nil, nil, met, logger)
|
_, err := configureHistorianBackend(context.Background(), cfg, nil, nil, nil, met, logger, tracer)
|
||||||
|
|
||||||
require.ErrorContains(t, err, "multi-backend target")
|
require.ErrorContains(t, err, "multi-backend target")
|
||||||
require.ErrorContains(t, err, "unrecognized")
|
require.ErrorContains(t, err, "unrecognized")
|
||||||
@@ -106,6 +109,7 @@ func TestConfigureHistorianBackend(t *testing.T) {
|
|||||||
t.Run("do not fail initialization if pinging Loki fails", func(t *testing.T) {
|
t.Run("do not fail initialization if pinging Loki fails", func(t *testing.T) {
|
||||||
met := metrics.NewHistorianMetrics(prometheus.NewRegistry(), metrics.Subsystem)
|
met := metrics.NewHistorianMetrics(prometheus.NewRegistry(), metrics.Subsystem)
|
||||||
logger := log.NewNopLogger()
|
logger := log.NewNopLogger()
|
||||||
|
tracer := tracing.InitializeTracerForTest()
|
||||||
cfg := setting.UnifiedAlertingStateHistorySettings{
|
cfg := setting.UnifiedAlertingStateHistorySettings{
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
Backend: "loki",
|
Backend: "loki",
|
||||||
@@ -114,7 +118,7 @@ func TestConfigureHistorianBackend(t *testing.T) {
|
|||||||
LokiWriteURL: "http://gone.invalid",
|
LokiWriteURL: "http://gone.invalid",
|
||||||
}
|
}
|
||||||
|
|
||||||
h, err := configureHistorianBackend(context.Background(), cfg, nil, nil, nil, met, logger)
|
h, err := configureHistorianBackend(context.Background(), cfg, nil, nil, nil, met, logger, tracer)
|
||||||
|
|
||||||
require.NotNil(t, h)
|
require.NotNil(t, h)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -124,12 +128,13 @@ func TestConfigureHistorianBackend(t *testing.T) {
|
|||||||
reg := prometheus.NewRegistry()
|
reg := prometheus.NewRegistry()
|
||||||
met := metrics.NewHistorianMetrics(reg, metrics.Subsystem)
|
met := metrics.NewHistorianMetrics(reg, metrics.Subsystem)
|
||||||
logger := log.NewNopLogger()
|
logger := log.NewNopLogger()
|
||||||
|
tracer := tracing.InitializeTracerForTest()
|
||||||
cfg := setting.UnifiedAlertingStateHistorySettings{
|
cfg := setting.UnifiedAlertingStateHistorySettings{
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
Backend: "annotations",
|
Backend: "annotations",
|
||||||
}
|
}
|
||||||
|
|
||||||
h, err := configureHistorianBackend(context.Background(), cfg, nil, nil, nil, met, logger)
|
h, err := configureHistorianBackend(context.Background(), cfg, nil, nil, nil, met, logger, tracer)
|
||||||
|
|
||||||
require.NotNil(t, h)
|
require.NotNil(t, h)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -146,11 +151,12 @@ grafana_alerting_state_history_info{backend="annotations"} 1
|
|||||||
reg := prometheus.NewRegistry()
|
reg := prometheus.NewRegistry()
|
||||||
met := metrics.NewHistorianMetrics(reg, metrics.Subsystem)
|
met := metrics.NewHistorianMetrics(reg, metrics.Subsystem)
|
||||||
logger := log.NewNopLogger()
|
logger := log.NewNopLogger()
|
||||||
|
tracer := tracing.InitializeTracerForTest()
|
||||||
cfg := setting.UnifiedAlertingStateHistorySettings{
|
cfg := setting.UnifiedAlertingStateHistorySettings{
|
||||||
Enabled: false,
|
Enabled: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
h, err := configureHistorianBackend(context.Background(), cfg, nil, nil, nil, met, logger)
|
h, err := configureHistorianBackend(context.Background(), cfg, nil, nil, nil, met, logger, tracer)
|
||||||
|
|
||||||
require.NotNil(t, h)
|
require.NotNil(t, h)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
|
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||||
"github.com/grafana/grafana/pkg/services/ngalert/metrics"
|
"github.com/grafana/grafana/pkg/services/ngalert/metrics"
|
||||||
"github.com/grafana/grafana/pkg/services/ngalert/models"
|
"github.com/grafana/grafana/pkg/services/ngalert/models"
|
||||||
@@ -66,7 +67,7 @@ func TestMultiorgAlertmanager_RemoteSecondaryMode(t *testing.T) {
|
|||||||
DefaultConfig: setting.GetAlertmanagerDefaultConfiguration(),
|
DefaultConfig: setting.GetAlertmanagerDefaultConfiguration(),
|
||||||
}
|
}
|
||||||
m := metrics.NewRemoteAlertmanagerMetrics(prometheus.NewRegistry())
|
m := metrics.NewRemoteAlertmanagerMetrics(prometheus.NewRegistry())
|
||||||
remoteAM, err := remote.NewAlertmanager(externalAMCfg, notifier.NewFileStore(orgID, kvStore), secretsService.Decrypt, remote.NoopAutogenFn, m)
|
remoteAM, err := remote.NewAlertmanager(externalAMCfg, notifier.NewFileStore(orgID, kvStore), secretsService.Decrypt, remote.NoopAutogenFn, m, tracing.InitializeTracerForTest())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Use both Alertmanager implementations in the forked Alertmanager.
|
// Use both Alertmanager implementations in the forked Alertmanager.
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import (
|
|||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
|
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||||
apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
|
apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
|
||||||
"github.com/grafana/grafana/pkg/services/ngalert/metrics"
|
"github.com/grafana/grafana/pkg/services/ngalert/metrics"
|
||||||
"github.com/grafana/grafana/pkg/services/ngalert/models"
|
"github.com/grafana/grafana/pkg/services/ngalert/models"
|
||||||
@@ -100,7 +101,7 @@ func (cfg *AlertmanagerConfig) Validate() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAlertmanager(cfg AlertmanagerConfig, store stateStore, decryptFn DecryptFn, autogenFn AutogenFn, metrics *metrics.RemoteAlertmanager) (*Alertmanager, error) {
|
func NewAlertmanager(cfg AlertmanagerConfig, store stateStore, decryptFn DecryptFn, autogenFn AutogenFn, metrics *metrics.RemoteAlertmanager, tracer tracing.Tracer) (*Alertmanager, error) {
|
||||||
if err := cfg.Validate(); err != nil {
|
if err := cfg.Validate(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -118,7 +119,7 @@ func NewAlertmanager(cfg AlertmanagerConfig, store stateStore, decryptFn Decrypt
|
|||||||
URL: u,
|
URL: u,
|
||||||
PromoteConfig: cfg.PromoteConfig,
|
PromoteConfig: cfg.PromoteConfig,
|
||||||
}
|
}
|
||||||
mc, err := remoteClient.New(mcCfg, metrics)
|
mc, err := remoteClient.New(mcCfg, metrics, tracer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -129,7 +130,7 @@ func NewAlertmanager(cfg AlertmanagerConfig, store stateStore, decryptFn Decrypt
|
|||||||
Password: cfg.BasicAuthPassword,
|
Password: cfg.BasicAuthPassword,
|
||||||
Logger: logger,
|
Logger: logger,
|
||||||
}
|
}
|
||||||
amc, err := remoteClient.NewAlertmanager(amcCfg, metrics)
|
amc, err := remoteClient.NewAlertmanager(amcCfg, metrics, tracer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import (
|
|||||||
"github.com/grafana/alerting/definition"
|
"github.com/grafana/alerting/definition"
|
||||||
"github.com/grafana/grafana/pkg/infra/db"
|
"github.com/grafana/grafana/pkg/infra/db"
|
||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
|
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||||
apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
|
apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
|
||||||
"github.com/grafana/grafana/pkg/services/ngalert/metrics"
|
"github.com/grafana/grafana/pkg/services/ngalert/metrics"
|
||||||
ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models"
|
ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models"
|
||||||
@@ -105,7 +106,7 @@ func TestNewAlertmanager(t *testing.T) {
|
|||||||
DefaultConfig: defaultGrafanaConfig,
|
DefaultConfig: defaultGrafanaConfig,
|
||||||
}
|
}
|
||||||
m := metrics.NewRemoteAlertmanagerMetrics(prometheus.NewRegistry())
|
m := metrics.NewRemoteAlertmanagerMetrics(prometheus.NewRegistry())
|
||||||
am, err := NewAlertmanager(cfg, nil, secretsService.Decrypt, NoopAutogenFn, m)
|
am, err := NewAlertmanager(cfg, nil, secretsService.Decrypt, NoopAutogenFn, m, tracing.InitializeTracerForTest())
|
||||||
if test.expErr != "" {
|
if test.expErr != "" {
|
||||||
require.EqualError(tt, err, test.expErr)
|
require.EqualError(tt, err, test.expErr)
|
||||||
return
|
return
|
||||||
@@ -177,7 +178,7 @@ func TestApplyConfig(t *testing.T) {
|
|||||||
|
|
||||||
// An error response from the remote Alertmanager should result in the readiness check failing.
|
// An error response from the remote Alertmanager should result in the readiness check failing.
|
||||||
m := metrics.NewRemoteAlertmanagerMetrics(prometheus.NewRegistry())
|
m := metrics.NewRemoteAlertmanagerMetrics(prometheus.NewRegistry())
|
||||||
am, err := NewAlertmanager(cfg, fstore, secretsService.Decrypt, NoopAutogenFn, m)
|
am, err := NewAlertmanager(cfg, fstore, secretsService.Decrypt, NoopAutogenFn, m, tracing.InitializeTracerForTest())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
config := &ngmodels.AlertConfiguration{
|
config := &ngmodels.AlertConfiguration{
|
||||||
@@ -305,6 +306,7 @@ func TestCompareAndSendConfiguration(t *testing.T) {
|
|||||||
decryptFn,
|
decryptFn,
|
||||||
test.autogenFn,
|
test.autogenFn,
|
||||||
m,
|
m,
|
||||||
|
tracing.InitializeTracerForTest(),
|
||||||
)
|
)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@@ -364,7 +366,7 @@ func TestIntegrationRemoteAlertmanagerConfiguration(t *testing.T) {
|
|||||||
|
|
||||||
secretsService := secretsManager.SetupTestService(t, database.ProvideSecretsStore(db.InitTestDB(t)))
|
secretsService := secretsManager.SetupTestService(t, database.ProvideSecretsStore(db.InitTestDB(t)))
|
||||||
m := metrics.NewRemoteAlertmanagerMetrics(prometheus.NewRegistry())
|
m := metrics.NewRemoteAlertmanagerMetrics(prometheus.NewRegistry())
|
||||||
am, err := NewAlertmanager(cfg, fstore, secretsService.Decrypt, NoopAutogenFn, m)
|
am, err := NewAlertmanager(cfg, fstore, secretsService.Decrypt, NoopAutogenFn, m, tracing.InitializeTracerForTest())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
encodedFullState, err := am.getFullState(ctx)
|
encodedFullState, err := am.getFullState(ctx)
|
||||||
@@ -521,7 +523,7 @@ func TestIntegrationRemoteAlertmanagerGetStatus(t *testing.T) {
|
|||||||
|
|
||||||
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
|
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
|
||||||
m := metrics.NewRemoteAlertmanagerMetrics(prometheus.NewRegistry())
|
m := metrics.NewRemoteAlertmanagerMetrics(prometheus.NewRegistry())
|
||||||
am, err := NewAlertmanager(cfg, nil, secretsService.Decrypt, NoopAutogenFn, m)
|
am, err := NewAlertmanager(cfg, nil, secretsService.Decrypt, NoopAutogenFn, m, tracing.InitializeTracerForTest())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// We should get the default Cloud Alertmanager configuration.
|
// We should get the default Cloud Alertmanager configuration.
|
||||||
@@ -555,7 +557,7 @@ func TestIntegrationRemoteAlertmanagerSilences(t *testing.T) {
|
|||||||
|
|
||||||
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
|
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
|
||||||
m := metrics.NewRemoteAlertmanagerMetrics(prometheus.NewRegistry())
|
m := metrics.NewRemoteAlertmanagerMetrics(prometheus.NewRegistry())
|
||||||
am, err := NewAlertmanager(cfg, nil, secretsService.Decrypt, NoopAutogenFn, m)
|
am, err := NewAlertmanager(cfg, nil, secretsService.Decrypt, NoopAutogenFn, m, tracing.InitializeTracerForTest())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// We should have no silences at first.
|
// We should have no silences at first.
|
||||||
@@ -640,7 +642,7 @@ func TestIntegrationRemoteAlertmanagerAlerts(t *testing.T) {
|
|||||||
|
|
||||||
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
|
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
|
||||||
m := metrics.NewRemoteAlertmanagerMetrics(prometheus.NewRegistry())
|
m := metrics.NewRemoteAlertmanagerMetrics(prometheus.NewRegistry())
|
||||||
am, err := NewAlertmanager(cfg, nil, secretsService.Decrypt, NoopAutogenFn, m)
|
am, err := NewAlertmanager(cfg, nil, secretsService.Decrypt, NoopAutogenFn, m, tracing.InitializeTracerForTest())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Wait until the Alertmanager is ready to send alerts.
|
// Wait until the Alertmanager is ready to send alerts.
|
||||||
@@ -709,7 +711,7 @@ func TestIntegrationRemoteAlertmanagerReceivers(t *testing.T) {
|
|||||||
|
|
||||||
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
|
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
|
||||||
m := metrics.NewRemoteAlertmanagerMetrics(prometheus.NewRegistry())
|
m := metrics.NewRemoteAlertmanagerMetrics(prometheus.NewRegistry())
|
||||||
am, err := NewAlertmanager(cfg, nil, secretsService.Decrypt, NoopAutogenFn, m)
|
am, err := NewAlertmanager(cfg, nil, secretsService.Decrypt, NoopAutogenFn, m, tracing.InitializeTracerForTest())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// We should start with the default config.
|
// We should start with the default config.
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import (
|
|||||||
|
|
||||||
httptransport "github.com/go-openapi/runtime/client"
|
httptransport "github.com/go-openapi/runtime/client"
|
||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"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/services/ngalert/client"
|
||||||
"github.com/grafana/grafana/pkg/services/ngalert/metrics"
|
"github.com/grafana/grafana/pkg/services/ngalert/metrics"
|
||||||
amclient "github.com/prometheus/alertmanager/api/v2/client"
|
amclient "github.com/prometheus/alertmanager/api/v2/client"
|
||||||
@@ -31,7 +32,7 @@ type Alertmanager struct {
|
|||||||
logger log.Logger
|
logger log.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAlertmanager(cfg *AlertmanagerConfig, metrics *metrics.RemoteAlertmanager) (*Alertmanager, error) {
|
func NewAlertmanager(cfg *AlertmanagerConfig, metrics *metrics.RemoteAlertmanager, tracer tracing.Tracer) (*Alertmanager, error) {
|
||||||
// First, add the authentication middleware.
|
// First, add the authentication middleware.
|
||||||
c := &http.Client{Transport: &MimirAuthRoundTripper{
|
c := &http.Client{Transport: &MimirAuthRoundTripper{
|
||||||
TenantID: cfg.TenantID,
|
TenantID: cfg.TenantID,
|
||||||
@@ -40,14 +41,15 @@ func NewAlertmanager(cfg *AlertmanagerConfig, metrics *metrics.RemoteAlertmanage
|
|||||||
}}
|
}}
|
||||||
|
|
||||||
tc := client.NewTimedClient(c, metrics.RequestLatency)
|
tc := client.NewTimedClient(c, metrics.RequestLatency)
|
||||||
|
trc := client.NewTracedClient(tc, tracer, "remote.alertmanager.client")
|
||||||
apiEndpoint := *cfg.URL
|
apiEndpoint := *cfg.URL
|
||||||
|
|
||||||
// Next, make sure you set the right path.
|
// Next, make sure you set the right path.
|
||||||
u := apiEndpoint.JoinPath(alertmanagerAPIMountPath, amclient.DefaultBasePath)
|
u := apiEndpoint.JoinPath(alertmanagerAPIMountPath, amclient.DefaultBasePath)
|
||||||
|
|
||||||
// Create an Alertmanager client using the timed client as the transport.
|
// Create an Alertmanager client using the instrumented client as the transport.
|
||||||
r := httptransport.New(u.Host, u.Path, []string{u.Scheme})
|
r := httptransport.New(u.Host, u.Path, []string{u.Scheme})
|
||||||
r.Transport = tc
|
r.Transport = trc
|
||||||
|
|
||||||
return &Alertmanager{
|
return &Alertmanager{
|
||||||
logger: cfg.Logger,
|
logger: cfg.Logger,
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
|
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||||
apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
|
apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
|
||||||
"github.com/grafana/grafana/pkg/services/ngalert/client"
|
"github.com/grafana/grafana/pkg/services/ngalert/client"
|
||||||
"github.com/grafana/grafana/pkg/services/ngalert/metrics"
|
"github.com/grafana/grafana/pkg/services/ngalert/metrics"
|
||||||
@@ -68,7 +69,7 @@ func (e *errorResponse) Error() string {
|
|||||||
return e.Error2
|
return e.Error2
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(cfg *Config, metrics *metrics.RemoteAlertmanager) (*Mimir, error) {
|
func New(cfg *Config, metrics *metrics.RemoteAlertmanager, tracer tracing.Tracer) (*Mimir, error) {
|
||||||
rt := &MimirAuthRoundTripper{
|
rt := &MimirAuthRoundTripper{
|
||||||
TenantID: cfg.TenantID,
|
TenantID: cfg.TenantID,
|
||||||
Password: cfg.Password,
|
Password: cfg.Password,
|
||||||
@@ -78,10 +79,12 @@ func New(cfg *Config, metrics *metrics.RemoteAlertmanager) (*Mimir, error) {
|
|||||||
c := &http.Client{
|
c := &http.Client{
|
||||||
Transport: rt,
|
Transport: rt,
|
||||||
}
|
}
|
||||||
|
tc := client.NewTimedClient(c, metrics.RequestLatency)
|
||||||
|
trc := client.NewTracedClient(tc, tracer, "remote.alertmanager.client")
|
||||||
|
|
||||||
return &Mimir{
|
return &Mimir{
|
||||||
endpoint: cfg.URL,
|
endpoint: cfg.URL,
|
||||||
client: client.NewTimedClient(c, metrics.RequestLatency),
|
client: trc,
|
||||||
logger: cfg.Logger,
|
logger: cfg.Logger,
|
||||||
metrics: metrics,
|
metrics: metrics,
|
||||||
promoteConfig: cfg.PromoteConfig,
|
promoteConfig: cfg.PromoteConfig,
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import (
|
|||||||
|
|
||||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"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/services/ngalert/client"
|
||||||
"github.com/grafana/grafana/pkg/services/ngalert/eval"
|
"github.com/grafana/grafana/pkg/services/ngalert/eval"
|
||||||
"github.com/grafana/grafana/pkg/services/ngalert/metrics"
|
"github.com/grafana/grafana/pkg/services/ngalert/metrics"
|
||||||
@@ -55,9 +56,9 @@ type RemoteLokiBackend struct {
|
|||||||
log log.Logger
|
log log.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRemoteLokiBackend(logger log.Logger, cfg LokiConfig, req client.Requester, metrics *metrics.Historian) *RemoteLokiBackend {
|
func NewRemoteLokiBackend(logger log.Logger, cfg LokiConfig, req client.Requester, metrics *metrics.Historian, tracer tracing.Tracer) *RemoteLokiBackend {
|
||||||
return &RemoteLokiBackend{
|
return &RemoteLokiBackend{
|
||||||
client: NewLokiClient(cfg, req, metrics, logger),
|
client: NewLokiClient(cfg, req, metrics, logger, tracer),
|
||||||
externalLabels: cfg.ExternalLabels,
|
externalLabels: cfg.ExternalLabels,
|
||||||
clock: clock.New(),
|
clock: clock.New(),
|
||||||
metrics: metrics,
|
metrics: metrics,
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"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/services/ngalert/client"
|
||||||
"github.com/grafana/grafana/pkg/services/ngalert/metrics"
|
"github.com/grafana/grafana/pkg/services/ngalert/metrics"
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
@@ -103,10 +104,11 @@ const (
|
|||||||
NeqRegEx Operator = "!~"
|
NeqRegEx Operator = "!~"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewLokiClient(cfg LokiConfig, req client.Requester, metrics *metrics.Historian, logger log.Logger) *HttpLokiClient {
|
func NewLokiClient(cfg LokiConfig, req client.Requester, metrics *metrics.Historian, logger log.Logger, tracer tracing.Tracer) *HttpLokiClient {
|
||||||
tc := client.NewTimedClient(req, metrics.WriteDuration)
|
tc := client.NewTimedClient(req, metrics.WriteDuration)
|
||||||
|
trc := client.NewTracedClient(tc, tracer, "ngalert.historian.client")
|
||||||
return &HttpLokiClient{
|
return &HttpLokiClient{
|
||||||
client: tc,
|
client: trc,
|
||||||
encoder: cfg.Encoder,
|
encoder: cfg.Encoder,
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
metrics: metrics,
|
metrics: metrics,
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
|
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestLokiConfig(t *testing.T) {
|
func TestLokiConfig(t *testing.T) {
|
||||||
@@ -227,7 +228,7 @@ func TestLokiHTTPClient_Manual(t *testing.T) {
|
|||||||
ReadPathURL: url,
|
ReadPathURL: url,
|
||||||
WritePathURL: url,
|
WritePathURL: url,
|
||||||
Encoder: JsonEncoder{},
|
Encoder: JsonEncoder{},
|
||||||
}, NewRequester(), metrics.NewHistorianMetrics(prometheus.NewRegistry(), metrics.Subsystem), log.NewNopLogger())
|
}, NewRequester(), metrics.NewHistorianMetrics(prometheus.NewRegistry(), metrics.Subsystem), log.NewNopLogger(), tracing.InitializeTracerForTest())
|
||||||
|
|
||||||
// Unauthorized request should fail against Grafana Cloud.
|
// Unauthorized request should fail against Grafana Cloud.
|
||||||
err = client.Ping(context.Background())
|
err = client.Ping(context.Background())
|
||||||
@@ -255,7 +256,7 @@ func TestLokiHTTPClient_Manual(t *testing.T) {
|
|||||||
BasicAuthUser: "<your_username>",
|
BasicAuthUser: "<your_username>",
|
||||||
BasicAuthPassword: "<your_password>",
|
BasicAuthPassword: "<your_password>",
|
||||||
Encoder: JsonEncoder{},
|
Encoder: JsonEncoder{},
|
||||||
}, NewRequester(), metrics.NewHistorianMetrics(prometheus.NewRegistry(), metrics.Subsystem), log.NewNopLogger())
|
}, NewRequester(), metrics.NewHistorianMetrics(prometheus.NewRegistry(), metrics.Subsystem), log.NewNopLogger(), tracing.InitializeTracerForTest())
|
||||||
|
|
||||||
// When running on prem, you might need to set the tenant id,
|
// When running on prem, you might need to set the tenant id,
|
||||||
// so the x-scope-orgid header is set.
|
// so the x-scope-orgid header is set.
|
||||||
@@ -389,7 +390,7 @@ func createTestLokiClient(req client.Requester) *HttpLokiClient {
|
|||||||
Encoder: JsonEncoder{},
|
Encoder: JsonEncoder{},
|
||||||
}
|
}
|
||||||
met := metrics.NewHistorianMetrics(prometheus.NewRegistry(), metrics.Subsystem)
|
met := metrics.NewHistorianMetrics(prometheus.NewRegistry(), metrics.Subsystem)
|
||||||
return NewLokiClient(cfg, req, met, log.NewNopLogger())
|
return NewLokiClient(cfg, req, met, log.NewNopLogger(), tracing.InitializeTracerForTest())
|
||||||
}
|
}
|
||||||
|
|
||||||
func reqBody(t *testing.T, req *http.Request) string {
|
func reqBody(t *testing.T, req *http.Request) string {
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import (
|
|||||||
|
|
||||||
"github.com/grafana/grafana-plugin-sdk-go/data"
|
"github.com/grafana/grafana-plugin-sdk-go/data"
|
||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"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/services/ngalert/client"
|
||||||
"github.com/grafana/grafana/pkg/services/ngalert/eval"
|
"github.com/grafana/grafana/pkg/services/ngalert/eval"
|
||||||
"github.com/grafana/grafana/pkg/services/ngalert/metrics"
|
"github.com/grafana/grafana/pkg/services/ngalert/metrics"
|
||||||
@@ -514,7 +515,7 @@ func createTestLokiBackend(req client.Requester, met *metrics.Historian) *Remote
|
|||||||
ExternalLabels: map[string]string{"externalLabelKey": "externalLabelValue"},
|
ExternalLabels: map[string]string{"externalLabelKey": "externalLabelValue"},
|
||||||
}
|
}
|
||||||
lokiBackendLogger := log.New("ngalert.state.historian", "backend", "loki")
|
lokiBackendLogger := log.New("ngalert.state.historian", "backend", "loki")
|
||||||
return NewRemoteLokiBackend(lokiBackendLogger, cfg, req, met)
|
return NewRemoteLokiBackend(lokiBackendLogger, cfg, req, met, tracing.InitializeTracerForTest())
|
||||||
}
|
}
|
||||||
|
|
||||||
func singleFromNormal(st *state.State) []state.StateTransition {
|
func singleFromNormal(st *state.State) []state.StateTransition {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
|
|
||||||
"github.com/grafana/grafana/pkg/infra/db"
|
"github.com/grafana/grafana/pkg/infra/db"
|
||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
|
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||||
"github.com/grafana/grafana/pkg/services/annotations"
|
"github.com/grafana/grafana/pkg/services/annotations"
|
||||||
"github.com/grafana/grafana/pkg/services/annotations/annotationsimpl"
|
"github.com/grafana/grafana/pkg/services/annotations/annotationsimpl"
|
||||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||||
@@ -29,7 +30,7 @@ func newPublicDashboardServiceImpl(
|
|||||||
db, cfg := db.InitTestDBWithCfg(t)
|
db, cfg := db.InitTestDBWithCfg(t)
|
||||||
tagService := tagimpl.ProvideService(db)
|
tagService := tagimpl.ProvideService(db)
|
||||||
if annotationsRepo == nil {
|
if annotationsRepo == nil {
|
||||||
annotationsRepo = annotationsimpl.ProvideService(db, cfg, featuremgmt.WithFeatures(), tagService)
|
annotationsRepo = annotationsimpl.ProvideService(db, cfg, featuremgmt.WithFeatures(), tagService, tracing.InitializeTracerForTest())
|
||||||
}
|
}
|
||||||
|
|
||||||
if publicDashboardStore == nil {
|
if publicDashboardStore == nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user