feat(observability): add maintenance policy metrics
Prometheus: runs, duration, rows_deleted, config_changes; инкремент при CRUD и Execute. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
@@ -7,6 +7,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"evobgp/internal/observability"
|
||||
"evobgp/internal/pgmonitor"
|
||||
"evobgp/internal/store"
|
||||
|
||||
@@ -22,19 +23,29 @@ type PolicyExecutor struct {
|
||||
|
||||
// Execute runs cleanup and/or vacuum steps for a policy.
|
||||
func (e *PolicyExecutor) Execute(ctx context.Context, policy *store.MaintenancePolicy, dryRun bool) (map[string]any, error) {
|
||||
if e == nil || e.Pool == nil {
|
||||
return nil, fmt.Errorf("maintenance: postgres not configured")
|
||||
}
|
||||
start := time.Now()
|
||||
if policy == nil {
|
||||
return nil, store.ErrInvalidInput
|
||||
}
|
||||
action := policyAction(policy)
|
||||
record := func(status string, detail map[string]any) {
|
||||
observability.RecordMaintenancePolicyRun(policy.ID, action, status, dryRun, time.Since(start), rowsDeletedFromDetail(detail))
|
||||
}
|
||||
|
||||
if e == nil || e.Pool == nil {
|
||||
record("failed", nil)
|
||||
return nil, fmt.Errorf("maintenance: postgres not configured")
|
||||
}
|
||||
if err := ValidateTableName(policy.TableName); err != nil {
|
||||
record("failed", nil)
|
||||
return nil, err
|
||||
}
|
||||
if err := ValidateCondition(policy.Condition); err != nil {
|
||||
record("failed", nil)
|
||||
return nil, err
|
||||
}
|
||||
if !store.ValidVacuumStrategy(policy.VacuumStrategy) {
|
||||
record("failed", nil)
|
||||
return nil, store.ErrInvalidInput
|
||||
}
|
||||
|
||||
@@ -50,6 +61,7 @@ func (e *PolicyExecutor) Execute(ctx context.Context, policy *store.MaintenanceP
|
||||
detail[k] = v
|
||||
}
|
||||
if err != nil {
|
||||
record("failed", detail)
|
||||
return detail, err
|
||||
}
|
||||
}
|
||||
@@ -61,6 +73,7 @@ func (e *PolicyExecutor) Execute(ctx context.Context, policy *store.MaintenanceP
|
||||
detail["vacuum"] = vacDetail
|
||||
}
|
||||
if err != nil {
|
||||
record("failed", detail)
|
||||
return detail, err
|
||||
}
|
||||
}
|
||||
@@ -68,10 +81,42 @@ func (e *PolicyExecutor) Execute(ctx context.Context, policy *store.MaintenanceP
|
||||
if !dryRun && e.Store != nil {
|
||||
_ = e.Store.TouchMaintenancePolicyRun(policy.ID, "succeeded", "")
|
||||
}
|
||||
|
||||
record("succeeded", detail)
|
||||
return detail, nil
|
||||
}
|
||||
|
||||
func policyAction(p *store.MaintenancePolicy) string {
|
||||
if p == nil {
|
||||
return "run"
|
||||
}
|
||||
if p.RetentionPeriodSec != nil || p.MaxRows != nil {
|
||||
if p.VacuumStrategy != store.VacuumStrategyNone {
|
||||
return "cleanup_vacuum"
|
||||
}
|
||||
return "cleanup"
|
||||
}
|
||||
if p.VacuumStrategy != store.VacuumStrategyNone {
|
||||
return p.VacuumStrategy
|
||||
}
|
||||
return "run"
|
||||
}
|
||||
|
||||
func rowsDeletedFromDetail(detail map[string]any) int64 {
|
||||
if detail == nil {
|
||||
return 0
|
||||
}
|
||||
switch v := detail["deleted"].(type) {
|
||||
case int64:
|
||||
return v
|
||||
case int:
|
||||
return int64(v)
|
||||
case float64:
|
||||
return int64(v)
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func (e *PolicyExecutor) runCleanup(ctx context.Context, policy *store.MaintenancePolicy, dryRun bool) (map[string]any, error) {
|
||||
detail := map[string]any{"cleanup": true}
|
||||
limit := NormalizeBatchLimit(policy.MaxRows)
|
||||
|
||||
Reference in New Issue
Block a user