Skip to content

Commit

Permalink
feat: add column logger
Browse files Browse the repository at this point in the history
Signed-off-by: gfanton <[email protected]>
  • Loading branch information
gfanton committed Mar 19, 2024
1 parent 9b51ac8 commit 1f8a5df
Show file tree
Hide file tree
Showing 2 changed files with 198 additions and 0 deletions.
144 changes: 144 additions & 0 deletions contribs/gnodev/pkg/logger/log_column.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
package logger

import (
"bytes"
"fmt"
"hash/fnv"
"io"
"log/slog"
"strconv"

"github.com/charmbracelet/lipgloss"
"github.com/charmbracelet/log"
"github.com/muesli/termenv"
)

func NewColumnLogger(w io.Writer, level slog.Level, color bool) *slog.Logger {
charmLogger := log.NewWithOptions(w, log.Options{
ReportTimestamp: false,
ReportCaller: false,
Prefix: "",
})

// Default column output
charmLogger.SetOutput(&columnWriter{
style: lipgloss.NewStyle(),
prefix: "",
writer: w,
})

colorProfile := termenv.TrueColor
if !color {
colorProfile = termenv.Ascii
}

columnHandler := &columnLogger{
Logger: charmLogger,
writer: w,
prefix: charmLogger.GetPrefix(),
colorProfile: colorProfile,
}

charmLogger.SetStyles(DefaultStyles())
charmLogger.SetColorProfile(colorProfile)
charmLogger.SetReportCaller(false)
switch level {
case slog.LevelDebug:
charmLogger.SetLevel(log.DebugLevel)
case slog.LevelError:
charmLogger.SetLevel(log.ErrorLevel)
case slog.LevelInfo:
charmLogger.SetLevel(log.InfoLevel)
case slog.LevelWarn:
charmLogger.SetLevel(log.WarnLevel)
default:
panic("invalid slog level")
}

return slog.New(columnHandler)
}

type columnLogger struct {
*log.Logger

prefix string
writer io.Writer
colorProfile termenv.Profile
}

func (cl *columnLogger) WithGroup(name string) slog.Handler {
if cl.prefix != "" {
name = fmt.Sprintf("%.1s.%s", cl.prefix, name)
}

nlog := cl.Logger.With() // clone logger
baseStyle := lipgloss.NewStyle().Foreground(lipgloss.Color(strconv.Itoa(stringToColor(name))))
nlog.SetOutput()
nlog.SetColorProfile(cl.colorProfile)
return &columnLogger{
Logger: nlog,
prefix: name,
writer: cl.writer,
}
}

var lf = []byte{'\n'}

type columnWriter struct {
inline bool
style lipgloss.Style
prefix string
writer io.Writer
}

func NewColumeWriter(baseStyle lipgloss.Style, prefix string, writer io.Writer) *columnWriter {
style := baseStyle.
Border(lipgloss.ThickBorder(), false, true, false, false).
BorderForeground(baseStyle.GetForeground()).
Bold(true).
Width(12)
return &columnWriter{style: style, prefix: prefix, writer: writer}
}

func (cl *columnWriter) Write(buf []byte) (n int, err error) {
for line := 0; len(buf) > 0; line++ {
i := bytes.IndexByte(buf, '\n')
todo := len(buf)
if i >= 0 {
todo = i
}

if !cl.inline {
var prefix string
if line == 0 {
prefix = cl.prefix
}

fmt.Fprint(cl.writer, cl.style.Render(prefix)+" ")
}

var nn int
nn, err = cl.writer.Write(buf[:todo])
n += nn
if err != nil {
return n, err
}
buf = buf[todo:]

if cl.inline = i < 0; !cl.inline {
if _, err = cl.writer.Write([]byte(lf)); err != nil {
return n, err
}
n++
buf = buf[1:]
}
}

return n, nil
}

func stringToColor(s string) int {
h := fnv.New32a()
h.Write([]byte(s))
return int((h.Sum32()+10)%255) + 1
}
54 changes: 54 additions & 0 deletions contribs/gnodev/pkg/logger/log_styles.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package logger

import (
"strings"

"github.com/charmbracelet/lipgloss"
"github.com/charmbracelet/log"
)

// DefaultStyles returns the default styles.
func DefaultStyles() *log.Styles {
style := log.DefaultStyles()
style.Levels = map[log.Level]lipgloss.Style{
log.DebugLevel: lipgloss.NewStyle().
SetString(strings.ToUpper(log.DebugLevel.String())).
Bold(true).
MaxWidth(1).
Foreground(lipgloss.Color("63")),
log.InfoLevel: lipgloss.NewStyle().
SetString(strings.ToUpper(log.InfoLevel.String())).
MaxWidth(1).
Foreground(lipgloss.Color("12")),

log.WarnLevel: lipgloss.NewStyle().
SetString(strings.ToUpper(log.WarnLevel.String())).
Bold(true).
MaxWidth(1).
Foreground(lipgloss.Color("192")),
log.ErrorLevel: lipgloss.NewStyle().
SetString(strings.ToUpper(log.ErrorLevel.String())).
Bold(true).
MaxWidth(1).
Foreground(lipgloss.Color("204")),
log.FatalLevel: lipgloss.NewStyle().
SetString(strings.ToUpper(log.FatalLevel.String())).
Bold(true).
MaxWidth(1).
Foreground(lipgloss.Color("134")),
}
style.Keys = map[string]lipgloss.Style{
"err": lipgloss.NewStyle().
Foreground(lipgloss.Color("9")),
"error": lipgloss.NewStyle().
Foreground(lipgloss.Color("9")),
}
style.Values = map[string]lipgloss.Style{
"err": lipgloss.NewStyle().
Foreground(lipgloss.Color("9")),
"error": lipgloss.NewStyle().
Foreground(lipgloss.Color("9")),
}

return style
}

0 comments on commit 1f8a5df

Please sign in to comment.