diff --git a/example/main.go b/example/main.go index e6a23b0..c87b28b 100644 --- a/example/main.go +++ b/example/main.go @@ -5,12 +5,16 @@ import ( "os" "github.com/juju/loggo" + "github.com/juju/loggo/loggoemoji" ) var logger = loggo.GetLogger("main") var rootLogger = loggo.GetLogger("") func main() { + loggo.ResetWriters() + loggo.RegisterWriter("emoji", loggoemoji.NewWriter(os.Stdout)) + args := os.Args if len(args) > 1 { loggo.ConfigureLoggers(args[1]) diff --git a/loggoemoji/package_test.go b/loggoemoji/package_test.go new file mode 100644 index 0000000..a827421 --- /dev/null +++ b/loggoemoji/package_test.go @@ -0,0 +1,14 @@ +// Copyright 2021 Canonical Ltd. +// Licensed under the LGPLv3, see LICENCE file for details. + +package loggoemoji + +import ( + "testing" + + gc "gopkg.in/check.v1" +) + +func Test(t *testing.T) { + gc.TestingT(t) +} diff --git a/loggoemoji/writer.go b/loggoemoji/writer.go new file mode 100644 index 0000000..6f9097c --- /dev/null +++ b/loggoemoji/writer.go @@ -0,0 +1,67 @@ +// Copyright 2021 Canonical Ltd. +// Licensed under the LGPLv3, see LICENCE file for details. + +package loggoemoji + +import ( + "fmt" + "io" + "path/filepath" + + "github.com/juju/ansiterm" + "github.com/juju/loggo" +) + +type levelContext struct { + Emoji string + Style *ansiterm.Context +} + +var ( + // SeverityEmoji defines the colors for the levels output by the ColorWriter. + SeverityEmoji = map[loggo.Level]levelContext{ + loggo.TRACE: {Emoji: "✏️", Style: ansiterm.Foreground(ansiterm.Default)}, + loggo.DEBUG: {Emoji: "🐞", Style: ansiterm.Foreground(ansiterm.Green)}, + loggo.INFO: {Emoji: "🧐", Style: ansiterm.Foreground(ansiterm.BrightBlue)}, + loggo.WARNING: {Emoji: "⚠️ ", Style: ansiterm.Foreground(ansiterm.Yellow)}, + loggo.ERROR: {Emoji: "😱", Style: ansiterm.Foreground(ansiterm.BrightRed)}, + loggo.CRITICAL: {Emoji: "💥", Style: &ansiterm.Context{ + Foreground: ansiterm.White, + Background: ansiterm.Red, + }}, + } + // LocationColor defines the colors for the location output by the ColorWriter. + LocationColor = ansiterm.Foreground(ansiterm.BrightBlue) +) + +type emojiWriter struct { + writer *ansiterm.Writer +} + +// NewWriter will write out colored severity levels if the writer is +// outputting to a terminal. +func NewWriter(writer io.Writer) loggo.Writer { + return &emojiWriter{ansiterm.NewWriter(writer)} +} + +// NewColorWriter will write out colored severity levels whether or not the +// writer is outputting to a terminal. +func NewColorWriter(writer io.Writer) loggo.Writer { + w := ansiterm.NewWriter(writer) + w.SetColorCapable(true) + return &emojiWriter{w} +} + +// Write implements Writer. +func (w *emojiWriter) Write(entry loggo.Entry) { + ts := entry.Timestamp.Format(loggo.TimeFormat) + // Just get the basename from the filename + filename := filepath.Base(entry.Filename) + + fmt.Fprintf(w.writer, "%s ", ts) + SeverityEmoji[entry.Level].Style.Fprintf(w.writer, entry.Level.Short()) + fmt.Fprintf(w.writer, " %s", SeverityEmoji[entry.Level].Emoji) + fmt.Fprintf(w.writer, " %s ", entry.Module) + LocationColor.Fprintf(w.writer, "%s:%d ", filename, entry.Line) + fmt.Fprintln(w.writer, entry.Message) +} diff --git a/loggoemoji/writer_test.go b/loggoemoji/writer_test.go new file mode 100644 index 0000000..daf3d4c --- /dev/null +++ b/loggoemoji/writer_test.go @@ -0,0 +1,53 @@ +// Copyright 2021 Canonical Ltd. +// Licensed under the LGPLv3, see LICENCE file for details. + +package loggoemoji + +import ( + "bytes" + "fmt" + + "github.com/juju/loggo" + gc "gopkg.in/check.v1" +) + +type WriterSuite struct{} + +var _ = gc.Suite(&WriterSuite{}) + +func (s *WriterSuite) TestWriteEmoji(c *gc.C) { + tests := []struct { + Level loggo.Level + Expected string + }{{ + Level: loggo.TRACE, + Expected: "✏️", + }, { + Level: loggo.DEBUG, + Expected: "🐞", + }, { + Level: loggo.INFO, + Expected: "🧐", + }, { + Level: loggo.WARNING, + Expected: "⚠️ ", + }, { + Level: loggo.ERROR, + Expected: "😱", + }, { + Level: loggo.CRITICAL, + Expected: "💥", + }} + for i, test := range tests { + c.Logf("test %d level %s", i, test.Level.Short()) + + buf := new(bytes.Buffer) + writer := NewWriter(buf) + writer.Write(loggo.Entry{ + Level: test.Level, + Message: "Hello", + }) + + c.Assert(buf.String(), gc.Equals, fmt.Sprintf("00:00:00 %s %s .:0 Hello\n", test.Level.Short(), test.Expected)) + } +}