diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index db9944bb..6efdb8f4 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -12,7 +12,7 @@ jobs: strategy: matrix: run-on: [ 'ubuntu', 'macOS', 'windows' ] - go-version: [ 'oldstable', 'stable' ] + go-version: [ 'stable' ] name: Test runs-on: ${{ matrix.run-on }}-latest steps: diff --git a/CHANGELOG.md b/CHANGELOG.md index 6feb987b..1f78e177 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Removed + +- Remove konf.Logger in favor of slog (#48). + ## [v0.2.0] - 3/18/2023 ### Removed diff --git a/config.go b/config.go index f2a4afa9..cbe6aeba 100644 --- a/config.go +++ b/config.go @@ -7,6 +7,7 @@ import ( "context" "errors" "fmt" + "log/slog" "strings" "sync" @@ -18,7 +19,6 @@ import ( // Config is a registry which holds configuration loaded by Loader(s). type Config struct { delimiter string - logger Logger values map[string]any providers []*provider @@ -45,7 +45,7 @@ func New(opts ...Option) (*Config, error) { return nil, fmt.Errorf("[konf] load configuration: %w", err) } maps.Merge(config.values, values) - config.logger.Info( + slog.Info( "Configuration has been loaded.", "loader", loader, ) @@ -170,7 +170,7 @@ func (c *Config) Watch(ctx context.Context, fns ...func(*Config)) error { //noli ctx, func(values map[string]any) { provider.values = values - c.logger.Info( + slog.Info( "Configuration has been changed.", "watcher", provider.watcher, ) diff --git a/config_test.go b/config_test.go index cf1905b3..fb24c5e2 100644 --- a/config_test.go +++ b/config_test.go @@ -254,25 +254,3 @@ type errorLoader struct{} func (errorLoader) Load() (map[string]any, error) { return nil, errors.New("load error") } - -func TestConfig_logger(t *testing.T) { - t.Parallel() - - logger := &logger{} - _, err := konf.New(konf.WithLogger(logger), konf.WithLoader(mapLoader{})) - require.NoError(t, err) - - require.Equal(t, "Configuration has been loaded.", logger.message) - require.Equal(t, []any{"loader", mapLoader{"configured": true}}, logger.keyAndValues) -} - -type logger struct { - konf.Logger - message string - keyAndValues []any -} - -func (l *logger) Info(message string, keyAndValues ...any) { - l.message = message - l.keyAndValues = keyAndValues -} diff --git a/global.go b/global.go index c7c3b0aa..e254c12a 100644 --- a/global.go +++ b/global.go @@ -5,6 +5,7 @@ package konf import ( "context" + "log/slog" "reflect" "sync" @@ -21,9 +22,9 @@ func Get[T any](path string) T { //nolint:ireturn var value T if err := global.Unmarshal(path, &value); err != nil { - global.logger.Error( + slog.Error( "Could not read config, return empty value instead.", - err, + "error", err, "path", path, "type", reflect.TypeOf(value), ) diff --git a/global_test.go b/global_test.go index a8ed1fa9..dbf49981 100644 --- a/global_test.go +++ b/global_test.go @@ -47,8 +47,8 @@ func TestGet_error(t *testing.T) { log.SetFlags(0) require.False(t, konf.Get[bool]("config")) - expected := "Error Could not read config, return empty value instead." + - " error=[konf] decode: cannot parse '' as bool: strconv.ParseBool: parsing \"string\": invalid syntax" + + expected := "ERROR Could not read config, return empty value instead." + + " error=\"[konf] decode: cannot parse '' as bool: strconv.ParseBool: parsing \\\"string\\\": invalid syntax\"" + " path=config type=bool\n" require.Equal(t, expected, buf.String()) } diff --git a/go.mod b/go.mod index b315a597..dd34f9c1 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/ktong/konf -go 1.20 +go 1.21 require ( github.com/fsnotify/fsnotify v1.7.0 diff --git a/logger.go b/logger.go deleted file mode 100644 index b92c8b26..00000000 --- a/logger.go +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) 2023 The konf authors -// Use of this source code is governed by a MIT license found in the LICENSE file. - -package konf - -import ( - "bytes" - "fmt" - "log" -) - -// Logger is the interface that wraps the basic methods for logging. -type Logger interface { - Info(message string, keyAndValues ...any) - Error(message string, err error, keyAndValues ...any) -} - -type stdlog struct{} - -func (l stdlog) Info(message string, keyAndValues ...any) { - l.log("Info", message, keyAndValues...) -} - -func (l stdlog) Error(message string, err error, keyAndValues ...any) { - if err != nil { - keyAndValues = append([]any{"error", err.Error()}, keyAndValues...) - } - - l.log("Error", message, keyAndValues...) -} - -func (stdlog) log(level, message string, keyAndValues ...any) { - buf := new(bytes.Buffer) - buf.WriteString(level) - buf.WriteRune(' ') - buf.WriteString(message) - for i := 0; i < len(keyAndValues); i += 2 { - buf.WriteRune(' ') - buf.WriteString(fmt.Sprintf("%s=%v", keyAndValues[i], keyAndValues[i+1])) - } - - log.Print(buf) -} diff --git a/option.go b/option.go index 156efac4..f0dc673c 100644 --- a/option.go +++ b/option.go @@ -22,15 +22,6 @@ func WithDelimiter(delimiter string) Option { } } -// WithLogger provides a Logger implementation to logger. -// -// The default implementation is using standard [log]. -func WithLogger(logger Logger) Option { - return func(config *options) { - config.logger = logger - } -} - // Option configures the given Config. type Option func(*options) @@ -44,7 +35,6 @@ func apply(opts []Option) options { option := &options{ Config: &Config{ delimiter: ".", - logger: stdlog{}, values: make(map[string]any), }, }