You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
crate/log/logsdk/logjson/processor.go

90 lines
2.3 KiB
Go

package logjson
import (
"encoding/json"
"fmt"
"io"
"os"
"git.blauwelle.com/go/crate/log/logsdk"
"git.blauwelle.com/go/crate/runtimehelper"
"git.blauwelle.com/go/crate/synchelper"
)
var _ logsdk.EntryProcessor = &Processor{}
// New 返回日志处理对象,
// 返回的对象是 [logsdk.EntryProcessor].
func New(opts ...Option) *Processor {
cfg := newConfig(opts...)
return &Processor{
bufferPool: cfg.pool,
output: cfg.output,
timeFormat: cfg.timestampFormat,
disableTime: cfg.disableTime,
disableHTMLEscape: cfg.disableHTMLEscape,
prettyPrint: cfg.prettyPrint,
}
}
// Processor 日志处理对象, 把日志处理成 JSON.
type Processor struct {
bufferPool synchelper.BytesBufferPool
output io.Writer
timeFormat string
disableTime bool
disableHTMLEscape bool
prettyPrint bool
}
// Process 处理日志
func (processor *Processor) Process(entry logsdk.ReadonlyEntry) {
m := Entry{
Stack: entry.Stack,
Fields: entry.Fields,
Level: entry.Level,
Message: entry.Message,
}
if !processor.disableTime {
m.Time = entry.Time.Format(processor.timeFormat) // 1次分配
}
if entry.Caller.IsValid() {
// 1次分配
// 直接取 &entry.Caller 会增加堆内存分配
m.Caller = &runtimehelper.Frame{
Function: entry.Caller.Function,
File: entry.Caller.File,
Line: entry.Caller.Line,
}
}
buf := processor.bufferPool.Get()
buf.Reset()
defer processor.bufferPool.Put(buf)
encoder := json.NewEncoder(buf)
if processor.prettyPrint {
encoder.SetIndent("", " ")
}
encoder.SetEscapeHTML(!processor.disableHTMLEscape)
// Encode 2次分配
if err := encoder.Encode(m); err != nil {
_, _ = fmt.Fprintf(os.Stderr, "JSON processor cannot encode log %#v: %s\n", m, err.Error())
}
if _, err := buf.WriteTo(processor.output); err != nil {
_, _ = fmt.Fprintf(os.Stderr, "JSON processor cannot write log: %s\n", err.Error())
}
}
// Entry 被用来 JSON 序列化
type Entry struct {
Message string `json:"msg"`
Time string `json:"time,omitempty"`
Caller *runtimehelper.Frame `json:"caller,omitempty"`
Stack []runtimehelper.Frame `json:"stack,omitempty"`
Fields []logsdk.KV `json:"fields,omitempty"`
Level logsdk.Level `json:"level"`
}