Advisor: Make evaluation interval and max history configurable (#100534)
This commit is contained in:
@@ -4,11 +4,13 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana-app-sdk/app"
|
||||
"github.com/grafana/grafana-app-sdk/k8s"
|
||||
"github.com/grafana/grafana-app-sdk/resource"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend/gtime"
|
||||
advisorv0alpha1 "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1"
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/app/checkregistry"
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/app/checks"
|
||||
@@ -16,24 +18,35 @@ import (
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
const evaluateChecksInterval = 24 * time.Hour
|
||||
const maxChecks = 10
|
||||
const defaultEvaluationInterval = 24 * time.Hour
|
||||
const defaultMaxHistory = 10
|
||||
|
||||
// Runner is a "runnable" app used to be able to expose and API endpoint
|
||||
// with the existing checks types. This does not need to be a CRUD resource, but it is
|
||||
// the only way existing at the moment to expose the check types.
|
||||
type Runner struct {
|
||||
checkRegistry checkregistry.CheckService
|
||||
client resource.Client
|
||||
checkRegistry checkregistry.CheckService
|
||||
client resource.Client
|
||||
evaluationInterval time.Duration
|
||||
maxHistory int
|
||||
}
|
||||
|
||||
// NewRunner creates a new Runner.
|
||||
func New(cfg app.Config) (app.Runnable, error) {
|
||||
// Read config
|
||||
checkRegistry, ok := cfg.SpecificConfig.(checkregistry.CheckService)
|
||||
specificConfig, ok := cfg.SpecificConfig.(checkregistry.AdvisorAppConfig)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid config type")
|
||||
}
|
||||
checkRegistry := specificConfig.CheckRegistry
|
||||
evalInterval, err := getEvaluationInterval(specificConfig.PluginConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
maxHistory, err := getMaxHistory(specificConfig.PluginConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Prepare storage client
|
||||
clientGenerator := k8s.NewClientRegistry(cfg.KubeConfig, k8s.ClientConfig{})
|
||||
@@ -43,8 +56,10 @@ func New(cfg app.Config) (app.Runnable, error) {
|
||||
}
|
||||
|
||||
return &Runner{
|
||||
checkRegistry: checkRegistry,
|
||||
client: client,
|
||||
checkRegistry: checkRegistry,
|
||||
client: client,
|
||||
evaluationInterval: evalInterval,
|
||||
maxHistory: maxHistory,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -64,7 +79,7 @@ func (r *Runner) Run(ctx context.Context) error {
|
||||
}
|
||||
}
|
||||
|
||||
nextSendInterval := time.Until(lastCreated.Add(evaluateChecksInterval))
|
||||
nextSendInterval := time.Until(lastCreated.Add(r.evaluationInterval))
|
||||
if nextSendInterval < time.Minute {
|
||||
nextSendInterval = 1 * time.Minute
|
||||
}
|
||||
@@ -85,8 +100,8 @@ func (r *Runner) Run(ctx context.Context) error {
|
||||
klog.Error("Error cleaning up old check reports", "error", err)
|
||||
}
|
||||
|
||||
if nextSendInterval != evaluateChecksInterval {
|
||||
nextSendInterval = evaluateChecksInterval
|
||||
if nextSendInterval != r.evaluationInterval {
|
||||
nextSendInterval = r.evaluationInterval
|
||||
}
|
||||
ticker.Reset(nextSendInterval)
|
||||
case <-ctx.Done():
|
||||
@@ -155,7 +170,7 @@ func (r *Runner) cleanupChecks(ctx context.Context) error {
|
||||
}
|
||||
|
||||
for _, checks := range checksByType {
|
||||
if len(checks) > maxChecks {
|
||||
if len(checks) > r.maxHistory {
|
||||
// Sort checks by creation time
|
||||
sort.Slice(checks, func(i, j int) bool {
|
||||
ti := checks[i].GetCreationTimestamp().Time
|
||||
@@ -163,7 +178,7 @@ func (r *Runner) cleanupChecks(ctx context.Context) error {
|
||||
return ti.Before(tj)
|
||||
})
|
||||
// Delete the oldest checks
|
||||
for i := 0; i < len(checks)-maxChecks; i++ {
|
||||
for i := 0; i < len(checks)-r.maxHistory; i++ {
|
||||
check := checks[i]
|
||||
id := check.GetStaticMetadata().Identifier()
|
||||
err := r.client.Delete(ctx, id, resource.DeleteOptions{})
|
||||
@@ -176,3 +191,29 @@ func (r *Runner) cleanupChecks(ctx context.Context) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getEvaluationInterval(pluginConfig map[string]string) (time.Duration, error) {
|
||||
evaluationInterval := defaultEvaluationInterval
|
||||
configEvaluationInterval, ok := pluginConfig["evaluation_interval"]
|
||||
if ok {
|
||||
var err error
|
||||
evaluationInterval, err = gtime.ParseDuration(configEvaluationInterval)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("invalid evaluation interval: %w", err)
|
||||
}
|
||||
}
|
||||
return evaluationInterval, nil
|
||||
}
|
||||
|
||||
func getMaxHistory(pluginConfig map[string]string) (int, error) {
|
||||
maxHistory := defaultMaxHistory
|
||||
configMaxHistory, ok := pluginConfig["max_history"]
|
||||
if ok {
|
||||
var err error
|
||||
maxHistory, err = strconv.Atoi(configMaxHistory)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("invalid max history: %w", err)
|
||||
}
|
||||
}
|
||||
return maxHistory, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user