Skip to content

feat: enable structured logging by default with slog adapter#12

Merged
appleboy merged 1 commit intomainfrom
default
Feb 15, 2026
Merged

feat: enable structured logging by default with slog adapter#12
appleboy merged 1 commit intomainfrom
default

Conversation

@appleboy
Copy link
Owner

  • Enable structured logging by default using Go's log/slog, replacing prior no-op logger default
  • Update README, docs, and code to clarify and document default logging behavior and how to disable logging
  • Add slogAdapter implementation to integrate slog.Logger with the logger interface
  • Introduce WithNoLogging option to allow disabling all log output
  • Add and update tests to verify default logger is slogAdapter, and that WithNoLogging disables logging
  • Switch default test requests to use context for better compatibility

- Enable structured logging by default using Go's log/slog, replacing prior no-op logger default
- Update README, docs, and code to clarify and document default logging behavior and how to disable logging
- Add slogAdapter implementation to integrate slog.Logger with the logger interface
- Introduce WithNoLogging option to allow disabling all log output
- Add and update tests to verify default logger is slogAdapter, and that WithNoLogging disables logging
- Switch default test requests to use context for better compatibility

Signed-off-by: appleboy <appleboy.tw@gmail.com>
Copilot AI review requested due to automatic review settings February 15, 2026 03:23
@appleboy appleboy merged commit 8eba476 into main Feb 15, 2026
10 of 12 checks passed
@appleboy appleboy deleted the default branch February 15, 2026 03:25
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request enables structured logging by default using Go's standard library log/slog, changing the default behavior from no logging (no-op) to automatic logging to stderr at INFO level. This is a significant behavioral change that affects all users who don't explicitly configure logging.

Changes:

  • Changed default logger from nopLogger{} to slogAdapter wrapping slog.Default() for automatic stderr logging
  • Added WithNoLogging() option to allow users to disable all logging output
  • Added internal slogAdapter type to implement the Logger interface with slog
  • Updated documentation in README and OBSERVABILITY.md to clarify new default behavior
  • Added tests to verify default logger behavior and WithNoLogging functionality
  • Switched test requests to use context.Background() for better compatibility

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
logger.go Added internal slogAdapter implementation and changed defaultLogger from nopLogger to slogAdapter wrapping slog.Default()
option.go Updated WithLogger documentation to reflect new defaults and added WithNoLogging() function
logger_test.go Added TestClient_DefaultLogger and TestClient_WithNoLogging tests, updated existing test to use context
docs/OBSERVABILITY.md Updated logging documentation to reflect default slog behavior, customization options, and disabling instructions
README.md Updated feature description and quick start to mention default structured logging to stderr

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


client, _ := retry.NewClient(
retry.WithLogger(retry.NewSlogAdapter(logger)),
retry.WithLogger(&slogAdapter{logger: logger}),
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

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

The slogAdapter type is not exported (lowercase 's') and cannot be used by external code. The documentation should reference the existing public SlogAdapter type from logger_slog.go instead, using retry.NewSlogAdapter(logger) which is the correct public API.

Suggested change
retry.WithLogger(&slogAdapter{logger: logger}),
retry.WithLogger(retry.NewSlogAdapter(logger)),

Copilot uses AI. Check for mistakes.
Comment on lines +21 to +43
// slogAdapter wraps slog.Logger to implement our Logger interface
type slogAdapter struct {
logger *slog.Logger
}

func (l *slogAdapter) Debug(msg string, args ...any) {
l.logger.Debug(msg, args...)
}

func (l *slogAdapter) Info(msg string, args ...any) {
l.logger.Info(msg, args...)
}

func (l *slogAdapter) Warn(msg string, args ...any) {
l.logger.Warn(msg, args...)
}

func (l *slogAdapter) Error(msg string, args ...any) {
l.logger.Error(msg, args...)
}

// defaultLogger uses slog.Default() which outputs to stderr with INFO level
var defaultLogger Logger = &slogAdapter{logger: slog.Default()}
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

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

There is now duplication between the internal slogAdapter type and the public SlogAdapter type in logger_slog.go. The implementation is identical. Consider removing the internal slogAdapter and using the public SlogAdapter for both the default logger and user-facing API to avoid code duplication and potential maintenance issues.

Suggested change
// slogAdapter wraps slog.Logger to implement our Logger interface
type slogAdapter struct {
logger *slog.Logger
}
func (l *slogAdapter) Debug(msg string, args ...any) {
l.logger.Debug(msg, args...)
}
func (l *slogAdapter) Info(msg string, args ...any) {
l.logger.Info(msg, args...)
}
func (l *slogAdapter) Warn(msg string, args ...any) {
l.logger.Warn(msg, args...)
}
func (l *slogAdapter) Error(msg string, args ...any) {
l.logger.Error(msg, args...)
}
// defaultLogger uses slog.Default() which outputs to stderr with INFO level
var defaultLogger Logger = &slogAdapter{logger: slog.Default()}
// defaultLogger uses slog.Default() which outputs to stderr with INFO level
var defaultLogger Logger = &SlogAdapter{logger: slog.Default()}

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants