Skip to content

Commit 2ba2d8b

Browse files
committed
TextUnmarshaler for Options for env
By implementing the encoding.TextUnmarshaler, Options can be populated by environment variables from env.
1 parent d147b4c commit 2ba2d8b

File tree

2 files changed

+30
-11
lines changed

2 files changed

+30
-11
lines changed

logging/config.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,39 @@ import (
55
"github.com/pkg/errors"
66
"go.uber.org/zap/zapcore"
77
"os"
8+
"strings"
89
"time"
910
)
1011

1112
// Options define child loggers with their desired log level.
1213
type Options map[string]zapcore.Level
1314

15+
// UnmarshalText implements encoding.TextUnmarshaler to allow Options to be parsed by env.
16+
//
17+
// This custom TextUnmarshaler is necessary as - for the moment - env does not support map[T]encoding.TextUnmarshaler.
18+
// After <https://github.com/caarlos0/env/pull/323> got merged and a new env release was drafted, this method can be
19+
// removed.
20+
func (o *Options) UnmarshalText(text []byte) error {
21+
optionsMap := make(map[string]zapcore.Level)
22+
23+
for _, entry := range strings.Split(string(text), ",") {
24+
key, valueStr, found := strings.Cut(entry, ":")
25+
if !found {
26+
return fmt.Errorf("entry %q cannot be unmarshalled as an Option entry", entry)
27+
}
28+
29+
valueLvl, err := zapcore.ParseLevel(valueStr)
30+
if err != nil {
31+
return fmt.Errorf("entry %q cannot be unmarshalled as level, %w", entry, err)
32+
}
33+
34+
optionsMap[key] = valueLvl
35+
}
36+
37+
*o = optionsMap
38+
return nil
39+
}
40+
1441
// Config defines Logger configuration.
1542
type Config struct {
1643
// zapcore.Level at 0 is for info level.

logging/config_test.go

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -55,17 +55,9 @@ func TestConfig(t *testing.T) {
5555
},
5656
},
5757
{
58-
name: "options-as-ints",
59-
opts: config.EnvOptions{Environment: map[string]string{"OPTIONS": "foo:-1,bar:0,buz:4"}},
60-
expected: Config{
61-
Output: "console",
62-
Interval: 20 * time.Second,
63-
Options: map[string]zapcore.Level{
64-
"foo": zapcore.DebugLevel,
65-
"bar": zapcore.InfoLevel,
66-
"buz": zapcore.PanicLevel,
67-
},
68-
},
58+
name: "options-invalid-levels",
59+
opts: config.EnvOptions{Environment: map[string]string{"OPTIONS": "foo:foo,bar:0"}},
60+
error: true,
6961
},
7062
}
7163

0 commit comments

Comments
 (0)