Vestmore_GO/utils/log/json_format.go

85 lines
1.7 KiB
Go

package log
import (
"bytes"
"encoding/json"
"fmt"
"runtime"
"strings"
"sync"
"time"
"github.com/sirupsen/logrus"
)
type levelSkip struct {
Skip int
Once sync.Once
}
// JSONFormatter formats logs into parsable json
type JSONFormatter struct {
diffSkip int
skip []*levelSkip
once sync.Once
}
// Format renders a single log entry
func (h *JSONFormatter) Format(e *logrus.Entry) ([]byte, error) {
skipOnce := h.skip[int(e.Level)]
skipOnce.Once.Do(func() {
for i := 4; i < 100; i++ {
// log.Println(i)
if pc, _, _, ok := runtime.Caller(i); ok {
funcStruct := runtime.FuncForPC(pc)
// log.Println(funcStruct.Name(), file, line)
if !strings.Contains(funcStruct.Name(), "github.com/sirupsen/logrus.") {
skipOnce.Skip++
if skipOnce.Skip >= 2 {
skipOnce.Skip = i - 3
break
}
}
} else {
break
}
}
})
var fileinfo string
if _, file, line, ok := runtime.Caller(skipOnce.Skip + h.diffSkip); ok {
if e.Level == logrus.InfoLevel {
fileinfo = fmt.Sprintf("%s:%d", file, line)
} else {
ps := strings.Split(file, "/")
fileinfo = fmt.Sprintf("%s:%d", strings.Join(ps, "/"), line)
}
}
var Data map[string]any = make(map[string]any, 4)
Data[logrus.FieldKeyTime] = e.Time.Format(time.RFC3339)
Data[logrus.FieldKeyMsg] = e.Message
Data[logrus.FieldKeyLevel] = e.Level
Data[logrus.FieldKeyFile] = fileinfo
var b *bytes.Buffer
if e.Buffer != nil {
b = e.Buffer
} else {
b = &bytes.Buffer{}
}
encoder := json.NewEncoder(b)
encoder.SetEscapeHTML(false)
if err := encoder.Encode(Data); err != nil {
return nil, fmt.Errorf("failed to marshal fields to JSON, %w", err)
}
return b.Bytes(), nil
}