Skip to content

Commit

Permalink
Update applier stats and status for destroy (#259)
Browse files Browse the repository at this point in the history
- Move stats to a sub-package and clean up the interface a bit
- Fix a bug in applier status that was double-counting zeroth enums

Change-Id: I10d93b1bd057f409e4d9726bfc7ce156ea633bf9
  • Loading branch information
karlkfi committed Nov 3, 2022
1 parent 3a38243 commit 8d9c21b
Show file tree
Hide file tree
Showing 7 changed files with 374 additions and 266 deletions.
29 changes: 15 additions & 14 deletions pkg/applier/kpt_applier.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"k8s.io/klog/v2"
"kpt.dev/configsync/pkg/api/configmanagement"
"kpt.dev/configsync/pkg/api/configsync"
"kpt.dev/configsync/pkg/applier/stats"
"kpt.dev/configsync/pkg/core"
"kpt.dev/configsync/pkg/declared"
"kpt.dev/configsync/pkg/kinds"
Expand Down Expand Up @@ -180,10 +181,10 @@ func wrapInventoryObj(obj *unstructured.Unstructured) (*live.InventoryResourceGr
return inv, nil
}

func processApplyEvent(ctx context.Context, e event.ApplyEvent, stats *applyEventStats, objectStatusMap ObjectStatusMap, unknownTypeResources map[core.ID]struct{}) status.Error {
func processApplyEvent(ctx context.Context, e event.ApplyEvent, s *stats.ApplyEventStats, objectStatusMap ObjectStatusMap, unknownTypeResources map[core.ID]struct{}) status.Error {
id := idFrom(e.Identifier)
klog.V(4).Infof("apply %v for object: %v", e.Status, id)
stats.EventByOp[e.Status]++
s.Add(e.Status)

objectStatus, ok := objectStatusMap[id]
if !ok || objectStatus == nil {
Expand Down Expand Up @@ -222,13 +223,13 @@ func processApplyEvent(ctx context.Context, e event.ApplyEvent, stats *applyEven
}
}

func processWaitEvent(e event.WaitEvent, waitStats *waitEventStats, objectStatusMap ObjectStatusMap) error {
func processWaitEvent(e event.WaitEvent, s *stats.WaitEventStats, objectStatusMap ObjectStatusMap) error {
id := idFrom(e.Identifier)
if e.Status != event.ReconcilePending {
// Don't log pending. It's noisy and only fires in certain conditions.
klog.V(4).Infof("Reconcile %v: %v", e.Status, id)
}
waitStats.EventByOp[e.Status]++
s.Add(e.Status)

objectStatus, ok := objectStatusMap[id]
if !ok || objectStatus == nil {
Expand Down Expand Up @@ -277,10 +278,10 @@ func handleApplySkippedEvent(obj *unstructured.Unstructured, id core.ID, err err
return SkipErrorForResource(err, id, actuation.ActuationStrategyApply)
}

func processPruneEvent(ctx context.Context, e event.PruneEvent, stats *pruneEventStats, objectStatusMap ObjectStatusMap, cs *clientSet) status.Error {
func processPruneEvent(ctx context.Context, e event.PruneEvent, s *stats.PruneEventStats, objectStatusMap ObjectStatusMap, cs *clientSet) status.Error {
id := idFrom(e.Identifier)
klog.V(4).Infof("prune %v for object: %v", e.Status, id)
stats.EventByOp[e.Status]++
s.Add(e.Status)

objectStatus, ok := objectStatusMap[id]
if !ok || objectStatus == nil {
Expand Down Expand Up @@ -401,7 +402,7 @@ func (a *Applier) sync(ctx context.Context, objs []client.Object) (map[schema.Gr
}
a.checkInventoryObjectSize(ctx, cs.client)

stats := newApplyStats()
s := stats.NewSyncStats()
objStatusMap := make(ObjectStatusMap)
// disabledObjs are objects for which the management are disabled
// through annotation.
Expand All @@ -413,7 +414,7 @@ func (a *Applier) sync(ctx context.Context, objs []client.Object) (map[schema.Gr
a.errs = status.Append(a.errs, err)
return nil, a.errs
}
stats.DisableObjs = DisabledObjStats{
s.DisableObjs = &stats.DisabledObjStats{
Total: uint64(len(disabledObjs)),
Succeeded: disabledCount,
}
Expand Down Expand Up @@ -465,7 +466,7 @@ func (a *Applier) sync(ctx context.Context, objs []client.Object) (map[schema.Gr
} else {
a.errs = status.Append(a.errs, Error(e.ErrorEvent.Err))
}
stats.ErrorTypeEvents++
s.ErrorTypeEvents++
case event.WaitType:
// Log WaitEvent at the verbose level of 4 due to the number of WaitEvent.
// For every object which is skipped to apply/prune, there will be one ReconcileSkipped WaitEvent.
Expand All @@ -474,7 +475,7 @@ func (a *Applier) sync(ctx context.Context, objs []client.Object) (map[schema.Gr
// a reconciled object may become pending before a wait task times out.
// Record the objs that have been reconciled.
klog.V(4).Info(e.WaitEvent)
a.errs = status.Append(a.errs, processWaitEvent(e.WaitEvent, &stats.WaitEvent, objStatusMap))
a.errs = status.Append(a.errs, processWaitEvent(e.WaitEvent, s.WaitEvent, objStatusMap))
case event.ApplyType:
logEvent := event.ApplyEvent{
GroupName: e.ApplyEvent.GroupName,
Expand All @@ -484,7 +485,7 @@ func (a *Applier) sync(ctx context.Context, objs []client.Object) (map[schema.Gr
Error: e.ApplyEvent.Error,
}
klog.V(4).Info(logEvent)
a.errs = status.Append(a.errs, processApplyEvent(ctx, e.ApplyEvent, &stats.ApplyEvent, objStatusMap, unknownTypeResources))
a.errs = status.Append(a.errs, processApplyEvent(ctx, e.ApplyEvent, s.ApplyEvent, objStatusMap, unknownTypeResources))
case event.PruneType:
logEvent := event.PruneEvent{
GroupName: e.PruneEvent.GroupName,
Expand All @@ -494,7 +495,7 @@ func (a *Applier) sync(ctx context.Context, objs []client.Object) (map[schema.Gr
Error: e.PruneEvent.Error,
}
klog.V(4).Info(logEvent)
a.errs = status.Append(a.errs, processPruneEvent(ctx, e.PruneEvent, &stats.PruneEvent, objStatusMap, cs))
a.errs = status.Append(a.errs, processPruneEvent(ctx, e.PruneEvent, s.PruneEvent, objStatusMap, cs))
default:
klog.V(4).Infof("skipped %v event", e.Type)
}
Expand All @@ -512,10 +513,10 @@ func (a *Applier) sync(ctx context.Context, objs []client.Object) (map[schema.Gr
klog.V(4).Infof("all resources are up to date.")
}

if stats.empty() {
if s.Empty() {
klog.V(4).Infof("The applier made no new progress")
} else {
klog.Infof("The applier made new progress: %s.", stats.string())
klog.Infof("The applier made new progress: %s", s.String())
objStatusMap.Log(klog.V(0))
}
return gvks, a.errs
Expand Down
43 changes: 22 additions & 21 deletions pkg/applier/kpt_applier_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/cli-runtime/pkg/genericclioptions"
"kpt.dev/configsync/pkg/applier/stats"
"kpt.dev/configsync/pkg/core"
"kpt.dev/configsync/pkg/kinds"
"kpt.dev/configsync/pkg/status"
Expand Down Expand Up @@ -418,21 +419,21 @@ func TestProcessApplyEvent(t *testing.T) {
testID := object.UnstructuredToObjMetadata(newTestObj())

ctx := context.Background()
status := newApplyStats()
s := stats.NewSyncStats()
objStatusMap := make(ObjectStatusMap)
unknownTypeResources := make(map[core.ID]struct{})

err := processApplyEvent(ctx, formApplyEvent(event.ApplyFailed, &deploymentID, fmt.Errorf("test error")).ApplyEvent, &status.ApplyEvent, objStatusMap, unknownTypeResources)
err := processApplyEvent(ctx, formApplyEvent(event.ApplyFailed, &deploymentID, fmt.Errorf("test error")).ApplyEvent, s.ApplyEvent, objStatusMap, unknownTypeResources)
expectedError := ErrorForResource(fmt.Errorf("test error"), idFrom(deploymentID))
testutil.AssertEqual(t, expectedError, err, "expected processPruneEvent to error on apply %s", event.ApplyFailed)

err = processApplyEvent(ctx, formApplyEvent(event.ApplySuccessful, &testID, nil).ApplyEvent, &status.ApplyEvent, objStatusMap, unknownTypeResources)
err = processApplyEvent(ctx, formApplyEvent(event.ApplySuccessful, &testID, nil).ApplyEvent, s.ApplyEvent, objStatusMap, unknownTypeResources)
assert.Nil(t, err, "expected processApplyEvent NOT to error on apply %s", event.ApplySuccessful)

expectedApplyStatus := newApplyStats()
expectedApplyStatus.ApplyEvent.EventByOp[event.ApplyFailed] = 1
expectedApplyStatus.ApplyEvent.EventByOp[event.ApplySuccessful] = 1
testutil.AssertEqual(t, expectedApplyStatus, status, "expected event stats to match")
expectedApplyStatus := stats.NewSyncStats()
expectedApplyStatus.ApplyEvent.Add(event.ApplyFailed)
expectedApplyStatus.ApplyEvent.Add(event.ApplySuccessful)
testutil.AssertEqual(t, expectedApplyStatus, s, "expected event stats to match")

expectedObjStatusMap := ObjectStatusMap{
idFrom(deploymentID): {
Expand All @@ -456,21 +457,21 @@ func TestProcessPruneEvent(t *testing.T) {
testID := object.UnstructuredToObjMetadata(newTestObj())

ctx := context.Background()
status := newApplyStats()
s := stats.NewSyncStats()
objStatusMap := make(ObjectStatusMap)
cs := &clientSet{}

err := processPruneEvent(ctx, formPruneEvent(event.PruneFailed, &deploymentID, fmt.Errorf("test error")).PruneEvent, &status.PruneEvent, objStatusMap, cs)
err := processPruneEvent(ctx, formPruneEvent(event.PruneFailed, &deploymentID, fmt.Errorf("test error")).PruneEvent, s.PruneEvent, objStatusMap, cs)
expectedError := ErrorForResource(fmt.Errorf("test error"), idFrom(deploymentID))
testutil.AssertEqual(t, expectedError, err, "expected processPruneEvent to error on prune %s", event.PruneFailed)

err = processPruneEvent(ctx, formPruneEvent(event.PruneSuccessful, &testID, nil).PruneEvent, &status.PruneEvent, objStatusMap, cs)
err = processPruneEvent(ctx, formPruneEvent(event.PruneSuccessful, &testID, nil).PruneEvent, s.PruneEvent, objStatusMap, cs)
assert.Nil(t, err, "expected processPruneEvent NOT to error on prune %s", event.PruneSuccessful)

expectedApplyStatus := newApplyStats()
expectedApplyStatus.PruneEvent.EventByOp[event.PruneFailed] = 1
expectedApplyStatus.PruneEvent.EventByOp[event.PruneSuccessful] = 1
testutil.AssertEqual(t, expectedApplyStatus, status, "expected event stats to match")
expectedApplyStatus := stats.NewSyncStats()
expectedApplyStatus.PruneEvent.Add(event.PruneFailed)
expectedApplyStatus.PruneEvent.Add(event.PruneSuccessful)
testutil.AssertEqual(t, expectedApplyStatus, s, "expected event stats to match")

expectedObjStatusMap := ObjectStatusMap{
idFrom(deploymentID): {
Expand All @@ -494,19 +495,19 @@ func TestProcessWaitEvent(t *testing.T) {
deploymentID := object.UnstructuredToObjMetadata(newDeploymentObj())
testID := object.UnstructuredToObjMetadata(newTestObj())

status := newApplyStats()
s := stats.NewSyncStats()
objStatusMap := make(ObjectStatusMap)

err := processWaitEvent(formWaitEvent(event.ReconcileFailed, &deploymentID).WaitEvent, &status.WaitEvent, objStatusMap)
err := processWaitEvent(formWaitEvent(event.ReconcileFailed, &deploymentID).WaitEvent, s.WaitEvent, objStatusMap)
assert.Nil(t, err, "expected processWaitEvent NOT to error on reconcile %s", event.ReconcileFailed)

err = processWaitEvent(formWaitEvent(event.ReconcileSuccessful, &testID).WaitEvent, &status.WaitEvent, objStatusMap)
err = processWaitEvent(formWaitEvent(event.ReconcileSuccessful, &testID).WaitEvent, s.WaitEvent, objStatusMap)
assert.Nil(t, err, "expected processWaitEvent NOT to error on reconcile %s", event.ReconcileSuccessful)

expectedApplyStatus := newApplyStats()
expectedApplyStatus.WaitEvent.EventByOp[event.ReconcileFailed] = 1
expectedApplyStatus.WaitEvent.EventByOp[event.ReconcileSuccessful] = 1
testutil.AssertEqual(t, expectedApplyStatus, status, "expected event stats to match")
expectedApplyStatus := stats.NewSyncStats()
expectedApplyStatus.WaitEvent.Add(event.ReconcileFailed)
expectedApplyStatus.WaitEvent.Add(event.ReconcileSuccessful)
testutil.AssertEqual(t, expectedApplyStatus, s, "expected event stats to match")

expectedObjStatusMap := ObjectStatusMap{
idFrom(deploymentID): {
Expand Down
185 changes: 0 additions & 185 deletions pkg/applier/stats.go

This file was deleted.

Loading

0 comments on commit 8d9c21b

Please sign in to comment.