1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-05 07:26:55 +00:00

refactor: engine execution stats (#6792)

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
This commit is contained in:
Charles-Edouard Brétéché 2023-04-05 14:27:18 +02:00 committed by GitHub
parent a710cccb7a
commit ab8639b643
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 40 additions and 25 deletions

View file

@ -3,7 +3,6 @@ package apply
import (
"encoding/json"
"testing"
"time"
kyverno "github.com/kyverno/kyverno/api/kyverno/v1"
preport "github.com/kyverno/kyverno/api/policyreport/v1alpha2"
@ -93,12 +92,12 @@ func Test_buildPolicyReports(t *testing.T) {
er := engineapi.EngineResponse{}
er.Policy = &policy
er.PolicyResponse.Add(time.Now(), time.Now(), *engineapi.RuleFail(
er.PolicyResponse.Add(engineapi.ExecutionStats{}, *engineapi.RuleFail(
"pods-require-account",
engineapi.Validation,
"validation error: User pods must include an account for charging. Rule pods-require-account failed at path /metadata/labels/"),
)
er.PolicyResponse.Add(time.Now(), time.Now(), *engineapi.RulePass(
er.PolicyResponse.Add(engineapi.ExecutionStats{}, *engineapi.RulePass(
"pods-require-limits",
engineapi.Validation,
"validation rule 'pods-require-limits' passed."),
@ -138,12 +137,12 @@ func Test_buildPolicyResults(t *testing.T) {
er := engineapi.EngineResponse{}
er.Policy = &policy
er.PolicyResponse.Add(time.Now(), time.Now(), *engineapi.RuleFail(
er.PolicyResponse.Add(engineapi.ExecutionStats{}, *engineapi.RuleFail(
"pods-require-account",
engineapi.Validation,
"validation error: User pods must include an account for charging. Rule pods-require-account failed at path /metadata/labels/"),
)
er.PolicyResponse.Add(time.Now(), time.Now(), *engineapi.RulePass(
er.PolicyResponse.Add(engineapi.ExecutionStats{}, *engineapi.RulePass(
"pods-require-limits",
engineapi.Validation,
"validation rule 'pods-require-limits' passed."),

View file

@ -1,7 +1,5 @@
package api
import "time"
// PolicyResponse policy application response
type PolicyResponse struct {
// Stats contains policy statistics
@ -10,8 +8,8 @@ type PolicyResponse struct {
Rules []RuleResponse
}
func (pr *PolicyResponse) Add(startTime, endTime time.Time, response RuleResponse) {
pr.Rules = append(pr.Rules, response.WithStats(startTime, endTime))
func (pr *PolicyResponse) Add(stats ExecutionStats, response RuleResponse) {
pr.Rules = append(pr.Rules, response.WithStats(stats))
status := response.Status()
if status == RuleStatusPass || status == RuleStatusFail {
pr.Stats.RulesAppliedCount++

View file

@ -2,7 +2,6 @@ package api
import (
"fmt"
"time"
kyvernov2alpha1 "github.com/kyverno/kyverno/api/kyverno/v2alpha1"
pssutils "github.com/kyverno/kyverno/pkg/pss/utils"
@ -108,9 +107,9 @@ func (r RuleResponse) WithPatches(patches ...[]byte) *RuleResponse {
return &r
}
func (r RuleResponse) WithStats(startTime, endTime time.Time) RuleResponse {
r.stats = NewExecutionStats(startTime)
r.stats.Done(endTime)
func (r RuleResponse) WithStats(stats ExecutionStats) RuleResponse {
r.stats = stats
return r
}

View file

@ -7,19 +7,38 @@ import (
// ExecutionStats stores the statistics for the single policy/rule application
type ExecutionStats struct {
// ProcessingTime is the time required to apply the policy/rule on the resource
ProcessingTime time.Duration
// Timestamp of the instant the policy/rule got triggered
Timestamp int64
processingTime time.Duration
// timestamp of the instant the policy/rule got triggered
timestamp time.Time
}
func NewExecutionStats(timestamp time.Time) ExecutionStats {
return ExecutionStats{
Timestamp: timestamp.Unix(),
timestamp: timestamp,
}
}
func NewExecutionStatsFull(startTime, endTime time.Time) ExecutionStats {
return ExecutionStats{
timestamp: startTime,
processingTime: endTime.Sub(startTime),
}
}
func (s ExecutionStats) Time() time.Time {
return s.timestamp
}
func (s ExecutionStats) Timestamp() int64 {
return s.timestamp.Unix()
}
func (s ExecutionStats) ProcessingTime() time.Duration {
return s.processingTime
}
func (s *ExecutionStats) Done(timestamp time.Time) {
s.ProcessingTime = timestamp.Sub(time.Unix(s.Timestamp, 0))
s.processingTime = timestamp.Sub(s.timestamp)
}
// PolicyStats stores statistics for the single policy application

View file

@ -53,9 +53,9 @@ func (e *engine) verifyAndPatchImages(
engineapi.ImageVerify,
)
matchedResource = resource
endTime := time.Now()
stats := engineapi.NewExecutionStatsFull(startTime, time.Now())
for _, ruleResp := range ruleResp {
resp.Add(startTime, endTime, ruleResp)
resp.Add(stats, ruleResp)
}
if applyRules == kyvernov1.ApplyOne && resp.Stats.RulesAppliedCount > 0 {
break

View file

@ -88,7 +88,7 @@ func (e *engine) reportMetrics(
attribute.String("rule_type", string(ruleType)),
attribute.String("rule_execution_cause", string(executionCause)),
}
e.durationHistogram.Record(ctx, rule.Stats().ProcessingTime.Seconds(), commonLabels...)
e.durationHistogram.Record(ctx, rule.Stats().ProcessingTime().Seconds(), commonLabels...)
}
}
}

View file

@ -50,9 +50,9 @@ func (e *engine) mutate(
engineapi.Mutation,
)
matchedResource = resource
endTime := time.Now()
stats := engineapi.NewExecutionStatsFull(startTime, time.Now())
for _, ruleResp := range ruleResp {
resp.Add(startTime, endTime, ruleResp)
resp.Add(stats, ruleResp)
}
if applyRules == kyvernov1.ApplyOne && resp.Stats.RulesAppliedCount > 0 {
break

View file

@ -68,9 +68,9 @@ func (e *engine) validate(
engineapi.Validation,
)
matchedResource = resource
endTime := time.Now()
stats := engineapi.NewExecutionStatsFull(startTime, time.Now())
for _, ruleResp := range ruleResp {
resp.Add(startTime, endTime, ruleResp)
resp.Add(stats, ruleResp)
}
if applyRules == kyvernov1.ApplyOne && resp.Stats.RulesAppliedCount > 0 {
break