Files
sacrificial-socket/log/json.go

153 lines
2.8 KiB
Go

package log
import (
"encoding/json"
"fmt"
"io"
"os"
"runtime"
"strings"
"time"
)
type jLog struct {
Timestamp time.Time `json:"ts"`
File string `json:"file"`
Line int `json:"line"`
Level string `json:"level"`
Fatal bool `json:"fatal"`
Msg string `json:"msg"`
}
func (jl *jLog) Marshal() []byte {
data, err := json.Marshal(jl)
if err != nil {
return []byte(fmt.Sprintf(`{"Error":"%s", "Line": %d, "File":"%s"}`, err, jl.Line, jl.File))
}
return data
}
type jsonLogFmt struct {
out io.Writer
logLevel int
logLevelAllowed int
}
func (j *jsonLogFmt) canLog() bool {
return (j.logLevel & j.logLevelAllowed) == j.logLevelAllowed
}
func (j *jsonLogFmt) writeJLog(msg string, fatal bool) {
jl := newJLog(msg, LogLevelMap[j.logLevelAllowed], fatal, 3)
data := jl.Marshal()
j.out.Write(append(data, '\n'))
}
func newJLog(msg, level string, fatal bool, callDepth int) *jLog {
jl := &jLog{
Timestamp: time.Now(),
Level: level,
Fatal: fatal,
Msg: msg,
}
_, file, line, ok := runtime.Caller(callDepth)
jl.File = file
jl.Line = line
if !ok {
jl.File = "???"
jl.Line = -1
}
return jl
}
func (j *jsonLogFmt) Print(v ...interface{}) {
if !j.canLog() {
return
}
msg, fatal := fmt.Sprint(v...), false
msg = strings.TrimRight(msg, "\n")
j.writeJLog(msg, fatal)
}
func (j *jsonLogFmt) Printf(format string, v ...interface{}) {
if !j.canLog() {
return
}
msg, fatal := fmt.Sprintf(format, v...), false
msg = strings.TrimRight(msg, "\n")
j.writeJLog(msg, fatal)
}
func (j *jsonLogFmt) Println(v ...interface{}) {
if !j.canLog() {
return
}
msg, fatal := fmt.Sprintln(v...), false
msg = strings.TrimRight(msg, "\n")
j.writeJLog(msg, fatal)
}
func (j *jsonLogFmt) Fatal(v ...interface{}) {
msg, fatal := fmt.Sprint(v...), true
msg = strings.TrimRight(msg, "\n")
j.writeJLog(msg, fatal)
os.Exit(1)
}
func (j *jsonLogFmt) Fatalf(format string, v ...interface{}) {
msg, fatal := fmt.Sprintf(format, v...), true
msg = strings.TrimRight(msg, "\n")
j.writeJLog(msg, fatal)
os.Exit(1)
}
func (j *jsonLogFmt) Fatalln(v ...interface{}) {
msg, fatal := fmt.Sprintln(v...), true
msg = strings.TrimRight(msg, "\n")
j.writeJLog(msg, fatal)
os.Exit(1)
}
func NewJSONLogger(out io.Writer, logLevel int) *Logger {
info := &jsonLogFmt{
out: out,
logLevel: logLevel,
logLevelAllowed: LogLevelINFO,
}
warn := &jsonLogFmt{
out: out,
logLevel: logLevel,
logLevelAllowed: LogLevelWARN,
}
err := &jsonLogFmt{
out: out,
logLevel: logLevel,
logLevelAllowed: LogLevelERR,
}
debug := &jsonLogFmt{
out: out,
logLevel: logLevel,
logLevelAllowed: LogLevelDEBUG,
}
return &Logger{
Info: info,
Warn: warn,
Err: err,
Debug: debug,
}
}