Skip to content

Commit

Permalink
Merge branch 'main' into slog
Browse files Browse the repository at this point in the history
  • Loading branch information
aymanbagabas authored Nov 7, 2023
2 parents cafb9c6 + d96bea2 commit d1330ba
Show file tree
Hide file tree
Showing 7 changed files with 204 additions and 157 deletions.
19 changes: 12 additions & 7 deletions level.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package log

import (
"math"
"errors"
"fmt"
"strings"
)

Expand Down Expand Up @@ -41,20 +43,23 @@ func (l Level) String() string {
}
}

// ErrInvalidLevel is an error returned when parsing an invalid level string.
var ErrInvalidLevel = errors.New("invalid level")

// ParseLevel converts level in string to Level type. Default level is InfoLevel.
func ParseLevel(level string) Level {
func ParseLevel(level string) (Level, error) {
switch strings.ToLower(level) {
case DebugLevel.String():
return DebugLevel
return DebugLevel, nil
case InfoLevel.String():
return InfoLevel
return InfoLevel, nil
case WarnLevel.String():
return WarnLevel
return WarnLevel, nil
case ErrorLevel.String():
return ErrorLevel
return ErrorLevel, nil
case FatalLevel.String():
return FatalLevel
return FatalLevel, nil
default:
return InfoLevel
return 0, fmt.Errorf("%w: %q", ErrInvalidLevel, level)
}
}
46 changes: 29 additions & 17 deletions level_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package log

import (
"fmt"
"testing"

"github.com/stretchr/testify/assert"
Expand All @@ -10,52 +11,63 @@ func TestDefaultLevel(t *testing.T) {
var level Level
assert.Equal(t, InfoLevel, level)
}

func TestParseLevel(t *testing.T) {
testCases := []struct {
name string
level string
expLevel Level
input string
expected Level
error error
}{
{
name: "Parse debug",
level: "debug",
expLevel: DebugLevel,
input: "debug",
expected: DebugLevel,
error: nil,
},
{
name: "Parse info",
level: "Info",
expLevel: InfoLevel,
input: "Info",
expected: InfoLevel,
error: nil,
},
{
name: "Parse warn",
level: "WARN",
expLevel: WarnLevel,
input: "WARN",
expected: WarnLevel,
error: nil,
},
{
name: "Parse error",
level: "error",
expLevel: ErrorLevel,
input: "error",
expected: ErrorLevel,
error: nil,
},
{
name: "Parse fatal",
level: "FATAL",
expLevel: FatalLevel,
input: "FATAL",
expected: FatalLevel,
error: nil,
},
{
name: "Default",
level: "",
expLevel: InfoLevel,
input: "",
expected: InfoLevel,
error: fmt.Errorf("%w: %q", ErrInvalidLevel, ""),
},
{
name: "Wrong level, set INFO",
level: "WRONG_LEVEL",
expLevel: InfoLevel,
input: "WRONG_LEVEL",
expected: InfoLevel,
error: fmt.Errorf("%w: %q", ErrInvalidLevel, "WRONG_LEVEL"),
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
assert.Equal(t, tc.expLevel, ParseLevel(tc.level))
lvl, err := ParseLevel(tc.input)
assert.Equal(t, tc.expected, lvl)
assert.Equal(t, tc.error, err)
})
}
}
14 changes: 14 additions & 0 deletions logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ type Logger struct {
fields []interface{}

helpers *sync.Map
styles *Styles
}

func (l *Logger) log(level Level, msg interface{}, keyvals ...interface{}) {
Expand Down Expand Up @@ -308,15 +309,28 @@ func (l *Logger) SetColorProfile(profile termenv.Profile) {
l.re.SetColorProfile(profile)
}

// SetStyles sets the logger styles for the TextFormatter.
func (l *Logger) SetStyles(s *Styles) {
if s == nil {
s = DefaultStyles()
}
l.mu.Lock()
defer l.mu.Unlock()
l.styles = s
}

// With returns a new logger with the given keyvals added.
func (l *Logger) With(keyvals ...interface{}) *Logger {
var st Styles
l.mu.Lock()
sl := *l
st = *l.styles
l.mu.Unlock()
sl.b = bytes.Buffer{}
sl.mu = &sync.RWMutex{}
sl.helpers = &sync.Map{}
sl.fields = append(l.fields, keyvals...)
sl.styles = &st
return &sl
}

Expand Down
6 changes: 6 additions & 0 deletions pkg.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ func NewWithOptions(w io.Writer, o Options) *Logger {

l.SetOutput(w)
l.SetLevel(Level(l.level))
l.SetStyles(DefaultStyles())

if l.callerFormatter == nil {
l.callerFormatter = ShortCallerFormatter
Expand Down Expand Up @@ -132,6 +133,11 @@ func SetColorProfile(profile termenv.Profile) {
defaultLogger.SetColorProfile(profile)
}

// SetStyles sets the logger styles for the TextFormatter.
func SetStyles(s *Styles) {
defaultLogger.SetStyles(s)
}

// GetPrefix returns the prefix for the default logger.
func GetPrefix() string {
return defaultLogger.GetPrefix()
Expand Down
161 changes: 77 additions & 84 deletions styles.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,99 +6,92 @@ import (
"github.com/charmbracelet/lipgloss"
)

var (
// TimestampStyle is the style for timestamps.
TimestampStyle = lipgloss.NewStyle()
// Styles defines the styles for the text logger.
type Styles struct {
// Timestamp is the style for timestamps.
Timestamp lipgloss.Style

// CallerStyle is the style for caller.
CallerStyle = lipgloss.NewStyle().Faint(true)
// Caller is the style for source caller.
Caller lipgloss.Style

// PrefixStyle is the style for prefix.
PrefixStyle = lipgloss.NewStyle().Bold(true).Faint(true)
// Prefix is the style for prefix.
Prefix lipgloss.Style

// MessageStyle is the style for messages.
MessageStyle = lipgloss.NewStyle()
// Message is the style for messages.
Message lipgloss.Style

// KeyStyle is the style for keys.
KeyStyle = lipgloss.NewStyle().Faint(true)
// Key is the style for keys.
Key lipgloss.Style

// ValueStyle is the style for values.
ValueStyle = lipgloss.NewStyle()
// Value is the style for values.
Value lipgloss.Style

// SeparatorStyle is the style for separators.
SeparatorStyle = lipgloss.NewStyle().Faint(true)
// Separator is the style for separators.
Separator lipgloss.Style

// DebugLevel is the style for debug level.
DebugLevelStyle = lipgloss.NewStyle().
SetString(strings.ToUpper(DebugLevel.String())).
Bold(true).
MaxWidth(4).
Foreground(lipgloss.AdaptiveColor{
Light: "63",
Dark: "63",
})
// Levels are the styles for each level.
Levels map[Level]lipgloss.Style

// InfoLevel is the style for info level.
InfoLevelStyle = lipgloss.NewStyle().
SetString(strings.ToUpper(InfoLevel.String())).
Bold(true).
MaxWidth(4).
Foreground(lipgloss.AdaptiveColor{
Light: "39",
Dark: "86",
})
// Keys overrides styles for specific keys.
Keys map[string]lipgloss.Style

// WarnLevel is the style for warn level.
WarnLevelStyle = lipgloss.NewStyle().
SetString(strings.ToUpper(WarnLevel.String())).
Bold(true).
MaxWidth(4).
Foreground(lipgloss.AdaptiveColor{
Light: "208",
Dark: "192",
})

// ErrorLevel is the style for error level.
ErrorLevelStyle = lipgloss.NewStyle().
SetString(strings.ToUpper(ErrorLevel.String())).
Bold(true).
MaxWidth(4).
Foreground(lipgloss.AdaptiveColor{
Light: "203",
Dark: "204",
})

// FatalLevel is the style for error level.
FatalLevelStyle = lipgloss.NewStyle().
SetString(strings.ToUpper(FatalLevel.String())).
Bold(true).
MaxWidth(4).
Foreground(lipgloss.AdaptiveColor{
Light: "133",
Dark: "134",
})

// KeyStyles overrides styles for specific keys.
KeyStyles = map[string]lipgloss.Style{}

// ValueStyles overrides value styles for specific keys.
ValueStyles = map[string]lipgloss.Style{}
)
// Values overrides value styles for specific keys.
Values map[string]lipgloss.Style
}

// levelStyle is a helper function to get the style for a level.
func levelStyle(level Level) lipgloss.Style {
switch level {
case DebugLevel:
return DebugLevelStyle
case InfoLevel:
return InfoLevelStyle
case WarnLevel:
return WarnLevelStyle
case ErrorLevel:
return ErrorLevelStyle
case FatalLevel:
return FatalLevelStyle
default:
return lipgloss.NewStyle()
// DefaultStyles returns the default styles.
func DefaultStyles() *Styles {
return &Styles{
Timestamp: lipgloss.NewStyle(),
Caller: lipgloss.NewStyle().Faint(true),
Prefix: lipgloss.NewStyle().Bold(true).Faint(true),
Message: lipgloss.NewStyle(),
Key: lipgloss.NewStyle().Faint(true),
Value: lipgloss.NewStyle(),
Separator: lipgloss.NewStyle().Faint(true),
Levels: map[Level]lipgloss.Style{
DebugLevel: lipgloss.NewStyle().
SetString(strings.ToUpper(DebugLevel.String())).
Bold(true).
MaxWidth(4).
Foreground(lipgloss.AdaptiveColor{
Light: "63",
Dark: "63",
}),
InfoLevel: lipgloss.NewStyle().
SetString(strings.ToUpper(InfoLevel.String())).
Bold(true).
MaxWidth(4).
Foreground(lipgloss.AdaptiveColor{
Light: "39",
Dark: "86",
}),
WarnLevel: lipgloss.NewStyle().
SetString(strings.ToUpper(WarnLevel.String())).
Bold(true).
MaxWidth(4).
Foreground(lipgloss.AdaptiveColor{
Light: "208",
Dark: "192",
}),
ErrorLevel: lipgloss.NewStyle().
SetString(strings.ToUpper(ErrorLevel.String())).
Bold(true).
MaxWidth(4).
Foreground(lipgloss.AdaptiveColor{
Light: "203",
Dark: "204",
}),
FatalLevel: lipgloss.NewStyle().
SetString(strings.ToUpper(FatalLevel.String())).
Bold(true).
MaxWidth(4).
Foreground(lipgloss.AdaptiveColor{
Light: "133",
Dark: "134",
}),
},
Keys: map[string]lipgloss.Style{},
Values: map[string]lipgloss.Style{},
}
}
Loading

0 comments on commit d1330ba

Please sign in to comment.