diff --git a/pkg/apiserver/rest/dualwriter_mode1.go b/pkg/apiserver/rest/dualwriter_mode1.go index 933ad8ff0ed..f09f589a56d 100644 --- a/pkg/apiserver/rest/dualwriter_mode1.go +++ b/pkg/apiserver/rest/dualwriter_mode1.go @@ -37,17 +37,18 @@ func (d *DualWriterMode1) Mode() DualWriterMode { // Create overrides the behavior of the generic DualWriter and writes only to LegacyStorage. func (d *DualWriterMode1) Create(ctx context.Context, original runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) { var method = "create" - log := d.Log.WithValues("kind", options.Kind, "method", method) + var kind = original.GetObjectKind().GroupVersionKind().Kind + log := d.Log.WithValues("method", method, "kind", kind) ctx = klog.NewContext(ctx, log) startLegacy := time.Now() created, err := d.Legacy.Create(ctx, original, createValidation, options) if err != nil { log.Error(err, "unable to create object in legacy storage") - d.recordLegacyDuration(true, mode1Str, options.Kind, method, startLegacy) + d.recordLegacyDuration(true, mode1Str, kind, method, startLegacy) return created, err } - d.recordLegacyDuration(false, mode1Str, options.Kind, method, startLegacy) + d.recordLegacyDuration(false, mode1Str, kind, method, startLegacy) createdCopy := created.DeepCopyObject() @@ -61,7 +62,7 @@ func (d *DualWriterMode1) Create(ctx context.Context, original runtime.Object, c startStorage := time.Now() storageObj, errObjectSt := d.Storage.Create(ctx, createdCopy, createValidation, options) - d.recordStorageDuration(errObjectSt != nil, mode1Str, options.Kind, method, startStorage) + d.recordStorageDuration(errObjectSt != nil, mode1Str, kind, method, startStorage) if err != nil { cancel() } @@ -78,7 +79,7 @@ func (d *DualWriterMode1) Create(ctx context.Context, original runtime.Object, c // Get overrides the behavior of the generic DualWriter and reads only from LegacyStorage. func (d *DualWriterMode1) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) { var method = "get" - log := d.Log.WithValues("kind", options.Kind, "method", method, "name", name) + log := d.Log.WithValues("method", method, "name", name) ctx = klog.NewContext(ctx, log) startLegacy := time.Now() @@ -86,14 +87,19 @@ func (d *DualWriterMode1) Get(ctx context.Context, name string, options *metav1. if errLegacy != nil { log.Error(errLegacy, "unable to get object in legacy storage") } - d.recordLegacyDuration(errLegacy != nil, mode1Str, options.Kind, method, startLegacy) + var kind string + if res != nil { + kind = res.GetObjectKind().GroupVersionKind().Kind + } + + d.recordLegacyDuration(errLegacy != nil, mode1Str, kind, method, startLegacy) go func(res runtime.Object) { startStorage := time.Now() ctx, cancel := context.WithTimeoutCause(ctx, time.Second*10, errors.New("storage get timeout")) defer cancel() storageObj, err := d.Storage.Get(ctx, name, options) - d.recordStorageDuration(err != nil, mode1Str, options.Kind, method, startStorage) + d.recordStorageDuration(err != nil, mode1Str, kind, method, startStorage) if err != nil { log.Error(err, "unable to get object in storage") cancel() @@ -112,7 +118,7 @@ func (d *DualWriterMode1) Get(ctx context.Context, name string, options *metav1. // List overrides the behavior of the generic DualWriter and reads only from LegacyStorage. func (d *DualWriterMode1) List(ctx context.Context, options *metainternalversion.ListOptions) (runtime.Object, error) { var method = "list" - log := d.Log.WithValues("kind", options.Kind, "resourceVersion", options.ResourceVersion, "kind", options.Kind, "method", method) + log := d.Log.WithValues("resourceVersion", options.ResourceVersion, "method", method) ctx = klog.NewContext(ctx, log) startLegacy := time.Now() @@ -120,14 +126,18 @@ func (d *DualWriterMode1) List(ctx context.Context, options *metainternalversion if errLegacy != nil { log.Error(errLegacy, "unable to list object in legacy storage") } - d.recordLegacyDuration(errLegacy != nil, mode1Str, options.Kind, method, startLegacy) + var kind string + if res != nil { + kind = res.GetObjectKind().GroupVersionKind().Kind + } + d.recordLegacyDuration(errLegacy != nil, mode1Str, kind, method, startLegacy) go func(res runtime.Object) { startStorage := time.Now() ctx, cancel := context.WithTimeoutCause(ctx, time.Second*10, errors.New("storage list timeout")) defer cancel() storageObj, err := d.Storage.List(ctx, options) - d.recordStorageDuration(err != nil, mode1Str, options.Kind, method, startStorage) + d.recordStorageDuration(err != nil, mode1Str, kind, method, startStorage) if err != nil { cancel() } @@ -143,14 +153,18 @@ func (d *DualWriterMode1) List(ctx context.Context, options *metainternalversion func (d *DualWriterMode1) Delete(ctx context.Context, name string, deleteValidation rest.ValidateObjectFunc, options *metav1.DeleteOptions) (runtime.Object, bool, error) { var method = "delete" - log := d.Log.WithValues("name", name, "kind", options.Kind, "method", method, "name", name) + log := d.Log.WithValues("name", name, "method", method, "name", name) ctx = klog.NewContext(ctx, d.Log) startLegacy := time.Now() res, async, err := d.Legacy.Delete(ctx, name, deleteValidation, options) + var kind string + if res != nil { + kind = res.GetObjectKind().GroupVersionKind().Kind + } if err != nil { log.Error(err, "unable to delete object in legacy storage") - d.recordLegacyDuration(true, mode1Str, options.Kind, method, startLegacy) + d.recordLegacyDuration(true, mode1Str, kind, method, startLegacy) return res, async, err } d.recordLegacyDuration(false, mode1Str, name, method, startLegacy) @@ -160,7 +174,7 @@ func (d *DualWriterMode1) Delete(ctx context.Context, name string, deleteValidat ctx, cancel := context.WithTimeoutCause(ctx, time.Second*10, errors.New("storage delete timeout")) defer cancel() storageObj, _, err := d.Storage.Delete(ctx, name, deleteValidation, options) - d.recordStorageDuration(err != nil, mode1Str, options.Kind, method, startStorage) + d.recordStorageDuration(err != nil, mode1Str, kind, method, startStorage) if err != nil { cancel() } @@ -177,24 +191,28 @@ func (d *DualWriterMode1) Delete(ctx context.Context, name string, deleteValidat // DeleteCollection overrides the behavior of the generic DualWriter and deletes only from LegacyStorage. func (d *DualWriterMode1) DeleteCollection(ctx context.Context, deleteValidation rest.ValidateObjectFunc, options *metav1.DeleteOptions, listOptions *metainternalversion.ListOptions) (runtime.Object, error) { var method = "delete-collection" - log := d.Log.WithValues("kind", options.Kind, "resourceVersion", listOptions.ResourceVersion, "method", method) + log := d.Log.WithValues("resourceVersion", listOptions.ResourceVersion, "method", method) ctx = klog.NewContext(ctx, log) + var kind string startLegacy := time.Now() res, err := d.Legacy.DeleteCollection(ctx, deleteValidation, options, listOptions) + if res != nil { + kind = res.GetObjectKind().GroupVersionKind().Kind + } if err != nil { log.Error(err, "unable to delete collection in legacy storage") - d.recordLegacyDuration(true, mode1Str, options.Kind, method, startLegacy) + d.recordLegacyDuration(true, mode1Str, kind, method, startLegacy) return res, err } - d.recordLegacyDuration(false, mode1Str, options.Kind, method, startLegacy) + d.recordLegacyDuration(false, mode1Str, kind, method, startLegacy) go func(res runtime.Object) { startStorage := time.Now() ctx, cancel := context.WithTimeoutCause(ctx, time.Second*10, errors.New("storage deletecollection timeout")) defer cancel() storageObj, err := d.Storage.DeleteCollection(ctx, deleteValidation, options, listOptions) - d.recordStorageDuration(err != nil, mode1Str, options.Kind, method, startStorage) + d.recordStorageDuration(err != nil, mode1Str, kind, method, startStorage) if err != nil { cancel() } @@ -210,17 +228,21 @@ func (d *DualWriterMode1) DeleteCollection(ctx context.Context, deleteValidation func (d *DualWriterMode1) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { var method = "update" - log := d.Log.WithValues("name", name, "kind", options.Kind, "method", method, "name", name) + log := d.Log.WithValues("name", name, "method", method, "name", name) ctx = klog.NewContext(ctx, log) + var kind string startLegacy := time.Now() res, async, err := d.Legacy.Update(ctx, name, objInfo, createValidation, updateValidation, forceAllowCreate, options) + if res != nil { + kind = res.GetObjectKind().GroupVersionKind().Kind + } if err != nil { log.Error(err, "unable to update in legacy storage") - d.recordLegacyDuration(true, mode1Str, options.Kind, method, startLegacy) + d.recordLegacyDuration(true, mode1Str, kind, method, startLegacy) return res, async, err } - d.recordLegacyDuration(false, mode1Str, options.Kind, method, startLegacy) + d.recordLegacyDuration(false, mode1Str, kind, method, startLegacy) go func(res runtime.Object) { ctx, cancel := context.WithTimeoutCause(ctx, time.Second*10, errors.New("storage update timeout")) @@ -256,7 +278,7 @@ func (d *DualWriterMode1) Update(ctx context.Context, name string, objInfo rest. startStorage := time.Now() defer cancel() storageObj, _, errObjectSt := d.Storage.Update(ctx, name, objInfo, createValidation, updateValidation, forceAllowCreate, options) - d.recordStorageDuration(errObjectSt != nil, mode1Str, options.Kind, method, startStorage) + d.recordStorageDuration(errObjectSt != nil, mode1Str, kind, method, startStorage) if err != nil { cancel() } diff --git a/pkg/apiserver/rest/dualwriter_mode2.go b/pkg/apiserver/rest/dualwriter_mode2.go index 95b4a93218b..55768a80943 100644 --- a/pkg/apiserver/rest/dualwriter_mode2.go +++ b/pkg/apiserver/rest/dualwriter_mode2.go @@ -40,17 +40,18 @@ func (d *DualWriterMode2) Mode() DualWriterMode { // Create overrides the behavior of the generic DualWriter and writes to LegacyStorage and Storage. func (d *DualWriterMode2) Create(ctx context.Context, original runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) { var method = "create" - log := d.Log.WithValues("kind", options.Kind, "method", method) + var kind = original.GetObjectKind().GroupVersionKind().Kind + log := d.Log.WithValues("method", method, "kind", kind) ctx = klog.NewContext(ctx, log) startLegacy := time.Now() created, err := d.Legacy.Create(ctx, original, createValidation, options) if err != nil { log.Error(err, "unable to create object in legacy storage") - d.recordLegacyDuration(true, mode2Str, options.Kind, method, startLegacy) + d.recordLegacyDuration(true, mode2Str, kind, method, startLegacy) return created, err } - d.recordLegacyDuration(false, mode2Str, options.Kind, method, startLegacy) + d.recordLegacyDuration(false, mode2Str, kind, method, startLegacy) if err := enrichLegacyObject(original, created); err != nil { return created, err @@ -60,10 +61,10 @@ func (d *DualWriterMode2) Create(ctx context.Context, original runtime.Object, c rsp, err := d.Storage.Create(ctx, created, createValidation, options) if err != nil { log.WithValues("name").Error(err, "unable to create object in storage") - d.recordStorageDuration(true, mode2Str, options.Kind, method, startStorage) + d.recordStorageDuration(true, mode2Str, kind, method, startStorage) return rsp, err } - d.recordStorageDuration(false, mode2Str, options.Kind, method, startStorage) + d.recordStorageDuration(false, mode2Str, kind, method, startStorage) areEqual := Compare(rsp, created) d.recordOutcome(mode2Str, getName(rsp), areEqual, method) @@ -76,12 +77,17 @@ func (d *DualWriterMode2) Create(ctx context.Context, original runtime.Object, c // It retrieves an object from Storage if possible, and if not it falls back to LegacyStorage. func (d *DualWriterMode2) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) { var method = "get" - log := d.Log.WithValues("name", name, "resourceVersion", options.ResourceVersion, "kind", options.Kind, "method", method) + log := d.Log.WithValues("name", name, "resourceVersion", options.ResourceVersion, "method", method) ctx = klog.NewContext(ctx, log) startStorage := time.Now() objStorage, err := d.Storage.Get(ctx, name, options) - d.recordStorageDuration(err != nil, mode2Str, options.Kind, method, startStorage) + var kind string + if objStorage != nil { + kind = objStorage.GetObjectKind().GroupVersionKind().Kind + } + + d.recordStorageDuration(err != nil, mode2Str, kind, method, startStorage) if err != nil { // if it errors because it's not found, we try to fetch it from the legacy storage if !apierrors.IsNotFound(err) { @@ -95,10 +101,10 @@ func (d *DualWriterMode2) Get(ctx context.Context, name string, options *metav1. objLegacy, err := d.Legacy.Get(ctx, name, options) if err != nil { log.Error(err, "unable to fetch object from legacy") - d.recordLegacyDuration(true, mode2Str, options.Kind, method, startLegacy) + d.recordLegacyDuration(true, mode2Str, kind, method, startLegacy) return objLegacy, err } - d.recordLegacyDuration(false, mode2Str, options.Kind, method, startLegacy) + d.recordLegacyDuration(false, mode2Str, kind, method, startLegacy) areEqual := Compare(objStorage, objLegacy) d.recordOutcome(mode2Str, name, areEqual, method) @@ -117,17 +123,21 @@ func (d *DualWriterMode2) Get(ctx context.Context, name string, options *metav1. // It returns Storage entries if possible and falls back to LegacyStorage entries if not. func (d *DualWriterMode2) List(ctx context.Context, options *metainternalversion.ListOptions) (runtime.Object, error) { var method = "list" - log := d.Log.WithValues("kind", options.Kind, "resourceVersion", options.ResourceVersion, "kind", options.Kind, "method", method) + log := d.Log.WithValues("resourceVersion", options.ResourceVersion, "method", method) ctx = klog.NewContext(ctx, log) startLegacy := time.Now() ll, err := d.Legacy.List(ctx, options) + var kind string + if ll != nil { + kind = ll.GetObjectKind().GroupVersionKind().Kind + } if err != nil { log.Error(err, "unable to list objects from legacy storage") - d.recordLegacyDuration(true, mode2Str, options.Kind, method, startLegacy) + d.recordLegacyDuration(true, mode2Str, kind, method, startLegacy) return ll, err } - d.recordLegacyDuration(false, mode2Str, options.Kind, method, startLegacy) + d.recordLegacyDuration(false, mode2Str, kind, method, startLegacy) legacyList, err := meta.ExtractList(ll) if err != nil { @@ -150,10 +160,10 @@ func (d *DualWriterMode2) List(ctx context.Context, options *metainternalversion sl, err := d.Storage.List(ctx, &optionsStorage) if err != nil { log.Error(err, "unable to list objects from storage") - d.recordStorageDuration(true, mode2Str, options.Kind, method, startStorage) + d.recordStorageDuration(true, mode2Str, kind, method, startStorage) return sl, err } - d.recordStorageDuration(false, mode2Str, options.Kind, method, startStorage) + d.recordStorageDuration(false, mode2Str, kind, method, startStorage) storageList, err := meta.ExtractList(sl) if err != nil { @@ -192,17 +202,21 @@ func (d *DualWriterMode2) List(ctx context.Context, options *metainternalversion // DeleteCollection overrides the behavior of the generic DualWriter and deletes from both LegacyStorage and Storage. func (d *DualWriterMode2) DeleteCollection(ctx context.Context, deleteValidation rest.ValidateObjectFunc, options *metav1.DeleteOptions, listOptions *metainternalversion.ListOptions) (runtime.Object, error) { var method = "delete-collection" - log := d.Log.WithValues("kind", options.Kind, "resourceVersion", listOptions.ResourceVersion, "method", method) + log := d.Log.WithValues("resourceVersion", listOptions.ResourceVersion, "method", method) ctx = klog.NewContext(ctx, log) + var kind string startLegacy := time.Now() deleted, err := d.Legacy.DeleteCollection(ctx, deleteValidation, options, listOptions) + if deleted != nil { + kind = deleted.GetObjectKind().GroupVersionKind().Kind + } if err != nil { log.WithValues("deleted", deleted).Error(err, "failed to delete collection successfully from legacy storage") - d.recordLegacyDuration(true, mode2Str, options.Kind, method, startLegacy) + d.recordLegacyDuration(true, mode2Str, kind, method, startLegacy) return deleted, err } - d.recordLegacyDuration(false, mode2Str, options.Kind, method, startLegacy) + d.recordLegacyDuration(false, mode2Str, kind, method, startLegacy) legacyList, err := meta.ExtractList(deleted) if err != nil { @@ -223,10 +237,10 @@ func (d *DualWriterMode2) DeleteCollection(ctx context.Context, deleteValidation res, err := d.Storage.DeleteCollection(ctx, deleteValidation, options, &optionsStorage) if err != nil { log.WithValues("deleted", res).Error(err, "failed to delete collection successfully from Storage") - d.recordStorageDuration(true, mode2Str, options.Kind, method, startStorage) + d.recordStorageDuration(true, mode2Str, kind, method, startStorage) return res, err } - d.recordStorageDuration(false, mode2Str, options.Kind, method, startStorage) + d.recordStorageDuration(false, mode2Str, kind, method, startStorage) areEqual := Compare(res, deleted) d.recordOutcome(mode2Str, getName(res), areEqual, method) @@ -239,30 +253,35 @@ func (d *DualWriterMode2) DeleteCollection(ctx context.Context, deleteValidation func (d *DualWriterMode2) Delete(ctx context.Context, name string, deleteValidation rest.ValidateObjectFunc, options *metav1.DeleteOptions) (runtime.Object, bool, error) { var method = "delete" - log := d.Log.WithValues("name", name, "kind", options.Kind, "method", method) + log := d.Log.WithValues("name", name, "method", method) ctx = klog.NewContext(ctx, log) + var kind string startLegacy := time.Now() deletedLS, async, err := d.Legacy.Delete(ctx, name, deleteValidation, options) + + if deletedLS != nil { + kind = deletedLS.GetObjectKind().GroupVersionKind().Kind + } if err != nil { if !apierrors.IsNotFound(err) { log.WithValues("objectList", deletedLS).Error(err, "could not delete from legacy store") - d.recordLegacyDuration(true, mode2Str, options.Kind, method, startLegacy) + d.recordLegacyDuration(true, mode2Str, kind, method, startLegacy) return deletedLS, async, err } } - d.recordLegacyDuration(false, mode2Str, options.Kind, method, startLegacy) + d.recordLegacyDuration(false, mode2Str, kind, method, startLegacy) startStorage := time.Now() deletedS, _, err := d.Storage.Delete(ctx, name, deleteValidation, options) if err != nil { if !apierrors.IsNotFound(err) { log.WithValues("objectList", deletedS).Error(err, "could not delete from duplicate storage") - d.recordStorageDuration(true, mode2Str, options.Kind, method, startStorage) + d.recordStorageDuration(true, mode2Str, kind, method, startStorage) } return deletedS, async, err } - d.recordStorageDuration(false, mode2Str, options.Kind, method, startStorage) + d.recordStorageDuration(false, mode2Str, kind, method, startStorage) areEqual := Compare(deletedS, deletedLS) d.recordOutcome(mode2Str, name, areEqual, method) @@ -276,11 +295,15 @@ func (d *DualWriterMode2) Delete(ctx context.Context, name string, deleteValidat // Update overrides the generic behavior of the Storage and writes first to the legacy storage and then to storage. func (d *DualWriterMode2) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { var method = "update" - log := d.Log.WithValues("name", name, "kind", options.Kind, "method", method) + log := d.Log.WithValues("name", name, "method", method) ctx = klog.NewContext(ctx, log) + var kind string // get foundObj and (updated) object so they can be stored in legacy store foundObj, err := d.Storage.Get(ctx, name, &metav1.GetOptions{}) + if foundObj != nil { + kind = foundObj.GetObjectKind().GroupVersionKind().Kind + } if err != nil { if !apierrors.IsNotFound(err) { log.WithValues("object", foundObj).Error(err, "could not get object to update") @@ -291,6 +314,9 @@ func (d *DualWriterMode2) Update(ctx context.Context, name string, objInfo rest. // obj can be populated in case it's found or empty in case it's not found updated, err := objInfo.UpdatedObject(ctx, foundObj) + if updated != nil { + kind = updated.GetObjectKind().GroupVersionKind().Kind + } if err != nil { log.WithValues("object", updated).Error(err, "could not update or create object") return nil, false, err @@ -300,10 +326,10 @@ func (d *DualWriterMode2) Update(ctx context.Context, name string, objInfo rest. obj, created, err := d.Legacy.Update(ctx, name, &updateWrapper{upstream: objInfo, updated: updated}, createValidation, updateValidation, forceAllowCreate, options) if err != nil { log.WithValues("object", obj).Error(err, "could not update in legacy storage") - d.recordLegacyDuration(true, mode2Str, options.Kind, "update", startLegacy) + d.recordLegacyDuration(true, mode2Str, kind, "update", startLegacy) return obj, created, err } - d.recordLegacyDuration(false, mode2Str, options.Kind, "update", startLegacy) + d.recordLegacyDuration(false, mode2Str, kind, "update", startLegacy) // if the object is found, create a new updateWrapper with the object found if foundObj != nil { @@ -322,7 +348,7 @@ func (d *DualWriterMode2) Update(ctx context.Context, name string, objInfo rest. res, created, err := d.Storage.Update(ctx, name, objInfo, createValidation, updateValidation, forceAllowCreate, options) if err != nil { log.WithValues("object", res).Error(err, "could not update in storage") - d.recordStorageDuration(true, mode2Str, options.Kind, "update", startStorage) + d.recordStorageDuration(true, mode2Str, kind, "update", startStorage) return res, created, err } diff --git a/pkg/apiserver/rest/dualwriter_mode3.go b/pkg/apiserver/rest/dualwriter_mode3.go index 00c6aa4ef05..17e9560b0c3 100644 --- a/pkg/apiserver/rest/dualwriter_mode3.go +++ b/pkg/apiserver/rest/dualwriter_mode3.go @@ -35,17 +35,18 @@ const mode3Str = "3" // Create overrides the behavior of the generic DualWriter and writes to LegacyStorage and Storage. func (d *DualWriterMode3) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) { var method = "create" - log := d.Log.WithValues("kind", options.Kind, "method", method) + var kind = obj.GetObjectKind().GroupVersionKind().Kind + log := d.Log.WithValues("kind", kind, "method", method) ctx = klog.NewContext(ctx, log) startStorage := time.Now() created, err := d.Storage.Create(ctx, obj, createValidation, options) if err != nil { log.Error(err, "unable to create object in storage") - d.recordLegacyDuration(true, mode3Str, options.Kind, method, startStorage) + d.recordLegacyDuration(true, mode3Str, kind, method, startStorage) return created, err } - d.recordStorageDuration(false, mode3Str, options.Kind, method, startStorage) + d.recordStorageDuration(false, mode3Str, kind, method, startStorage) go func() { ctx, cancel := context.WithTimeoutCause(ctx, time.Second*10, errors.New("legacy create timeout")) @@ -53,7 +54,7 @@ func (d *DualWriterMode3) Create(ctx context.Context, obj runtime.Object, create startLegacy := time.Now() _, errObjectSt := d.Legacy.Create(ctx, obj, createValidation, options) - d.recordLegacyDuration(errObjectSt != nil, mode3Str, options.Kind, method, startLegacy) + d.recordLegacyDuration(errObjectSt != nil, mode3Str, kind, method, startLegacy) }() return created, err @@ -62,7 +63,7 @@ func (d *DualWriterMode3) Create(ctx context.Context, obj runtime.Object, create // Get overrides the behavior of the generic DualWriter and retrieves an object from Storage. func (d *DualWriterMode3) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) { var method = "get" - log := d.Log.WithValues("kind", options.Kind, "name", name, "method", method) + log := d.Log.WithValues("name", name, "method", method) ctx = klog.NewContext(ctx, log) startStorage := time.Now() @@ -70,7 +71,12 @@ func (d *DualWriterMode3) Get(ctx context.Context, name string, options *metav1. if err != nil { log.Error(err, "unable to get object in storage") } - d.recordStorageDuration(err != nil, mode3Str, options.Kind, method, startStorage) + + var kind string + if res != nil { + kind = res.GetObjectKind().GroupVersionKind().Kind + } + d.recordStorageDuration(err != nil, mode3Str, kind, method, startStorage) return res, err } @@ -78,7 +84,7 @@ func (d *DualWriterMode3) Get(ctx context.Context, name string, options *metav1. // List overrides the behavior of the generic DualWriter and reads only from Unified Store. func (d *DualWriterMode3) List(ctx context.Context, options *metainternalversion.ListOptions) (runtime.Object, error) { var method = "list" - log := d.Log.WithValues("kind", options.Kind, "resourceVersion", options.ResourceVersion, "method", method) + log := d.Log.WithValues("resourceVersion", options.ResourceVersion, "method", method) ctx = klog.NewContext(ctx, log) startStorage := time.Now() @@ -86,21 +92,29 @@ func (d *DualWriterMode3) List(ctx context.Context, options *metainternalversion if err != nil { log.Error(err, "unable to list object in storage") } - d.recordStorageDuration(err != nil, mode3Str, options.Kind, method, startStorage) + var kind string + if res != nil { + kind = res.GetObjectKind().GroupVersionKind().Kind + } + d.recordStorageDuration(err != nil, mode3Str, kind, method, startStorage) return res, err } func (d *DualWriterMode3) Delete(ctx context.Context, name string, deleteValidation rest.ValidateObjectFunc, options *metav1.DeleteOptions) (runtime.Object, bool, error) { var method = "delete" - log := d.Log.WithValues("name", name, "kind", options.Kind, "method", method) + log := d.Log.WithValues("name", name, "method", method) ctx = klog.NewContext(ctx, d.Log) + var kind string startStorage := time.Now() res, async, err := d.Storage.Delete(ctx, name, deleteValidation, options) + if res != nil { + kind = res.GetObjectKind().GroupVersionKind().Kind + } if err != nil { log.Error(err, "unable to delete object in storage") - d.recordStorageDuration(true, mode3Str, options.Kind, method, startStorage) + d.recordStorageDuration(true, mode3Str, kind, method, startStorage) return res, async, err } d.recordStorageDuration(false, mode3Str, name, method, startStorage) @@ -110,7 +124,7 @@ func (d *DualWriterMode3) Delete(ctx context.Context, name string, deleteValidat ctx, cancel := context.WithTimeoutCause(ctx, time.Second*10, errors.New("legacy delete timeout")) defer cancel() _, _, err := d.Legacy.Delete(ctx, name, deleteValidation, options) - d.recordLegacyDuration(err != nil, mode3Str, options.Kind, method, startLegacy) + d.recordLegacyDuration(err != nil, mode3Str, kind, method, startLegacy) }() return res, async, err @@ -119,17 +133,21 @@ func (d *DualWriterMode3) Delete(ctx context.Context, name string, deleteValidat // Update overrides the behavior of the generic DualWriter and writes first to Storage and then to LegacyStorage. func (d *DualWriterMode3) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { var method = "update" - log := d.Log.WithValues("name", name, "kind", options.Kind, "method", method) + log := d.Log.WithValues("name", name, "method", method) ctx = klog.NewContext(ctx, log) + var kind string startStorage := time.Now() res, async, err := d.Storage.Update(ctx, name, objInfo, createValidation, updateValidation, forceAllowCreate, options) + if res != nil { + kind = res.GetObjectKind().GroupVersionKind().Kind + } if err != nil { log.Error(err, "unable to update in storage") - d.recordLegacyDuration(true, mode3Str, options.Kind, method, startStorage) + d.recordLegacyDuration(true, mode3Str, kind, method, startStorage) return res, async, err } - d.recordStorageDuration(false, mode3Str, options.Kind, method, startStorage) + d.recordStorageDuration(false, mode3Str, kind, method, startStorage) go func() { ctx, cancel := context.WithTimeoutCause(ctx, time.Second*10, errors.New("legacy update timeout")) @@ -137,7 +155,7 @@ func (d *DualWriterMode3) Update(ctx context.Context, name string, objInfo rest. startLegacy := time.Now() defer cancel() _, _, errObjectSt := d.Legacy.Update(ctx, name, objInfo, createValidation, updateValidation, forceAllowCreate, options) - d.recordLegacyDuration(errObjectSt != nil, mode3Str, options.Kind, method, startLegacy) + d.recordLegacyDuration(errObjectSt != nil, mode3Str, kind, method, startLegacy) }() return res, async, err @@ -146,24 +164,28 @@ func (d *DualWriterMode3) Update(ctx context.Context, name string, objInfo rest. // DeleteCollection overrides the behavior of the generic DualWriter and deletes from both LegacyStorage and Storage. func (d *DualWriterMode3) DeleteCollection(ctx context.Context, deleteValidation rest.ValidateObjectFunc, options *metav1.DeleteOptions, listOptions *metainternalversion.ListOptions) (runtime.Object, error) { var method = "delete-collection" - log := d.Log.WithValues("kind", options.Kind, "resourceVersion", listOptions.ResourceVersion, "method", method) + log := d.Log.WithValues("resourceVersion", listOptions.ResourceVersion, "method", method) ctx = klog.NewContext(ctx, log) + var kind string startStorage := time.Now() res, err := d.Storage.DeleteCollection(ctx, deleteValidation, options, listOptions) + if res != nil { + kind = res.GetObjectKind().GroupVersionKind().Kind + } if err != nil { log.Error(err, "unable to delete collection in storage") - d.recordStorageDuration(true, mode3Str, options.Kind, method, startStorage) + d.recordStorageDuration(true, mode3Str, kind, method, startStorage) return res, err } - d.recordStorageDuration(false, mode3Str, options.Kind, method, startStorage) + d.recordStorageDuration(false, mode3Str, kind, method, startStorage) go func() { startLegacy := time.Now() ctx, cancel := context.WithTimeoutCause(ctx, time.Second*10, errors.New("legacy deletecollection timeout")) defer cancel() _, err := d.Legacy.DeleteCollection(ctx, deleteValidation, options, listOptions) - d.recordStorageDuration(err != nil, mode3Str, options.Kind, method, startLegacy) + d.recordStorageDuration(err != nil, mode3Str, kind, method, startLegacy) }() return res, err diff --git a/pkg/apiserver/rest/dualwriter_mode4.go b/pkg/apiserver/rest/dualwriter_mode4.go index ae3a96da3c7..94df3cea591 100644 --- a/pkg/apiserver/rest/dualwriter_mode4.go +++ b/pkg/apiserver/rest/dualwriter_mode4.go @@ -2,6 +2,7 @@ package rest import ( "context" + "time" metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -35,77 +36,116 @@ func (d *DualWriterMode4) Mode() DualWriterMode { // Create overrides the behavior of the generic DualWriter and writes only to Storage. func (d *DualWriterMode4) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) { var method = "create" - log := d.Log.WithValues("kind", options.Kind, "method", method) + var kind = obj.GetObjectKind().GroupVersionKind().Kind + log := d.Log.WithValues("method", method, "kind", kind) ctx = klog.NewContext(ctx, log) + + startStorage := time.Now() res, err := d.Storage.Create(ctx, obj, createValidation, options) if err != nil { log.Error(err, "unable to create object in storage") } + d.recordStorageDuration(err != nil, mode4Str, kind, method, startStorage) return res, err } // Get overrides the behavior of the generic DualWriter and retrieves an object from Storage. func (d *DualWriterMode4) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) { var method = "get" - log := d.Log.WithValues("kind", options.Kind, "method", method) + log := d.Log.WithValues("method", method) ctx = klog.NewContext(ctx, log) + + startStorage := time.Now() res, err := d.Storage.Get(ctx, name, options) if err != nil { log.Error(err, "unable to create object in storage") } + var kind string + if res != nil { + kind = res.GetObjectKind().GroupVersionKind().Kind + } + d.recordStorageDuration(err != nil, mode4Str, kind, method, startStorage) return res, err } func (d *DualWriterMode4) Delete(ctx context.Context, name string, deleteValidation rest.ValidateObjectFunc, options *metav1.DeleteOptions) (runtime.Object, bool, error) { var method = "delete" - log := d.Log.WithValues("name", name, "kind", options.Kind, "method", method) + log := d.Log.WithValues("name", name, "method", method) ctx = klog.NewContext(ctx, log) + + var kind string + startStorage := time.Now() res, async, err := d.Storage.Delete(ctx, name, deleteValidation, options) if err != nil { log.Error(err, "unable to delete object in storage") } + if res != nil { + kind = res.GetObjectKind().GroupVersionKind().Kind + } + d.recordStorageDuration(err != nil, mode4Str, kind, method, startStorage) return res, async, err } // DeleteCollection overrides the behavior of the generic DualWriter and deletes only from Storage. func (d *DualWriterMode4) DeleteCollection(ctx context.Context, deleteValidation rest.ValidateObjectFunc, options *metav1.DeleteOptions, listOptions *metainternalversion.ListOptions) (runtime.Object, error) { var method = "delete-collection" - log := d.Log.WithValues("kind", options.Kind, "resourceVersion", listOptions.ResourceVersion, "method", method, "mode", mode4Str) + log := d.Log.WithValues("resourceVersion", listOptions.ResourceVersion, "method", method, "mode", mode4Str) ctx = klog.NewContext(ctx, log) + var kind string + + startStorage := time.Now() res, err := d.Storage.DeleteCollection(ctx, deleteValidation, options, listOptions) if err != nil { log.Error(err, "unable to delete collection in storage") } + if res != nil { + kind = res.GetObjectKind().GroupVersionKind().Kind + } + d.recordStorageDuration(err != nil, mode4Str, kind, method, startStorage) return res, err } // Update overrides the generic behavior of the Storage and writes only to US. func (d *DualWriterMode4) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { var method = "update" - log := d.Log.WithValues("name", name, "kind", options.Kind, "method", method) + log := d.Log.WithValues("name", name, "method", method) ctx = klog.NewContext(ctx, log) + var kind string + + startStorage := time.Now() res, async, err := d.Storage.Update(ctx, name, objInfo, createValidation, updateValidation, forceAllowCreate, options) if err != nil { log.Error(err, "unable to update object in storage") } + if res != nil { + kind = res.GetObjectKind().GroupVersionKind().Kind + } + d.recordStorageDuration(err != nil, mode4Str, kind, method, startStorage) return res, async, err } func (d *DualWriterMode4) List(ctx context.Context, options *metainternalversion.ListOptions) (runtime.Object, error) { var method = "list" - log := d.Log.WithValues("kind", options.Kind, "resourceVersion", options.ResourceVersion, "kind", options.Kind, "method", method) + log := d.Log.WithValues("resourceVersion", options.ResourceVersion, "method", method) ctx = klog.NewContext(ctx, log) + + startStorage := time.Now() res, err := d.Storage.List(ctx, options) if err != nil { log.Error(err, "unable to list objects in storage") } + var kind string + if res != nil { + kind = res.GetObjectKind().GroupVersionKind().Kind + } + d.recordStorageDuration(err != nil, mode4Str, kind, method, startStorage) return res, err } //TODO: uncomment when storage watch is implemented // func (d *DualWriterMode4) Watch(ctx context.Context, options *metainternalversion.ListOptions) (watch.Interface, error) { // var method = "watch" -// d.Log.WithValues("kind", options.Kind, "method", method, "mode", mode4Str).Info("starting to watch") +// d.Log.WithValues("kind", kind, "method", method, "mode", mode4Str).Info("starting to watch") // return d.Storage.Watch(ctx, options) // } diff --git a/pkg/apiserver/rest/metrics.go b/pkg/apiserver/rest/metrics.go index 674e54d0635..1457ffb8e16 100644 --- a/pkg/apiserver/rest/metrics.go +++ b/pkg/apiserver/rest/metrics.go @@ -51,14 +51,14 @@ func (m *dualWriterMetrics) init(reg prometheus.Registerer) { } } -func (m *dualWriterMetrics) recordLegacyDuration(isError bool, mode string, name string, method string, startFrom time.Time) { +func (m *dualWriterMetrics) recordLegacyDuration(isError bool, mode string, kind string, method string, startFrom time.Time) { duration := time.Since(startFrom).Seconds() - m.legacy.WithLabelValues(strconv.FormatBool(isError), mode, name, method).Observe(duration) + m.legacy.WithLabelValues(strconv.FormatBool(isError), mode, kind, method).Observe(duration) } -func (m *dualWriterMetrics) recordStorageDuration(isError bool, mode string, name string, method string, startFrom time.Time) { +func (m *dualWriterMetrics) recordStorageDuration(isError bool, mode string, kind string, method string, startFrom time.Time) { duration := time.Since(startFrom).Seconds() - m.storage.WithLabelValues(strconv.FormatBool(isError), mode, name, method).Observe(duration) + m.storage.WithLabelValues(strconv.FormatBool(isError), mode, kind, method).Observe(duration) } func (m *dualWriterMetrics) recordOutcome(mode string, name string, areEqual bool, method string) {