128 lines
2.7 KiB
Go
128 lines
2.7 KiB
Go
package log
|
|
|
|
import (
|
|
"fmt"
|
|
"golang.org/x/term"
|
|
"io"
|
|
"os"
|
|
"strings"
|
|
)
|
|
|
|
// ColorMode indicates if colorized output should be used
|
|
type ColorMode int
|
|
|
|
const (
|
|
// ColorAuto means to automatically detect if a writer is an interactive terminal and
|
|
// if so use colorized output.
|
|
ColorAuto ColorMode = 0
|
|
|
|
// ColorNever avoids colorized output at all.
|
|
ColorNever ColorMode = -1
|
|
|
|
// ColorAlways enforces colorized output even if it is routed into some file.
|
|
ColorAlways ColorMode = 1
|
|
|
|
// ColorOn means to enable colorized output.
|
|
ColorOn ColorMode = 1
|
|
|
|
// ColorOff means not to use colorized output.
|
|
ColorOff ColorMode = -1
|
|
)
|
|
|
|
// Colorize indicates if colorized output should be used.
|
|
func (c ColorMode) Colorize() bool {
|
|
return c > 0
|
|
}
|
|
|
|
type PlainFormatter struct {
|
|
UseColor ColorMode
|
|
|
|
/* avoid checking the output fd on each log message. Only do so if fd changed */
|
|
lastFd int
|
|
fdColor ColorMode
|
|
}
|
|
|
|
func (f *PlainFormatter) resolveColorMode(target io.Writer) ColorMode {
|
|
if f.UseColor == ColorAuto {
|
|
fd := -1
|
|
if file, ok := target.(*os.File); ok {
|
|
fd = int(file.Fd())
|
|
}
|
|
|
|
if f.fdColor == ColorAuto || fd != f.lastFd {
|
|
// update cache
|
|
f.lastFd = fd
|
|
if fd > -1 && term.IsTerminal(fd) {
|
|
f.fdColor = ColorOn
|
|
} else {
|
|
f.fdColor = ColorOff
|
|
}
|
|
}
|
|
return f.fdColor
|
|
}
|
|
return f.UseColor
|
|
}
|
|
|
|
type levelColorData struct {
|
|
Dark string
|
|
Light string
|
|
}
|
|
|
|
/*
|
|
fg bg
|
|
Black 30/90 40/100
|
|
Red 31 41
|
|
Green 32 42
|
|
Yellow 33 43
|
|
Blue 34 44
|
|
Magenta 35 45
|
|
Cyan 36 46
|
|
White 37 47
|
|
*/
|
|
|
|
var levelColorDatas = []levelColorData{
|
|
/* SILENT */ {Dark: "\033[30;107m", Light: ""}, // never ever log it?
|
|
/* PANIC */ {Dark: "\033[93;101m", Light: ""},
|
|
/* FATAL */ {Dark: "\033[30;101m", Light: ""},
|
|
/* ERROR */ {Dark: "\033[91m", Light: ""},
|
|
/* WARN */ {Dark: "\033[33m", Light: ""},
|
|
/* NOTICE */ {Dark: "\033[95m", Light: ""},
|
|
/* INFO */ {Dark: "\033[97m", Light: ""},
|
|
/* DEBUG */ {Dark: "\033[37m", Light: ""},
|
|
/* TRACE */ {Dark: "\033[90m", Light: ""},
|
|
}
|
|
|
|
func (f *PlainFormatter) String() string {
|
|
return "PlainFormatter"
|
|
}
|
|
|
|
func (f *PlainFormatter) Output(message string, envelope Envelope) {
|
|
o := envelope.Logger().Target()
|
|
cm := f.resolveColorMode(o)
|
|
msg := ""
|
|
if cm.Colorize() {
|
|
msg += levelColorDatas[envelope.Level()].Dark
|
|
}
|
|
|
|
msg += envelope.Time().Format("20060102-150405.000000") + " "
|
|
if envelope.Logger() != 0 {
|
|
msg += "[" + envelope.Logger().String() + "] "
|
|
}
|
|
msg += envelope.Level().String() + ": "
|
|
msg += strings.TrimSpace(message)
|
|
if envelope.Error() != nil {
|
|
msg += fmt.Sprintf(" [err=%v]", envelope.Error())
|
|
}
|
|
for _, v := range envelope.Arguments() {
|
|
msg += " " + v.String()
|
|
}
|
|
if cm.Colorize() {
|
|
msg += "\033[0m"
|
|
}
|
|
msg += "\n"
|
|
|
|
// "time (logger) level message args"
|
|
|
|
fmt.Fprint(o, msg)
|
|
}
|