log/删除所有的依赖库;

develop
Ge Song 2 years ago
parent 4e1fe211cb
commit 1f39ef8c3a

@ -1,8 +1,3 @@
module git.blauwelle.com/go/crate/log module git.blauwelle.com/go/crate/log
go 1.20 go 1.20
require (
git.blauwelle.com/go/crate/runtimehelper v0.1.0
git.blauwelle.com/go/crate/synchelper v0.1.0
)

@ -1,4 +0,0 @@
git.blauwelle.com/go/crate/runtimehelper v0.1.0 h1:qNhtnt9YmHXNHKsGRbwD3AZ3pezpOwrbmX1o9Bz532I=
git.blauwelle.com/go/crate/runtimehelper v0.1.0/go.mod h1:yVMA0GkO9AS7iuPmalHKeWyv9en0JWj25rY1vpTuHhk=
git.blauwelle.com/go/crate/synchelper v0.1.0 h1:4yEXpshkklaws/57P94xN5bA3NmyyKGcZqYmzd6QIK4=
git.blauwelle.com/go/crate/synchelper v0.1.0/go.mod h1:2JkfH+7sF0Q0wiIaDOqG42ZLO5JxpcMfSoyy7db4Y2g=

@ -4,8 +4,6 @@ import (
"context" "context"
"fmt" "fmt"
"time" "time"
"git.blauwelle.com/go/crate/runtimehelper"
) )
// Entry 包含日志所需的全部中间信息并负责输出日志 // Entry 包含日志所需的全部中间信息并负责输出日志
@ -198,10 +196,10 @@ func (entry Entry) log(ctx context.Context, level Level, message string) {
readonlyEntry.Time = time.Now() readonlyEntry.Time = time.Now()
} }
if newEntry.GetReportCaller() { if newEntry.GetReportCaller() {
readonlyEntry.Caller = runtimehelper.Caller(newEntry.callerSkip) readonlyEntry.Caller = getCaller(newEntry.callerSkip)
} }
if newEntry.GetReportStack() { if newEntry.GetReportStack() {
readonlyEntry.Stack = runtimehelper.Stack(newEntry.callerSkip, 32) readonlyEntry.Stack = getStack(newEntry.callerSkip, 32)
} }
for _, processor := range newEntry.logger.getLevelProcessors(level) { for _, processor := range newEntry.logger.getLevelProcessors(level) {
processor.Process(readonlyEntry) processor.Process(readonlyEntry)
@ -211,8 +209,8 @@ func (entry Entry) log(ctx context.Context, level Level, message string) {
// ReadonlyEntry 是日志系统收集到1条日志记录 // ReadonlyEntry 是日志系统收集到1条日志记录
type ReadonlyEntry struct { type ReadonlyEntry struct {
Context context.Context `json:"-"` Context context.Context `json:"-"`
Caller runtimehelper.Frame Caller Frame
Stack []runtimehelper.Frame Stack []Frame
Time time.Time Time time.Time
Message string Message string
Fields []KV Fields []KV

@ -4,8 +4,6 @@ import (
"io" "io"
"os" "os"
"time" "time"
"git.blauwelle.com/go/crate/synchelper"
) )
// Option 配置日志处理对象 // Option 配置日志处理对象
@ -14,9 +12,9 @@ type Option interface {
} }
// WithBufferPool 配置缓冲池 // WithBufferPool 配置缓冲池
func WithBufferPool(pool synchelper.BytesBufferPool) Option { func WithBufferPool(pool BytesBufferPool) Option {
return optionFunc(func(cfg *config) { return optionFunc(func(cfg *config) {
cfg.pool = pool cfg.bytesBufferPool = pool
cfg.hasPool = true cfg.hasPool = true
}) })
} }
@ -62,10 +60,10 @@ func newConfig(opts ...Option) *config {
opt.apply(cfg) opt.apply(cfg)
} }
if !cfg.hasPool { if !cfg.hasPool {
cfg.pool = synchelper.NewBytesBufferPool(512, 4096) cfg.bytesBufferPool = newBytesBufferPool(512, 4096)
} }
if cfg.output == nil { if cfg.output == nil {
cfg.output = synchelper.NewSyncWriter(os.Stderr) cfg.output = newSyncWriter(os.Stderr)
} }
if cfg.timestampFormat == "" { if cfg.timestampFormat == "" {
cfg.timestampFormat = time.RFC3339Nano cfg.timestampFormat = time.RFC3339Nano
@ -83,7 +81,7 @@ func defaultConfig() *config {
} }
type config struct { type config struct {
pool synchelper.BytesBufferPool bytesBufferPool BytesBufferPool
output io.Writer output io.Writer
timestampFormat string timestampFormat string
hasPool bool hasPool bool

@ -0,0 +1,38 @@
package logjson
import (
"bytes"
"sync"
)
type BytesBufferPool interface {
Get() *bytes.Buffer
Put(buffer *bytes.Buffer)
}
func newBytesBufferPool(initialSize, maximumSize int) *bytesBufferPool {
return &bytesBufferPool{
pool: sync.Pool{
New: func() any {
return bytes.NewBuffer(make([]byte, 0, initialSize))
},
},
maximumSize: maximumSize,
}
}
type bytesBufferPool struct {
pool sync.Pool
maximumSize int
}
func (pool *bytesBufferPool) Get() *bytes.Buffer {
return pool.pool.Get().(*bytes.Buffer)
}
func (pool *bytesBufferPool) Put(buf *bytes.Buffer) {
if buf.Cap() > pool.maximumSize {
return
}
pool.pool.Put(buf)
}

@ -7,8 +7,6 @@ import (
"os" "os"
"git.blauwelle.com/go/crate/log/logsdk" "git.blauwelle.com/go/crate/log/logsdk"
"git.blauwelle.com/go/crate/runtimehelper"
"git.blauwelle.com/go/crate/synchelper"
) )
var _ logsdk.EntryProcessor = &Processor{} var _ logsdk.EntryProcessor = &Processor{}
@ -18,7 +16,7 @@ var _ logsdk.EntryProcessor = &Processor{}
func New(opts ...Option) *Processor { func New(opts ...Option) *Processor {
cfg := newConfig(opts...) cfg := newConfig(opts...)
return &Processor{ return &Processor{
bufferPool: cfg.pool, bytesBufferPool: cfg.bytesBufferPool,
output: cfg.output, output: cfg.output,
timeFormat: cfg.timestampFormat, timeFormat: cfg.timestampFormat,
disableTime: cfg.disableTime, disableTime: cfg.disableTime,
@ -29,7 +27,7 @@ func New(opts ...Option) *Processor {
// Processor 日志处理对象, 把日志处理成 JSON. // Processor 日志处理对象, 把日志处理成 JSON.
type Processor struct { type Processor struct {
bufferPool synchelper.BytesBufferPool bytesBufferPool BytesBufferPool
output io.Writer output io.Writer
timeFormat string timeFormat string
disableTime bool disableTime bool
@ -51,16 +49,16 @@ func (processor *Processor) Process(entry logsdk.ReadonlyEntry) {
if entry.Caller.IsValid() { if entry.Caller.IsValid() {
// 1次分配 // 1次分配
// 直接取 &entry.Caller 会增加堆内存分配 // 直接取 &entry.Caller 会增加堆内存分配
m.Caller = &runtimehelper.Frame{ m.Caller = &logsdk.Frame{
Function: entry.Caller.Function, Function: entry.Caller.Function,
File: entry.Caller.File, File: entry.Caller.File,
Line: entry.Caller.Line, Line: entry.Caller.Line,
} }
} }
buf := processor.bufferPool.Get() buf := processor.bytesBufferPool.Get()
buf.Reset() buf.Reset()
defer processor.bufferPool.Put(buf) defer processor.bytesBufferPool.Put(buf)
encoder := json.NewEncoder(buf) encoder := json.NewEncoder(buf)
if processor.prettyPrint { if processor.prettyPrint {
@ -82,8 +80,8 @@ func (processor *Processor) Process(entry logsdk.ReadonlyEntry) {
type Entry struct { type Entry struct {
Message string `json:"msg"` Message string `json:"msg"`
Time string `json:"time,omitempty"` Time string `json:"time,omitempty"`
Caller *runtimehelper.Frame `json:"caller,omitempty"` Caller *logsdk.Frame `json:"caller,omitempty"`
Stack []runtimehelper.Frame `json:"stack,omitempty"` Stack []logsdk.Frame `json:"stack,omitempty"`
Fields []logsdk.KV `json:"fields,omitempty"` Fields []logsdk.KV `json:"fields,omitempty"`
Level logsdk.Level `json:"level"` Level logsdk.Level `json:"level"`
} }

@ -0,0 +1,24 @@
package logjson
import (
"io"
"sync"
)
func newSyncWriter(writer io.Writer) io.Writer {
return &syncWriter{
writer: writer,
lock: sync.Mutex{},
}
}
type syncWriter struct {
writer io.Writer
lock sync.Mutex
}
func (w *syncWriter) Write(p []byte) (n int, err error) {
w.lock.Lock()
defer w.lock.Unlock()
return w.writer.Write(p)
}

@ -0,0 +1,52 @@
package logsdk
import (
"runtime"
)
// Frame 调用相关信息
type Frame struct {
Function string `json:"func"`
File string `json:"file"`
Line int `json:"line"`
}
// IsValid 表示是否有效
func (frame Frame) IsValid() bool {
return frame.Line > 0
}
func getCaller(skip int) Frame {
pc := make([]uintptr, 1)
n := runtime.Callers(skip+2, pc)
frame, _ := runtime.CallersFrames(pc[:n]).Next()
if frame.PC == 0 {
return Frame{}
}
return Frame{
Function: frame.Function,
File: frame.File,
Line: frame.Line,
}
}
func getStack(skip, maximumFrames int) []Frame {
pc := make([]uintptr, maximumFrames)
n := runtime.Callers(skip+2, pc)
stack := make([]Frame, 0, n)
frames := runtime.CallersFrames(pc[:n])
for {
frame, more := frames.Next()
if frame.PC != 0 {
stack = append(stack, Frame{
Function: frame.Function,
File: frame.File,
Line: frame.Line,
})
}
if !more {
break
}
}
return stack
}
Loading…
Cancel
Save