feat(go): implement golang sdk logger#3379
Conversation
|
Thanks for the PR. It is labeled Slash commands (own line, regular comment) move it around the queue:
See CONTRIBUTING.md for details. |
|
I was doing code review but realized that you are still working on it since github tell me to refresh the PR. However, I do found some problem. I'm sorry when I wrote the misleading proposal since it's just a small silly example. I did some small research on it and realized that there is something new about go log system and it would probably help: https://go.dev/blog/slog. I think it can be used directly to replace the |
Thanks for the clarification. I introduced the interface based on the original proposal, but I agree that using |
|
By the way, test is missing. So if you don't mind please provide unit test for this PR. |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #3379 +/- ##
============================================
- Coverage 74.65% 74.64% -0.01%
Complexity 943 943
============================================
Files 1228 1228
Lines 120529 120559 +30
Branches 97263 97263
============================================
+ Hits 89975 89993 +18
- Misses 27614 27631 +17
+ Partials 2940 2935 -5
🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
I think both logger.go and logger_test.go can be removed. But it doesn't mean we don't need test. Actually, I think it would be great if we can test wither the WithLogger works.
NopLogger() can be replaced with slog.New(slog.DiscardHandler) directly, very straight forward and easy to understand.
| logger := opts.logger | ||
| if logger == nil { | ||
| logger = iggcon.NopLogger() | ||
| } |
There was a problem hiding this comment.
This if statement can be removed. We can just move the default value into the GetDefaultOptions() at R46.
| logger := opts.logger | ||
| if logger == nil { | ||
| logger = iggcon.NopLogger() | ||
| } |
There was a problem hiding this comment.
same here, move it to GetDefaultOptions(). We set NopLogger() in default options, and let the
for _, opt := range options {
opt(&opts)
}to overwrite it.
| // NopLogger returns a logger that silently discards all output. | ||
| func NopLogger() *slog.Logger { | ||
| return slog.New(slog.DiscardHandler) | ||
| } |
There was a problem hiding this comment.
Maybe we can delete logger.go and logger_test.go. If we use *slog.Logger, we can just inline slog.New(slog.DiscardHandler) for default logger. And for user who want to see the logs, they can do
client.NewIggyClient(client.WithLogger(slog.New(slog.NewTextHandler(
os.Stdout,
&slog.HandlerOptions{
Level: slog.LevelDebug,
}))))So the NewLogger won't be actually used.
The NopLogger makes sense, but I think it's also fine to just inline
slog.New(slog.DiscardHandler)So we can remove both of them, and the corresponding tests.
| func CheckAndRedirectToLeader(ctx context.Context, c iggcon.Client, currentAddress string, transport iggcon.Protocol, logger *slog.Logger) (string, error) { | ||
| if logger == nil { | ||
| logger = iggcon.NopLogger() | ||
| } |
There was a problem hiding this comment.
Regarding here, if you change the GetDefaultOptions(), it should be safe to remove the nil check.
|
|
||
| return &IggyTcpClient{ | ||
| config: opts.config, | ||
| logger: logger, |
There was a problem hiding this comment.
| logger: logger, | |
| logger: opts.logger, |
Makes sense. If we remove |
Yeah, great choice, under the |
|
I removed the custom logger helpers and moved the default logger into |
chengxilo
left a comment
There was a problem hiding this comment.
Just a few changes needed. Mainly the nil guard
| func TestGetDefaultOptions_ProvidesLogger(t *testing.T) { | ||
| opts := GetDefaultOptions() | ||
| if opts.logger == nil { | ||
| t.Fatal("expected default options to include a non-nil logger") | ||
| } | ||
| } |
There was a problem hiding this comment.
| func TestGetDefaultOptions_ProvidesLogger(t *testing.T) { | |
| opts := GetDefaultOptions() | |
| if opts.logger == nil { | |
| t.Fatal("expected default options to include a non-nil logger") | |
| } | |
| } |
unnecessary
| ic, ok := cli.(*IggyClient) | ||
| if !ok { | ||
| t.Fatal("expected *IggyClient from NewIggyClient") | ||
| } |
There was a problem hiding this comment.
| ic, ok := cli.(*IggyClient) | |
| if !ok { | |
| t.Fatal("expected *IggyClient from NewIggyClient") | |
| } | |
| ic := cli.(*IggyClient) |
it will always be a IggyClient so the check is not needed.
60897bd to
0ed2244
Compare
|
I've added the nil guard for |
|
/ready |
|
Just minor typo issue. lgtm now. We still need to add the logs in the tcp client to align with rust sdk. But it can be done in another PR (Or if you prefer, we can do it here too). We can open an issue when this is done. |
Co-authored-by: Chengxi Luo <chengxi.luo2004@gmail.com>
Thanks. I missed that typo too. |
Which issue does this PR address?
Closes #3364
Rationale
The SDK currently logs to stdout using
log.Printfand users have no way to controlit. They can't turn it off, change the log level, or redirect it. This PR adds a
configurable logger so users can decide whether to enable logging, what level of
detail they want, and where the logs should go.
What changed?
The SDK was printing log messages directly to stdout with no user control.
This PR adds a Logger interface that users can pass to the client via
WithLogger().By default, logging is silent (zero overhead). When enabled, users can choose their
log level (Debug, Info, Warn, Error) and output destination (stderr, file, custom).
All internal
log.Printfcalls have been replaced with logger method calls.Local Execution
Passed
go vet ./...- no issuesgofmt- all files formatted correctlygolangci-lint- no errors or warningsgo build ./...- builds successfullygo test ./contracts ./client/tcp ./internal/util- all tests passAI Usage
Tool: Claude Sonnet 4.6
Scope: Generated the logger interface, DefaultLogger and NoopLogger implementations. All generated code was reviewed, integrated and tested manually.
Verification: All code compiles and tests pass locally.