85 lines
1.7 KiB
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
|
|
}
|