-
Notifications
You must be signed in to change notification settings - Fork 350
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
chore: improve logging with additional test coverage #1937
Conversation
internal/proxy/proxy.go
Outdated
} | ||
} | ||
return nil, fmt.Errorf("[%v] Unable to mount socket: %v", inst.Name, err) | ||
fmt.Errorf("[%v] Unable to mount socket: %v", inst.Name, err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to either log this error, or return it. Right now, this is creating an error value and discarding it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If there is only one instance, should we still fail the proxy?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replaced it with logger.Errorf(). Thanks!
Considering the scenario where this one instance was accidentally stopped, having the proxy run will save a minor effort of restarting proxy after the instance is activated. It's not a huge saving, but the behaviour could be consistent.
internal/proxy/proxy_test.go
Outdated
@@ -306,6 +309,39 @@ func TestClientInitialization(t *testing.T) { | |||
filepath.Join(testUnixSocketPathPg), | |||
}, | |||
}, | |||
{ | |||
desc: "without TCP port or unix socket for non functional instance", | |||
in: &proxy.Config{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test below is build around wantTCPAddrs or wantUnixAddrs. So as written, this test will never fail. To ensure we have the behavior we want here, we should add a functioning socket with a non functioning one and ensure we get what we expect with wantTCPAddrs or wantUnixAddrs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fake dialer's EngineVersion() added a fakeserver case to mimic the failed instance case. EngineVersion() call will fail in the NewClient() call. What the test does is to make sure that NewClient() will proceed upon the failure of EngineVersion().
internal/proxy/proxy_test.go
Outdated
}, | ||
}, | ||
}, | ||
wantUnixAddrs: []string{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should the fake instance result in a Unix socket?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the case of the auto-reconnecting the instance, it might be good to keep the socket?
6b2cd86
to
fd02e36
Compare
A couple of high level thoughts:
WDYT? |
cff7808
to
db06ac9
Compare
Makes sense. Updated the PR that fails the unix path if the instance is not active. |
internal/proxy/proxy.go
Outdated
@@ -747,6 +747,14 @@ type socketMount struct { | |||
dialOpts []cloudsqlconn.DialOption | |||
} | |||
|
|||
func getNetworkType(conf *Config, inst InstanceConnConfig) string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's make this networkType
. Cf. https://go.dev/doc/effective_go#Getters
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed. Thanks!
internal/proxy/proxy.go
Outdated
} | ||
|
||
l.Infof("[%s] Listening on %s", inst.Name, m.Addr()) | ||
mnts = append(mnts, m) | ||
} | ||
c.mnts = mnts | ||
return c, nil | ||
if len(mnts) > 0 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's swap this with the error below, so the error path is indented.
https://github.com/golang/go/wiki/CodeReviewComments#indent-error-flow
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed. Thanks!
internal/proxy/proxy_test.go
Outdated
}, | ||
} | ||
|
||
unixTcs := []struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shall we move this one test case into a dedicated test below? e.g., TestProxyInitializationWithFailedUnixSocket?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea to make the test more explicit! Fixed
internal/proxy/proxy.go
Outdated
@@ -801,6 +807,8 @@ func (c *Client) newSocketMount(ctx context.Context, conf *Config, pc *portConfi | |||
|
|||
address, err = newUnixSocketMount(inst, conf.UnixSocket, strings.HasPrefix(version, "POSTGRES")) | |||
if err != nil { | |||
c.logger.Errorf("could not mount unix socket %q for %q: %v", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's consolidate all logging up above in NewClient.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see that we're not doing that consistently above. We should confirm that we're not logging this error twice, though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As discussed offline, removed the NewClient logs and kept logs at the newSocketMount level.
722c84a
to
30238d6
Compare
Replaced fmt.Errorf with logger.Errorf for instance failure Fail the inactive instance with unix path Fixed lint error Added inactive instance test with unix path Replace getNetworkType with networkType Fixed the error path indentation Make the unix path failure test a seperate func Fail the proxy binary if the tcp socket argument is wrong
30238d6
to
a77165f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Key point: let's add support here for skipped over failed Unix sockets. Otherwise, we should require users specify a port for TCP sockets to avoid adding any additional complexity here.
internal/proxy/proxy.go
Outdated
switch err.(type) { | ||
// this is not the inactive instance case. Fail the proxy | ||
// so that the user could fix the proxy command error. | ||
case *net.OpError: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In what cases does this error get returned? Could we add a comment clarifying that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this isn't Unix related, I think we shouldn't add it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added the comments. This is to handle the case where listen call could fail.
internal/proxy/proxy.go
Outdated
@@ -801,6 +807,8 @@ func (c *Client) newSocketMount(ctx context.Context, conf *Config, pc *portConfi | |||
|
|||
address, err = newUnixSocketMount(inst, conf.UnixSocket, strings.HasPrefix(version, "POSTGRES")) | |||
if err != nil { | |||
c.logger.Errorf("could not mount unix socket %q for %q: %v", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see that we're not doing that consistently above. We should confirm that we're not logging this error twice, though.
for _, tc := range tcs { | ||
t.Run(tc.desc, func(t *testing.T) { | ||
_, err := proxy.NewClient(ctx, &fakeDialer{}, testLogger, tc.in) | ||
if tc.wantSuccess != (err == nil) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could this be:
if tc.wantSuccess && err != nil {
// ...
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the proposed change, if tc.wantSuccess is false (we want NewClient() to fail), the branch will not be executed regardless what the err is. This will miss reporting the failing case when err is nil and we want NewClient() to fail.
internal/proxy/proxy.go
Outdated
mErr := m.Close() | ||
if mErr != nil { | ||
l.Errorf("failed to close mount: %v", mErr) | ||
switch err.(type) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of switching on error type, could we just continue if the socket type is a Unix socket (like what we had before)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will miss the case when the type is TCP socket and there is no active instance. Correct me if I'm wrong, my understanding from the discussion offline:
- Inactive instance with unix socket should fail
- Inactive instance with TCP socket with no port number configured should fail.
As discussed offline, keep the logic to fail the proxy if the proxy is unable to connect to inactive instances. Retain the logging to keep it consistent. |
Let proxy continue to run even instances specified are inactive.
Tested these scenarios: