diff --git a/pkg/services/ngalert/metrics/scheduler.go b/pkg/services/ngalert/metrics/scheduler.go index 2a3cf441702..d6c6707f0a9 100644 --- a/pkg/services/ngalert/metrics/scheduler.go +++ b/pkg/services/ngalert/metrics/scheduler.go @@ -4,7 +4,7 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" - "github.com/grafana/grafana/pkg/util/ticker" + "github.com/grafana/grafana/pkg/services/ngalert/schedule/ticker" ) const ( diff --git a/pkg/services/ngalert/schedule/schedule.go b/pkg/services/ngalert/schedule/schedule.go index 67aba2ab917..e0b3b6faf0d 100644 --- a/pkg/services/ngalert/schedule/schedule.go +++ b/pkg/services/ngalert/schedule/schedule.go @@ -18,9 +18,9 @@ import ( "github.com/grafana/grafana/pkg/services/ngalert/eval" "github.com/grafana/grafana/pkg/services/ngalert/metrics" ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models" + "github.com/grafana/grafana/pkg/services/ngalert/schedule/ticker" "github.com/grafana/grafana/pkg/services/ngalert/state" "github.com/grafana/grafana/pkg/setting" - "github.com/grafana/grafana/pkg/util/ticker" ) // ScheduleService is an interface for a service that schedules the evaluation @@ -169,7 +169,7 @@ func NewScheduler(cfg SchedulerCfg, stateManager *state.Manager) *schedule { func (sch *schedule) Run(ctx context.Context) error { sch.log.Info("Starting scheduler", "tickInterval", sch.baseInterval, "maxAttempts", sch.maxAttempts) - t := ticker.New(sch.clock, sch.baseInterval, sch.metrics.Ticker) + t := ticker.New(sch.clock, sch.baseInterval, sch.metrics.Ticker, sch.log) defer t.Stop() if err := sch.schedulePeriodic(ctx, t); err != nil { diff --git a/pkg/util/ticker/metrics.go b/pkg/services/ngalert/schedule/ticker/metrics.go similarity index 100% rename from pkg/util/ticker/metrics.go rename to pkg/services/ngalert/schedule/ticker/metrics.go diff --git a/pkg/util/ticker/ticker.go b/pkg/services/ngalert/schedule/ticker/ticker.go similarity index 89% rename from pkg/util/ticker/ticker.go rename to pkg/services/ngalert/schedule/ticker/ticker.go index 502325ca07f..a52b9c4e559 100644 --- a/pkg/util/ticker/ticker.go +++ b/pkg/services/ngalert/schedule/ticker/ticker.go @@ -21,10 +21,11 @@ type T struct { interval time.Duration metrics *Metrics stopCh chan struct{} + logger log.Logger } // NewTicker returns a Ticker that ticks on interval marks (or very shortly after) starting at c.Now(), and never drops ticks. interval should not be negative or zero. -func New(c clock.Clock, interval time.Duration, metric *Metrics) *T { +func New(c clock.Clock, interval time.Duration, metric *Metrics, logger log.Logger) *T { if interval <= 0 { panic(fmt.Errorf("non-positive interval [%v] is not allowed", interval)) } @@ -35,6 +36,7 @@ func New(c clock.Clock, interval time.Duration, metric *Metrics) *T { interval: interval, metrics: metric, stopCh: make(chan struct{}), + logger: logger, } metric.IntervalSeconds.Set(t.interval.Seconds()) // Seconds report fractional part as well, so it matches the format of the timestamp we report below go t.run() @@ -47,8 +49,7 @@ func getStartTick(clk clock.Clock, interval time.Duration) time.Time { } func (t *T) run() { - logger := log.New("ticker") - logger.Info("starting", "first_tick", t.last.Add(t.interval)) + t.logger.Info("starting", "component", "ticker", "first_tick", t.last.Add(t.interval)) LOOP: for { next := t.last.Add(t.interval) // calculate the time of the next tick @@ -72,7 +73,7 @@ LOOP: break LOOP } } - logger.Info("stopped", "last_tick", t.last) + t.logger.Info("stopped", "component", "ticker", "last_tick", t.last) } // Stop stops the ticker. It does not close the C channel diff --git a/pkg/util/ticker/ticker_test.go b/pkg/services/ngalert/schedule/ticker/ticker_test.go similarity index 95% rename from pkg/util/ticker/ticker_test.go rename to pkg/services/ngalert/schedule/ticker/ticker_test.go index 39cbca221e7..b83dabff083 100644 --- a/pkg/util/ticker/ticker_test.go +++ b/pkg/services/ngalert/schedule/ticker/ticker_test.go @@ -13,6 +13,8 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/testutil" "github.com/stretchr/testify/require" + + "github.com/grafana/grafana/pkg/infra/log/logtest" ) func TestTicker(t *testing.T) { @@ -51,7 +53,7 @@ func TestTicker(t *testing.T) { interval := time.Duration(rand.Int63n(100)+10) * time.Second clk := clock.NewMock() clk.Add(interval) // align clock with the start tick - ticker := New(clk, interval, NewMetrics(prometheus.NewRegistry(), "test")) + ticker := New(clk, interval, NewMetrics(prometheus.NewRegistry(), "test"), &logtest.Fake{}) ticks := rand.Intn(9) + 1 jitter := rand.Int63n(int64(interval) - 1) @@ -85,7 +87,7 @@ func TestTicker(t *testing.T) { t.Run("should not put anything to channel until it's time", func(t *testing.T) { clk := clock.NewMock() interval := time.Duration(rand.Int63n(9)+1) * time.Second - ticker := New(clk, interval, NewMetrics(prometheus.NewRegistry(), "test")) + ticker := New(clk, interval, NewMetrics(prometheus.NewRegistry(), "test"), &logtest.Fake{}) expectedTick := clk.Now().Add(interval) for { require.Empty(t, ticker.C) @@ -102,7 +104,7 @@ func TestTicker(t *testing.T) { t.Run("should put the tick in the channel immediately if it is behind", func(t *testing.T) { clk := clock.NewMock() interval := time.Duration(rand.Int63n(9)+1) * time.Second - ticker := New(clk, interval, NewMetrics(prometheus.NewRegistry(), "test")) + ticker := New(clk, interval, NewMetrics(prometheus.NewRegistry(), "test"), &logtest.Fake{}) // We can expect the first tick to be at a consistent interval. Take a snapshot of the clock now, before we advance it. expectedTick := clk.Now().Add(interval) @@ -131,7 +133,7 @@ func TestTicker(t *testing.T) { clk.Set(time.Now()) interval := time.Duration(rand.Int63n(9)+1) * time.Second registry := prometheus.NewPedanticRegistry() - ticker := New(clk, interval, NewMetrics(registry, "test")) + ticker := New(clk, interval, NewMetrics(registry, "test"), &logtest.Fake{}) expectedTick := getStartTick(clk, interval).Add(interval) expectedMetricFmt := `# HELP grafana_test_ticker_interval_seconds Interval at which the ticker is meant to tick. @@ -174,7 +176,7 @@ func TestTicker(t *testing.T) { t.Run("when it waits for the next tick", func(t *testing.T) { clk := clock.NewMock() interval := time.Duration(rand.Int63n(9)+1) * time.Second - ticker := New(clk, interval, NewMetrics(prometheus.NewRegistry(), "test")) + ticker := New(clk, interval, NewMetrics(prometheus.NewRegistry(), "test"), &logtest.Fake{}) clk.Add(interval) readChanOrFail(t, ticker.C) ticker.Stop() @@ -185,7 +187,7 @@ func TestTicker(t *testing.T) { t.Run("when it waits for the tick to be consumed", func(t *testing.T) { clk := clock.NewMock() interval := time.Duration(rand.Int63n(9)+1) * time.Second - ticker := New(clk, interval, NewMetrics(prometheus.NewRegistry(), "test")) + ticker := New(clk, interval, NewMetrics(prometheus.NewRegistry(), "test"), &logtest.Fake{}) clk.Add(interval) ticker.Stop() require.Empty(t, ticker.C) @@ -194,7 +196,7 @@ func TestTicker(t *testing.T) { t.Run("multiple times", func(t *testing.T) { clk := clock.NewMock() interval := time.Duration(rand.Int63n(9)+1) * time.Second - ticker := New(clk, interval, NewMetrics(prometheus.NewRegistry(), "test")) + ticker := New(clk, interval, NewMetrics(prometheus.NewRegistry(), "test"), &logtest.Fake{}) ticker.Stop() ticker.Stop() ticker.Stop()