Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP]Migrate client-go/rest to contextual logging #122445

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

WillardHu
Copy link

@WillardHu WillardHu commented Dec 22, 2023

What type of PR is this?

/kind cleanup

What this PR does / why we need it:

Migrate client-go/rest to contextual logging

Which issue(s) this PR fixes:

Fixes [#3077 ](kubernetes/enhancements#3077)

Special notes for your reviewer:

Check result of logcheck:

# echo "Component | Non-Structured Logging | Non-Contextual Logging | Owner " && echo "------ | ------- |  ------- | ------" && for i in $(find staging/src/k8s.io/client-go/rest  -maxdepth 0 -type d | sort); do      echo "$i | $(cd $i; ${GOPATH}/bin/logcheck -check-structured -check-deprecations=false 2>&1 ./... | wc -l ) | $(cd $i; ${GOPATH}/bin/logcheck -check-structured -check-deprecations=false -check-contextual ./... 2>&1 | wc -l ) |" | grep -v '| 0 | 0 |'; done
Component | Non-Structured Logging | Non-Contextual Logging | Owner
------ | ------- |  ------- | ------
staging/src/k8s.io/client-go/rest |        0 |        0 |

Does this PR introduce a user-facing change?

Migrate client-go/rest to contextual logging

Additional documentation e.g., KEPs (Kubernetes Enhancement Proposals), usage docs, etc.:

- [KEP]: https://github.com/kubernetes/enhancements/tree/42bb993e369d166142b7181e90882066ad6c7651/keps/sig-instrumentation/3077-contextual-logging

@k8s-ci-robot k8s-ci-robot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. kind/cleanup Categorizes issue or PR as related to cleaning up code, process, or technical debt. do-not-merge/release-note-label-needed Indicates that a PR should not merge because it's missing one of the release note labels. labels Dec 22, 2023
Copy link

linux-foundation-easycla bot commented Dec 22, 2023

CLA Signed

The committers listed above are authorized under a signed CLA.

  • ✅ login: WillardHu / name: Willard (6834ea7)

@k8s-ci-robot k8s-ci-robot added the sig/api-machinery Categorizes an issue or PR as relevant to SIG API Machinery. label Dec 22, 2023
@k8s-ci-robot k8s-ci-robot added the needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. label Dec 22, 2023
@k8s-ci-robot
Copy link
Contributor

This issue is currently awaiting triage.

If a SIG or subproject determines this is a relevant issue, they will accept it by applying the triage/accepted label and provide further guidance.

The triage/accepted label can be added by org members by writing /triage accepted in a comment.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@k8s-ci-robot
Copy link
Contributor

Welcome @WillardHu!

It looks like this is your first PR to kubernetes/kubernetes 🎉. Please refer to our pull request process documentation to help your PR have a smooth ride to approval.

You will be prompted by a bot to use commands during the review process. Do not be afraid to follow the prompts! It is okay to experiment. Here is the bot commands documentation.

You can also check if kubernetes/kubernetes has its own contribution guidelines.

You may want to refer to our testing guide if you run into trouble with your tests not passing.

If you are having difficulty getting your pull request seen, please follow the recommended escalation practices. Also, for tips and tricks in the contribution process you may want to read the Kubernetes contributor cheat sheet. We want to make sure your contribution gets all the attention it needs!

Thank you, and welcome to Kubernetes. 😃

@k8s-ci-robot k8s-ci-robot added cncf-cla: no Indicates the PR's author has not signed the CNCF CLA. needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. needs-priority Indicates a PR lacks a `priority/foo` label and requires one. labels Dec 22, 2023
@k8s-ci-robot
Copy link
Contributor

Hi @WillardHu. Thanks for your PR.

I'm waiting for a kubernetes member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@k8s-ci-robot k8s-ci-robot added cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. release-note Denotes a PR that will be considered when it comes time to generate release notes. and removed cncf-cla: no Indicates the PR's author has not signed the CNCF CLA. do-not-merge/release-note-label-needed Indicates that a PR should not merge because it's missing one of the release note labels. labels Dec 22, 2023
@WillardHu
Copy link
Author

PTAL, thanks @pohly

@aojea
Copy link
Member

aojea commented Dec 22, 2023

client-go is a library consumed from multiple projects , sounds weird that controller foo with its own context has RESTRequest context, no?

/cc @liggitt

@@ -513,6 +515,9 @@ func InClusterConfig() (*Config, error) {
tokenFile = "/var/run/secrets/kubernetes.io/serviceaccount/token"
rootCAFile = "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
)
// TODO: the context parameter can be added to the method in the future
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The goal is to convert the code now, not later... 🥵

I don't know what the right API should be. That is what we need to find out.

@pohly
Copy link
Contributor

pohly commented Dec 23, 2023

@WillardHu: I don't think this PR is ready for review. It's probably also not a good first issue. Are you sure that you want to continue?

@WillardHu WillardHu changed the title Migrate client-go/rest to contextual logging [WIP]Migrate client-go/rest to contextual logging Dec 23, 2023
@k8s-ci-robot k8s-ci-robot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Dec 23, 2023
@WillardHu
Copy link
Author

@WillardHu: I don't think this PR is ready for review. It's probably also not a good first issue. Are you sure that you want to continue?

Yes, I'll follow up on the changes, and I'll think again about how to define logger instances. We can discuss in the issue first.

@k8s-ci-robot k8s-ci-robot added the sig/storage Categorizes an issue or PR as relevant to SIG Storage. label Dec 27, 2023
@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: WillardHu
Once this PR has been reviewed and has the lgtm label, please assign yliaog for approval. For more information see the Kubernetes Code Review Process.

The full list of commands accepted by this bot can be found here.

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@WillardHu WillardHu force-pushed the client-go-rest-contextual branch 5 times, most recently from 25c8cff to 1bedf91 Compare January 18, 2024 09:52
klog.Errorf("Expected to load root CA config from %s, but got err: %v", rootCAFile, err)
} else {
tlsClientConfig.CAFile = rootCAFile
return nil, err
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a potentially breaking change: previously, the error was ignored, which might have allowed some apps to run. Now they are going to fail.

We need to research why this error was ignored and reach out to maintainers to figure out whether this can be changed.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original logic looks like verifying the validity of the root CA. The function NewPool() returns an error if the file could not be read, a certificate could not be parsed, or if the file does not contain any certificates. Invalid client root certificate access k8s services also return error responses.
I will try to find the author to understand why it was considered to ignore this error.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reverted to the original logic, but I found that error logging here was important to the caller, so I used a new function InClusterConfigWithContext() to support contextual logging.

@@ -335,36 +335,36 @@ func TestHTTPProxy(t *testing.T) {
}

func TestCreateBackoffManager(t *testing.T) {

ctx := context.Background()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In tests, use _, ctx := ktesting.NewTestContext(t) with ktesting = k8s.io/klog/v2/ktesting.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, thanks.

UpdateBackoff(actualUrl *url.URL, err error, responseCode int)
CalculateBackoff(actualUrl *url.URL) time.Duration
UpdateBackoff(ctx context.Context, actualUrl *url.URL, err error, responseCode int)
CalculateBackoff(ctx context.Context, actualUrl *url.URL) time.Duration
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changing the interface is another API break.

We have to keep BackoffManager as it is and add a BackoffManagerContext. Let's keep the method names the same in both, to minimize code changes.

BackoffManager and all functions returning one must get the logcheck remark.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, thanks.

@@ -68,8 +69,8 @@ type HTTPClient interface {
// ResponseWrapper is an interface for getting a response.
// The response may be either accessed as a raw data (the whole output is put into memory) or as a stream.
type ResponseWrapper interface {
DoRaw(context.Context) ([]byte, error)
Stream(context.Context) (io.ReadCloser, error)
DoRaw(...context.Context) ([]byte, error)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's keep the interface as it is (API break!). Passing nil for "no context" seems fine to me.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My idea is use a variable argument list for backward compatibility. In this case, the function DoRaw() can have a context paramete DoRaw(ctx) or no paramete DoRaw(). We can delete the context.Context paramete in the future.
But this is for the user to use, the modification behavior is not controlled. I'll modify it.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, thanks.

Copy link
Contributor

@pohly pohly Jan 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changing an interface can also break code which implements it. This code used to work:

var r rest.Request = &myRequest{}

type myRequest struct {
...
}

func (r *myRequest) DoRaw(context.Context) ([]byte, error) { ... }

With the change to DoRaw(...context.Context) ([]byte, error) it no longer does. Extending an interface has the same problem.

This code also breaks:

var doRaw func(context.Context) ([]byte, error)

doRaw = r.DoRaw

It's not clear whether any of this is actually going to be a problem. But it might, so let's avoid it whenever possible.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have reverted the interface definition. :-)


// gctx defined the global context, it's set by method chaining Context().
// We can get it using the r.ctx() member function, which ensures that returns context is always not nil
gctx context.Context
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The context isn't global? It's specific for the request. I would simply call the field ctx.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, thanks.

return r
}

// ctx returns the global context, if it is not set, we use the default context.Background()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Presumably this is needed because klog.FromContext and logr.FromContext crash when passed a nil context. Probably too late to change that now.

getCtx returning r.ctx?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the function returns the member field r.ctx, but if the member field is nil, the default value context.Background() is returned.

@WillardHu WillardHu force-pushed the client-go-rest-contextual branch 2 times, most recently from 0a8481b to ddb1101 Compare January 25, 2024 02:17
@WillardHu
Copy link
Author

Next I'll regenerate the client code in kubernetes/typed package, and complete the performance comparison.

Signed-off-by: WillardHu <wei.hu@daocloud.io>
@k8s-ci-robot k8s-ci-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Apr 25, 2024
@k8s-ci-robot
Copy link
Contributor

PR needs rebase.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. kind/cleanup Categorizes issue or PR as related to cleaning up code, process, or technical debt. needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. needs-priority Indicates a PR lacks a `priority/foo` label and requires one. needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. release-note Denotes a PR that will be considered when it comes time to generate release notes. sig/api-machinery Categorizes an issue or PR as relevant to SIG API Machinery. sig/storage Categorizes an issue or PR as relevant to SIG Storage. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants