Skip to content

Commit

Permalink
Add built-in console log formatter.
Browse files Browse the repository at this point in the history
  • Loading branch information
Qingshan Luo committed Dec 2, 2021
1 parent 13f95ef commit 8e2d77d
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 0 deletions.
54 changes: 54 additions & 0 deletions console_formatter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package logger

import (
"bytes"

"github.com/edoger/zkits-logger/internal"
)

// NewConsoleFormatter creates and returns an instance of the log console formatter.
// The console formatter is very similar to the text formatter. The only difference is that
// we output different console colors for different log levels, which is very useful when
// outputting logs from the console.
func NewConsoleFormatter() Formatter {
return new(consoleFormatter)
}

// The built-in console formatter.
type consoleFormatter struct{}

// Format formats the given log entity into character data and writes it to the given buffer.
func (f *consoleFormatter) Format(e Entity, b *bytes.Buffer) (err error) {
if name := e.Name(); name == "" {
b.WriteString("[" + e.TimeString() + "]")
} else {
b.WriteString(name + " [" + e.TimeString() + "]")
}
switch e.Level() {
case TraceLevel:
b.WriteString("[\u001B[36m" + e.Level().ShortCapitalString() + "\u001B[0m] ") // cyan
case DebugLevel:
b.WriteString("[\u001B[96m" + e.Level().ShortCapitalString() + "\u001B[0m] ") // hi-intensity cyan
case InfoLevel:
b.WriteString("[\u001B[92m" + e.Level().ShortCapitalString() + "\u001B[0m] ") // hi-intensity green
case WarnLevel:
b.WriteString("[\u001B[93m" + e.Level().ShortCapitalString() + "\u001B[0m] ") // hi-intensity yellow
case ErrorLevel:
b.WriteString("[\u001B[95m" + e.Level().ShortCapitalString() + "\u001B[0m] ") // hi-intensity red
case FatalLevel:
b.WriteString("[\u001B[31m" + e.Level().ShortCapitalString() + "\u001B[0m] ") // magenta
case PanicLevel:
b.WriteString("[\u001B[91m" + e.Level().ShortCapitalString() + "\u001B[0m] ") // hi-intensity magenta
default:
b.WriteString("[" + e.Level().ShortCapitalString() + "] ") // no color
}
b.WriteString(e.Message())
if caller := e.Caller(); caller != "" {
b.WriteString(" " + caller)
}
if fields := e.Fields(); len(fields) > 0 {
b.WriteString(" " + internal.FormatFieldsToText(e.Fields()))
}
b.WriteByte('\n')
return
}
23 changes: 23 additions & 0 deletions console_formatter_caller_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package logger

import (
"bytes"
"fmt"
"strconv"
"testing"
)

func TestConsoleFormatter_Format_WithoutCaller(t *testing.T) {
l := New("")
l.SetFormatter(NewConsoleFormatter())
l.SetDefaultTimeFormat("TIME")
buf := new(bytes.Buffer)
l.SetOutput(buf)

l.WithField("foo", 1).WithCaller().Trace("test") // LINE 17
fmt.Println(buf.String())
want := "[TIME][\u001B[36mTAC\u001B[0m] test console_formatter_caller_test.go:17 foo=1\n"
if want != buf.String() {
t.Fatalf("NewConsoleFormatter().Format(): %s", strconv.Quote(buf.String()))
}
}
61 changes: 61 additions & 0 deletions console_formatter_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package logger

import (
"bytes"
"fmt"
"strconv"
"strings"
"testing"
)

func TestNewConsoleFormatter(t *testing.T) {
if f := NewConsoleFormatter(); f == nil {
t.Fatal("NewConsoleFormatter(): return nil.")
}
}

func TestConsoleFormatter_Format(t *testing.T) {
l := New("CONSOLE")
l.SetFormatter(NewConsoleFormatter())
l.SetDefaultTimeFormat("TIME")
l.SetExitFunc(nil)
l.SetPanicFunc(nil)
buf := new(bytes.Buffer)
l.SetOutput(buf)

l.WithField("foo", 1).Trace("test")
l.WithField("foo", 1).Debug("test")
l.WithField("foo", 1).Info("test")
l.WithField("foo", 1).Warn("test")
l.WithField("foo", 1).Error("test")
l.WithField("foo", 1).Fatal("test")
l.WithField("foo", 1).Panic("test")
fmt.Println(buf.String())
lines := []string{
"CONSOLE [TIME][\u001B[36mTAC\u001B[0m] test foo=1",
"CONSOLE [TIME][\u001B[96mDBG\u001B[0m] test foo=1",
"CONSOLE [TIME][\u001B[92mINF\u001B[0m] test foo=1",
"CONSOLE [TIME][\u001B[93mWAN\u001B[0m] test foo=1",
"CONSOLE [TIME][\u001B[95mERR\u001B[0m] test foo=1",
"CONSOLE [TIME][\u001B[31mFAT\u001B[0m] test foo=1",
"CONSOLE [TIME][\u001B[91mPNC\u001B[0m] test foo=1",
}
if want := strings.Join(lines, "\n") + "\n"; want != buf.String() {
t.Fatalf("NewConsoleFormatter().Format(): %s", strconv.Quote(buf.String()))
}
}

func TestConsoleFormatter_Format_WithoutName(t *testing.T) {
l := New("")
l.SetFormatter(NewConsoleFormatter())
l.SetDefaultTimeFormat("TIME")
buf := new(bytes.Buffer)
l.SetOutput(buf)

l.WithField("foo", 1).Trace("test")
fmt.Println(buf.String())
want := "[TIME][\u001B[36mTAC\u001B[0m] test foo=1\n"
if want != buf.String() {
t.Fatalf("NewConsoleFormatter().Format(): %s", strconv.Quote(buf.String()))
}
}

0 comments on commit 8e2d77d

Please sign in to comment.