mirror of
https://github.com/stakater/Reloader.git
synced 2026-08-27 14:37:17 +00:00
feat: Use strategic merge to patch workloads and add metrics for load testing
This commit is contained in:
@@ -38,11 +38,32 @@ func (h *ReloadHandler) Process(
|
||||
workloads, err := h.Lister.List(ctx, namespace)
|
||||
if err != nil {
|
||||
log.Error(err, "failed to list workloads")
|
||||
h.Collectors.RecordError("list_workloads")
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
||||
workloadsByKind := make(map[string]int)
|
||||
for _, w := range workloads {
|
||||
workloadsByKind[string(w.Kind())]++
|
||||
}
|
||||
for kind, count := range workloadsByKind {
|
||||
h.Collectors.RecordWorkloadsScanned(kind, count)
|
||||
}
|
||||
|
||||
decisions := reload.FilterDecisions(getDecisions(workloads))
|
||||
|
||||
matchedByKind := make(map[string]int)
|
||||
for _, d := range decisions {
|
||||
matchedByKind[string(d.Workload.Kind())]++
|
||||
}
|
||||
for kind, count := range matchedByKind {
|
||||
h.Collectors.RecordWorkloadsMatched(kind, count)
|
||||
}
|
||||
|
||||
if len(decisions) == 0 {
|
||||
h.Collectors.RecordSkipped("no_match")
|
||||
}
|
||||
|
||||
if h.WebhookClient.IsConfigured() && len(decisions) > 0 {
|
||||
return h.sendWebhook(ctx, resourceName, namespace, resourceType, decisions, log)
|
||||
}
|
||||
@@ -61,11 +82,13 @@ func (h *ReloadHandler) sendWebhook(
|
||||
var workloads []webhook.WorkloadInfo
|
||||
var hash string
|
||||
for _, d := range decisions {
|
||||
workloads = append(workloads, webhook.WorkloadInfo{
|
||||
Kind: string(d.Workload.Kind()),
|
||||
Name: d.Workload.GetName(),
|
||||
Namespace: d.Workload.GetNamespace(),
|
||||
})
|
||||
workloads = append(
|
||||
workloads, webhook.WorkloadInfo{
|
||||
Kind: string(d.Workload.Kind()),
|
||||
Name: d.Workload.GetName(),
|
||||
Namespace: d.Workload.GetNamespace(),
|
||||
},
|
||||
)
|
||||
if hash == "" {
|
||||
hash = d.Hash
|
||||
}
|
||||
@@ -81,17 +104,22 @@ func (h *ReloadHandler) sendWebhook(
|
||||
Workloads: workloads,
|
||||
}
|
||||
|
||||
actionStartTime := time.Now()
|
||||
if err := h.WebhookClient.Send(ctx, payload); err != nil {
|
||||
log.Error(err, "failed to send webhook notification")
|
||||
h.Collectors.RecordReload(false, namespace)
|
||||
h.Collectors.RecordAction("webhook", "error", time.Since(actionStartTime))
|
||||
h.Collectors.RecordError("webhook_send")
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
||||
log.Info("webhook notification sent",
|
||||
log.Info(
|
||||
"webhook notification sent",
|
||||
"resource", resourceName,
|
||||
"workloadCount", len(workloads),
|
||||
)
|
||||
h.Collectors.RecordReload(true, namespace)
|
||||
h.Collectors.RecordAction("webhook", "success", time.Since(actionStartTime))
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
@@ -103,12 +131,14 @@ func (h *ReloadHandler) applyReloads(
|
||||
log logr.Logger,
|
||||
) {
|
||||
for _, decision := range decisions {
|
||||
log.Info("reloading workload",
|
||||
log.Info(
|
||||
"reloading workload",
|
||||
"workload", decision.Workload.GetName(),
|
||||
"kind", decision.Workload.Kind(),
|
||||
"reason", decision.Reason,
|
||||
)
|
||||
|
||||
actionStartTime := time.Now()
|
||||
updated, err := UpdateWorkloadWithRetry(
|
||||
ctx,
|
||||
h.Client,
|
||||
@@ -121,35 +151,46 @@ func (h *ReloadHandler) applyReloads(
|
||||
decision.Hash,
|
||||
decision.AutoReload,
|
||||
)
|
||||
actionLatency := time.Since(actionStartTime)
|
||||
|
||||
if err != nil {
|
||||
log.Error(err, "failed to update workload",
|
||||
log.Error(
|
||||
err, "failed to update workload",
|
||||
"workload", decision.Workload.GetName(),
|
||||
"kind", decision.Workload.Kind(),
|
||||
)
|
||||
h.EventRecorder.ReloadFailed(decision.Workload.GetObject(), resourceType.Kind(), resourceName, err)
|
||||
h.Collectors.RecordReload(false, resourceNamespace)
|
||||
h.Collectors.RecordAction(string(decision.Workload.Kind()), "error", actionLatency)
|
||||
h.Collectors.RecordError("update_workload")
|
||||
continue
|
||||
}
|
||||
|
||||
if updated {
|
||||
h.EventRecorder.ReloadSuccess(decision.Workload.GetObject(), resourceType.Kind(), resourceName)
|
||||
h.Collectors.RecordReload(true, resourceNamespace)
|
||||
log.Info("workload reloaded successfully",
|
||||
h.Collectors.RecordAction(string(decision.Workload.Kind()), "success", actionLatency)
|
||||
log.Info(
|
||||
"workload reloaded successfully",
|
||||
"workload", decision.Workload.GetName(),
|
||||
"kind", decision.Workload.Kind(),
|
||||
)
|
||||
|
||||
if err := h.Alerter.Send(ctx, alerting.AlertMessage{
|
||||
WorkloadKind: string(decision.Workload.Kind()),
|
||||
WorkloadName: decision.Workload.GetName(),
|
||||
WorkloadNamespace: decision.Workload.GetNamespace(),
|
||||
ResourceKind: resourceType.Kind(),
|
||||
ResourceName: resourceName,
|
||||
ResourceNamespace: resourceNamespace,
|
||||
Timestamp: time.Now(),
|
||||
}); err != nil {
|
||||
if err := h.Alerter.Send(
|
||||
ctx, alerting.AlertMessage{
|
||||
WorkloadKind: string(decision.Workload.Kind()),
|
||||
WorkloadName: decision.Workload.GetName(),
|
||||
WorkloadNamespace: decision.Workload.GetNamespace(),
|
||||
ResourceKind: resourceType.Kind(),
|
||||
ResourceName: resourceName,
|
||||
ResourceNamespace: resourceNamespace,
|
||||
Timestamp: time.Now(),
|
||||
},
|
||||
); err != nil {
|
||||
log.Error(err, "failed to send alert")
|
||||
}
|
||||
} else {
|
||||
h.Collectors.RecordAction(string(decision.Workload.Kind()), "no_change", actionLatency)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user