From c087e079edefbb0aca0d5a3eeab167b61fff6093 Mon Sep 17 00:00:00 2001 From: Techassi Date: Fri, 14 Jan 2022 09:40:43 +0100 Subject: [PATCH] zap: Add ParseAtomicLevel func (#1048) As discussed in #1047 this PR adds a zap.ParseAtomicLevel() func which enables the user to construct a log level based on ASCII text input. Usage ``` level, err := zap.ParseAtomicLevel("info") // InfoLevel, nil level, err := zap.ParseAtomicLevel("DEBUG") // DebugLevel, nil level, err := zap.ParseAtomicLevel("FOO") // InfoLevel, "unrecognized level: "FOO"" ``` Co-authored-by: Sung Yoon Whang Co-authored-by: Sung Yoon Whang --- level.go | 17 +++++++++++++++++ level_test.go | 23 +++++++++++++++++++++++ 2 files changed, 40 insertions(+) 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)