You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
160 lines
3.3 KiB
160 lines
3.3 KiB
package log |
|
|
|
import ( |
|
"fmt" |
|
"io" |
|
"os" |
|
"strings" |
|
"sync" |
|
|
|
"go-common/app/tool/bgr/log/color" |
|
|
|
"golang.org/x/crypto/ssh/terminal" |
|
) |
|
|
|
// FDWriter interface extends io.Writer with file descriptor function |
|
type FDWriter interface { |
|
io.Writer |
|
Fd() uintptr |
|
} |
|
|
|
// Logger struct definition |
|
type Logger struct { |
|
mu sync.RWMutex |
|
out FDWriter |
|
color bool |
|
debug bool |
|
buf strings.Builder |
|
} |
|
|
|
type prefix struct { |
|
Plain string |
|
Color string |
|
} |
|
|
|
const ( |
|
_plainError = "[ ERROR ] " |
|
_plainWarn = "[ WARN ] " |
|
_plainInfo = "[ INFO ] " |
|
_plainDebug = "[ DEBUG ] " |
|
_plainFatal = "[ FATAL ] " |
|
) |
|
|
|
var ( |
|
_prefixError = prefix{ |
|
Plain: _plainError, |
|
Color: colorful.Red(_plainError), |
|
} |
|
|
|
_prefixWarn = prefix{ |
|
Plain: _plainWarn, |
|
Color: colorful.Orange(_plainWarn), |
|
} |
|
|
|
_prefixInfo = prefix{ |
|
Plain: _plainInfo, |
|
Color: colorful.Green(_plainInfo), |
|
} |
|
|
|
_prefixDebug = prefix{ |
|
Plain: _plainDebug, |
|
Color: colorful.Purple(_plainDebug), |
|
} |
|
|
|
_prefixFatal = prefix{ |
|
Plain: _plainFatal, |
|
Color: colorful.Gray(_plainFatal), |
|
} |
|
) |
|
|
|
// New returns new Logger instance with predefined writer output and |
|
// automatically detect terminal coloring support |
|
func New(out FDWriter, debug bool) *Logger { |
|
return &Logger{ |
|
color: terminal.IsTerminal(int(out.Fd())), |
|
out: out, |
|
debug: debug, |
|
buf: strings.Builder{}, |
|
} |
|
} |
|
|
|
func (l *Logger) output(prefix prefix, data string) (err error) { |
|
l.mu.Lock() |
|
defer l.mu.Unlock() |
|
|
|
l.buf.Reset() |
|
if l.color { |
|
if _, err = l.buf.WriteString(prefix.Color); err != nil { |
|
return |
|
} |
|
} else { |
|
if _, err = l.buf.WriteString(prefix.Plain); err != nil { |
|
return |
|
} |
|
} |
|
if _, err = l.buf.WriteString(data); err != nil { |
|
return |
|
} |
|
if data[len(data)-1] != '\n' { |
|
l.buf.WriteString("\n") |
|
} |
|
|
|
_, err = l.out.Write([]byte(l.buf.String())) |
|
return |
|
} |
|
|
|
// Error print error message to output |
|
func (l *Logger) Error(v ...interface{}) { |
|
l.output(_prefixError, fmt.Sprintln(v...)) |
|
} |
|
|
|
// Errorf print formatted error message to output |
|
func (l *Logger) Errorf(format string, v ...interface{}) { |
|
l.output(_prefixError, fmt.Sprintf(format, v...)) |
|
} |
|
|
|
// Warn print warning message to output |
|
func (l *Logger) Warn(v ...interface{}) { |
|
l.output(_prefixWarn, fmt.Sprintln(v...)) |
|
} |
|
|
|
// Warnf print formatted warning message to output |
|
func (l *Logger) Warnf(format string, v ...interface{}) { |
|
l.output(_prefixWarn, fmt.Sprintf(format, v...)) |
|
} |
|
|
|
// Info print informational message to output |
|
func (l *Logger) Info(v ...interface{}) { |
|
l.output(_prefixInfo, fmt.Sprintln(v...)) |
|
} |
|
|
|
// Infof print formatted informational message to output |
|
func (l *Logger) Infof(format string, v ...interface{}) { |
|
l.output(_prefixInfo, fmt.Sprintf(format, v...)) |
|
} |
|
|
|
// Debug print debug message to output if debug output enabled |
|
func (l *Logger) Debug(v ...interface{}) { |
|
if l.debug { |
|
l.output(_prefixDebug, fmt.Sprintln(v...)) |
|
} |
|
} |
|
|
|
// Debugf print formatted debug message to output if debug output enabled |
|
func (l *Logger) Debugf(format string, v ...interface{}) { |
|
if l.debug { |
|
l.output(_prefixDebug, fmt.Sprintf(format, v...)) |
|
} |
|
} |
|
|
|
// Fatal print fatal message to output and then exit(1) |
|
func (l *Logger) Fatal(v ...interface{}) { |
|
l.output(_prefixFatal, fmt.Sprintln(v...)) |
|
os.Exit(1) |
|
} |
|
|
|
// Fatalf print formatted fatal message to output and then exit(1) |
|
func (l *Logger) Fatalf(format string, v ...interface{}) { |
|
l.output(_prefixFatal, fmt.Sprintf(format, v...)) |
|
os.Exit(1) |
|
}
|
|
|