diff --git a/level.go b/level.go index 3567a9a1e..8f86c430f 100644 --- a/level.go +++ b/level.go @@ -86,6 +86,23 @@ func NewAtomicLevelAt(l zapcore.Level) AtomicLevel { return a } +// ParseAtomicLevel parses an AtomicLevel based on a lowercase or all-caps ASCII +// representation of the log level. If the provided ASCII representation is +// invalid an error is returned. +// +// This is particularly useful when dealing with text input to configure log +// levels. +func ParseAtomicLevel(text string) (AtomicLevel, error) { + a := NewAtomicLevel() + l, err := zapcore.ParseLevel(text) + if err != nil { + return a, err + } + + a.SetLevel(l) + return a, nil +} + // Enabled implements the zapcore.LevelEnabler interface, which allows the // AtomicLevel to be used in place of traditional static levels. func (lvl AtomicLevel) Enabled(l zapcore.Level) bool { diff --git a/level_test.go b/level_test.go index a8fb650c3..ccfc89c34 100644 --- a/level_test.go +++ b/level_test.go @@ -57,6 +57,29 @@ func TestNewAtomicLevel(t *testing.T) { assert.Equal(t, WarnLevel, lvl.Level(), "Unexpected level after SetLevel.") } +func TestParseAtomicLevel(t *testing.T) { + tests := []struct { + text string + level AtomicLevel + err string + }{ + {"info", NewAtomicLevel(), ""}, + {"DEBUG", NewAtomicLevelAt(DebugLevel), ""}, + {"FOO", NewAtomicLevel(), `unrecognized level: "FOO"`}, + } + + for _, tt := range tests { + parsedAtomicLevel, err := ParseAtomicLevel(tt.text) + if len(tt.err) == 0 { + assert.NoError(t, err) + assert.Equal(t, tt.level, parsedAtomicLevel) + } else { + assert.Error(t, err) + assert.Contains(t, err.Error(), tt.err) + } + } +} + func TestAtomicLevelMutation(t *testing.T) { lvl := NewAtomicLevel() lvl.SetLevel(WarnLevel)