1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
| package log
import ( "fmt" "strings"
"github.com/pkg/errors" "github.com/samber/lo" "go.uber.org/zap/buffer" "go.uber.org/zap/zapcore"
"{{{ .Package }}}/app/util" )
const timeFormat = "15:04:05.000000"
type customEncoder struct { zapcore.Encoder colored bool pool buffer.Pool }
func newEncoder(cfg zapcore.EncoderConfig, colored bool) *customEncoder { return &customEncoder{Encoder: zapcore.NewJSONEncoder(cfg), colored: colored, pool: buffer.NewPool()} }
func (e *customEncoder) Clone() zapcore.Encoder { return &customEncoder{Encoder: e.Encoder.Clone(), colored: e.colored, pool: e.pool} }
func (e *customEncoder) EncodeEntry(entry zapcore.Entry, fields []zapcore.Field) (*buffer.Buffer, error) { go func() { recentMU.Lock() defer recentMU.Unlock() RecentLogs = append(RecentLogs, &entry) if len(RecentLogs) > 50 { RecentLogs = RecentLogs[1:] } }() b, err := e.Encoder.EncodeEntry(entry, fields) if err != nil { return nil, errors.Wrap(err, "logging error") } out := b.Bytes() b.Free()
data, err := util.FromJSONMap(out) if err != nil { return nil, errors.Wrap(err, "can't parse logging JSON") }
ret := e.pool.Get() ret.AppendByte('\n') addLine := func(l string) { ret.AppendString(l) ret.AppendByte('\n') }
lvl := fmt.Sprintf("%-5v", entry.Level.CapitalString()) if e.colored { lvl = levelToColor[entry.Level.String()].Add(lvl) } tm := entry.Time.Format(timeFormat)
msg := entry.Message var msgLines []string if strings.Contains(msg, "\n") { msgLines = util.StringSplitLines(msg) msg = msgLines[0] msgLines = msgLines[1:] }
if e.colored { addLine(fmt.Sprintf("[%s] %s %s", lvl, tm, Cyan.Add(msg))) } else { addLine(fmt.Sprintf("[%s] %s %s", lvl, tm, msg)) }
lo.ForEach(msgLines, func(ml string, _ int) { if e.colored { if strings.Contains(ml, util.AppKey) { ml = Green.Add(ml) } addLine(" " + Cyan.Add(ml)) } else { addLine(" " + ml) } }) if len(data) > 0 { addLine(" " + util.ToJSONCompact(data)) } caller := entry.Caller.String() if entry.Caller.Function != "" { caller += " (" + entry.Caller.Function + ")" } addLine(" " + caller)
if entry.Stack != "" { st := util.StringSplitLines(entry.Stack) lo.ForEach(st, func(stl string, _ int) { if strings.Contains(stl, util.AppKey) { stl = Green.Add(stl) } addLine(" " + stl) }) } return ret, nil }
|