168 lines
3.1 KiB
Go
168 lines
3.1 KiB
Go
package log
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
const (
|
|
CRed = LogColor("\033[01;31m")
|
|
CGreen = LogColor("\033[01;32m")
|
|
CYellow = LogColor("\033[01;33m")
|
|
CBlue = LogColor("\033[01;34m")
|
|
CMagenta = LogColor("\033[01;35m")
|
|
CCyan = LogColor("\033[01;36m")
|
|
CWhite = LogColor("\033[01;37m")
|
|
CReset = LogColor("\033[0m")
|
|
|
|
LDbg = LogLevel(0x00)
|
|
LInf = LogLevel(0x01)
|
|
LWrn = LogLevel(0x02)
|
|
LErr = LogLevel(0x03)
|
|
)
|
|
|
|
var (
|
|
LevelNameMap = map[LogLevel]string{
|
|
LDbg: "DBG",
|
|
LInf: "INF",
|
|
LWrn: "WRN",
|
|
LErr: "ERR",
|
|
}
|
|
|
|
LevelColorMap = map[LogLevel]LogColor{
|
|
LDbg: CBlue,
|
|
LInf: CGreen,
|
|
LWrn: CYellow,
|
|
LErr: CRed,
|
|
}
|
|
)
|
|
|
|
type Logger struct {
|
|
Writer io.Writer
|
|
TimeFormat string
|
|
TagColor map[string]LogColor
|
|
MinLevel LogLevel
|
|
}
|
|
|
|
type Tag struct {
|
|
Name string
|
|
Color LogColor
|
|
Logger *Logger
|
|
}
|
|
|
|
type LogColor string
|
|
type LogLevel uint8
|
|
|
|
func New(w io.Writer) *Logger {
|
|
return &Logger{
|
|
Writer: w,
|
|
TimeFormat: time.RFC3339,
|
|
}
|
|
}
|
|
|
|
func NewStdout() *Logger {
|
|
l := New(os.Stdout)
|
|
l.MinLevel = LInf
|
|
return l
|
|
}
|
|
|
|
func (l *Logger) AddTagColor(prefix string, color LogColor) *Logger {
|
|
l.TagColor[prefix] = color
|
|
return l
|
|
}
|
|
|
|
func (l *Logger) SetTagColor(m map[string]LogColor) *Logger {
|
|
l.TagColor = m
|
|
return l
|
|
}
|
|
|
|
func (l *Logger) SetTimeFormat(format string) *Logger {
|
|
l.TimeFormat = format
|
|
return l
|
|
}
|
|
|
|
func (l *Logger) GetFormatedTime() string {
|
|
return time.Now().Local().Format(l.TimeFormat)
|
|
}
|
|
|
|
func (l *Logger) Logf(tag string, level LogLevel, format string, a ...any) {
|
|
l.Tag(tag).Logf(level, format, a...)
|
|
}
|
|
|
|
func (l *Logger) Tag(tag string) *Tag {
|
|
color := CReset
|
|
for prefix, c := range l.TagColor {
|
|
if strings.HasPrefix(tag, prefix) {
|
|
color = c
|
|
}
|
|
}
|
|
return &Tag{Name: tag, Color: color, Logger: l}
|
|
}
|
|
|
|
func (tag *Tag) ColoredName() string {
|
|
return fmt.Sprintf("%s%s%s", tag.Color, tag.Name, CReset)
|
|
}
|
|
|
|
func (tag *Tag) Logf(level LogLevel, format string, a ...any) {
|
|
if level < tag.Logger.MinLevel {
|
|
return
|
|
}
|
|
lines := strings.Split(fmt.Sprintf(format, a...), "\n")
|
|
for _, line := range lines {
|
|
c := fmt.Sprintf("%s %s - [%s] %s\n",
|
|
tag.Logger.GetFormatedTime(),
|
|
level.Colored(),
|
|
tag.ColoredName(),
|
|
line,
|
|
)
|
|
//nolint:errcheck
|
|
tag.Logger.Writer.Write([]byte(c))
|
|
}
|
|
}
|
|
|
|
func (tag *Tag) LogWriter(level LogLevel) io.Writer {
|
|
r, w := io.Pipe()
|
|
go func() {
|
|
defer w.Close()
|
|
buf2 := []byte{}
|
|
buf1 := make([]byte, 1)
|
|
for {
|
|
_, err := r.Read(buf1)
|
|
if err != nil {
|
|
tag.Logger.Tag("log").Errf("LogWriter read error: %v", err)
|
|
break
|
|
}
|
|
if buf1[0] == '\n' {
|
|
tag.Logf(level, "%s", buf2)
|
|
buf2 = []byte{}
|
|
} else {
|
|
buf2 = append(buf2, buf1[0])
|
|
}
|
|
}
|
|
}()
|
|
return w
|
|
}
|
|
|
|
func (tag *Tag) Dbgf(format string, a ...any) {
|
|
tag.Logf(LDbg, format, a...)
|
|
}
|
|
|
|
func (tag *Tag) Inff(format string, a ...any) {
|
|
tag.Logf(LInf, format, a...)
|
|
}
|
|
|
|
func (tag *Tag) Wrnf(format string, a ...any) {
|
|
tag.Logf(LWrn, format, a...)
|
|
}
|
|
|
|
func (tag *Tag) Errf(format string, a ...any) {
|
|
tag.Logf(LErr, format, a...)
|
|
}
|
|
|
|
func (ll *LogLevel) Colored() string {
|
|
return fmt.Sprintf("%s%s%s", LevelColorMap[*ll], LevelNameMap[*ll], CReset)
|
|
}
|