update
commit
0e3a40c587
|
@ -0,0 +1,65 @@
|
||||||
|
package log
|
||||||
|
|
||||||
|
type Attribute int
|
||||||
|
|
||||||
|
// Base attributes
|
||||||
|
const (
|
||||||
|
Reset Attribute = iota
|
||||||
|
Bold
|
||||||
|
Faint
|
||||||
|
Italic
|
||||||
|
Underline
|
||||||
|
BlinkSlow
|
||||||
|
BlinkRapid
|
||||||
|
ReverseVideo
|
||||||
|
Concealed
|
||||||
|
CrossedOut
|
||||||
|
)
|
||||||
|
|
||||||
|
// Foreground text colors
|
||||||
|
const (
|
||||||
|
FgBlack Attribute = iota + 30
|
||||||
|
FgRed
|
||||||
|
FgGreen
|
||||||
|
FgYellow
|
||||||
|
FgBlue
|
||||||
|
FgMagenta
|
||||||
|
FgCyan
|
||||||
|
FgWhite
|
||||||
|
)
|
||||||
|
|
||||||
|
// Foreground Hi-Intensity text colors
|
||||||
|
const (
|
||||||
|
FgHiBlack Attribute = iota + 90
|
||||||
|
FgHiRed
|
||||||
|
FgHiGreen
|
||||||
|
FgHiYellow
|
||||||
|
FgHiBlue
|
||||||
|
FgHiMagenta
|
||||||
|
FgHiCyan
|
||||||
|
FgHiWhite
|
||||||
|
)
|
||||||
|
|
||||||
|
// Background text colors
|
||||||
|
const (
|
||||||
|
BgBlack Attribute = iota + 40
|
||||||
|
BgRed
|
||||||
|
BgGreen
|
||||||
|
BgYellow
|
||||||
|
BgBlue
|
||||||
|
BgMagenta
|
||||||
|
BgCyan
|
||||||
|
BgWhite
|
||||||
|
)
|
||||||
|
|
||||||
|
// Background Hi-Intensity text colors
|
||||||
|
const (
|
||||||
|
BgHiBlack Attribute = iota + 100
|
||||||
|
BgHiRed
|
||||||
|
BgHiGreen
|
||||||
|
BgHiYellow
|
||||||
|
BgHiBlue
|
||||||
|
BgHiMagenta
|
||||||
|
BgHiCyan
|
||||||
|
BgHiWhite
|
||||||
|
)
|
|
@ -0,0 +1,8 @@
|
||||||
|
module kumoly.io/core/log
|
||||||
|
|
||||||
|
go 1.17
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||||
|
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect
|
||||||
|
)
|
|
@ -0,0 +1,4 @@
|
||||||
|
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
|
||||||
|
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||||
|
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I=
|
||||||
|
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
@ -0,0 +1,172 @@
|
||||||
|
package log
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"runtime"
|
||||||
|
"text/template"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/mattn/go-isatty"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
Lerror = 1 << iota
|
||||||
|
Lwarn
|
||||||
|
Linfo
|
||||||
|
Ldebug
|
||||||
|
)
|
||||||
|
|
||||||
|
var PROD = true
|
||||||
|
var LEVEL = Lerror | Linfo
|
||||||
|
|
||||||
|
const (
|
||||||
|
DEFAULT_ERR = `{{Time}} [{{red}}ERROR{{reset}}]({{cyan}}{{.System}}{{reset}}) {{.Caller}} {{.Message}}{{if .Fields}}{{printf "%v\n" .Fields}}{{end}}{{if .Stack}}{{redl}}{{.Stack}}{{reset}}{{end}}`
|
||||||
|
DEFAULT_DEBUG = `{{Time}} [{{magenta}}DEBUG{{reset}}]({{cyan}}{{.System}}{{reset}}) {{.Caller}} {{.Message}}{{if .Fields}}{{printf "%v\n" .Fields}}{{end}}{{if .Stack}}{{.Stack}}{{end}}`
|
||||||
|
DEFAULT_WARN = `{{Time}} [{{yellow}}WARN {{reset}}]({{cyan}}{{.System}}{{reset}}) {{.Message}}{{if .Fields}}{{printf "%v\n" .Fields}}{{end}}`
|
||||||
|
DEFAULT_INFO = `{{Time}} [{{blue}}INFO {{reset}}]({{cyan}}{{.System}}{{reset}}) {{.Message}}{{if .Fields}}{{printf "%v\n" .Fields}}{{end}}`
|
||||||
|
)
|
||||||
|
|
||||||
|
type LogFormater struct {
|
||||||
|
ErrTmplStr string
|
||||||
|
WarnTmplStr string
|
||||||
|
InfoTmplStr string
|
||||||
|
DebugTmplStr string
|
||||||
|
}
|
||||||
|
|
||||||
|
type H map[string]interface{}
|
||||||
|
|
||||||
|
type Ldata struct {
|
||||||
|
Message string
|
||||||
|
System string
|
||||||
|
|
||||||
|
// Caller only evaluates in DEBUG, and ERROR calls
|
||||||
|
Caller string
|
||||||
|
|
||||||
|
// Stack only eval when !PROD and {DEBUG, ERROR}
|
||||||
|
Stack string
|
||||||
|
Fields H
|
||||||
|
|
||||||
|
Color bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type logger struct {
|
||||||
|
system string
|
||||||
|
color bool
|
||||||
|
|
||||||
|
err io.Writer
|
||||||
|
out io.Writer
|
||||||
|
|
||||||
|
err_tmpl *template.Template
|
||||||
|
warn_tmpl *template.Template
|
||||||
|
info_tmpl *template.Template
|
||||||
|
debug_tmpl *template.Template
|
||||||
|
}
|
||||||
|
|
||||||
|
func New() *logger {
|
||||||
|
l := &logger{
|
||||||
|
err: os.Stderr,
|
||||||
|
out: os.Stdout,
|
||||||
|
color: true,
|
||||||
|
}
|
||||||
|
l.guessColor()
|
||||||
|
l.SetTmpl(NewLogFormater())
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *logger) guessColor() {
|
||||||
|
if w, ok := l.out.(*os.File); !ok || os.Getenv("TERM") == "dumb" ||
|
||||||
|
(!isatty.IsTerminal(w.Fd()) && !isatty.IsCygwinTerminal(w.Fd())) {
|
||||||
|
l.color = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (l *logger) SetColor(c bool) {
|
||||||
|
l.color = c
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewLogFormater() *LogFormater {
|
||||||
|
return &LogFormater{
|
||||||
|
ErrTmplStr: DEFAULT_ERR,
|
||||||
|
WarnTmplStr: DEFAULT_WARN,
|
||||||
|
InfoTmplStr: DEFAULT_INFO,
|
||||||
|
DebugTmplStr: DEFAULT_DEBUG,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *logger) SetTmpl(tmpl *LogFormater) error {
|
||||||
|
funcMap := template.FuncMap{
|
||||||
|
"Time": func() string { return time.Now().Format("2006/01/02 15:04:05") },
|
||||||
|
"red": func() string { return "\033[91m" },
|
||||||
|
"redl": func() string { return "\033[31m" },
|
||||||
|
"green": func() string { return "\033[92m" },
|
||||||
|
"yellow": func() string { return "\033[93m" },
|
||||||
|
"blue": func() string { return "\033[94m" },
|
||||||
|
"magenta": func() string { return "\033[95m" },
|
||||||
|
"cyan": func() string { return "\033[96m" },
|
||||||
|
"white": func() string { return "\033[97m" },
|
||||||
|
"reset": func() string { return "\033[0m" },
|
||||||
|
}
|
||||||
|
err_tmpl, err := template.New("err_tmpl").Funcs(funcMap).Parse(tmpl.ErrTmplStr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
l.err_tmpl = err_tmpl
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *logger) error(depth int, stack string, fields H, v ...interface{}) {
|
||||||
|
msg := fmt.Sprintln(v...)
|
||||||
|
data := Ldata{
|
||||||
|
Fields: fields,
|
||||||
|
Message: msg,
|
||||||
|
System: l.system,
|
||||||
|
Caller: caller(depth),
|
||||||
|
Color: l.color,
|
||||||
|
Stack: stack,
|
||||||
|
}
|
||||||
|
err := l.err_tmpl.Execute(os.Stdout, data)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *logger) ErrorF(fields H, v ...interface{}) {
|
||||||
|
stak := ""
|
||||||
|
if !PROD {
|
||||||
|
stak = stack()
|
||||||
|
}
|
||||||
|
l.error(3, stak, fields, v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *logger) Error(v ...interface{}) {
|
||||||
|
stak := ""
|
||||||
|
if !PROD {
|
||||||
|
stak = stack()
|
||||||
|
}
|
||||||
|
l.error(3, stak, H{}, v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func caller(depth int) string {
|
||||||
|
_, file, line, _ := runtime.Caller(depth)
|
||||||
|
short := file
|
||||||
|
for i := len(file) - 1; i > 0; i-- {
|
||||||
|
if file[i] == '/' {
|
||||||
|
short = file[i+1:]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%s:%d", short, line)
|
||||||
|
}
|
||||||
|
|
||||||
|
func stack() string {
|
||||||
|
buf := make([]byte, 1024)
|
||||||
|
for {
|
||||||
|
n := runtime.Stack(buf, false)
|
||||||
|
if n < len(buf) {
|
||||||
|
return string(buf[:n])
|
||||||
|
}
|
||||||
|
buf = make([]byte, 2*len(buf))
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package log
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestError(t *testing.T) {
|
||||||
|
PROD = false
|
||||||
|
log := New()
|
||||||
|
log.system = "test"
|
||||||
|
log.Error("d", "sdf", "sdfsdf")
|
||||||
|
|
||||||
|
log.ErrorF(H{"Test": "set"}, "d", "sdf", "sdfsdf")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestErrorProd(t *testing.T) {
|
||||||
|
PROD = true
|
||||||
|
log := New()
|
||||||
|
log.system = "test"
|
||||||
|
log.Error("d", "sdf", "sdfsdf")
|
||||||
|
|
||||||
|
log.ErrorF(H{"Test": "set"}, "d", "sdf", "sdfsdf")
|
||||||
|
}
|
Loading…
Reference in New Issue