log/删除所有的依赖库;
This commit is contained in:
@@ -1,8 +1,3 @@
|
||||
module git.blauwelle.com/go/crate/log
|
||||
|
||||
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"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"git.blauwelle.com/go/crate/runtimehelper"
|
||||
)
|
||||
|
||||
// Entry 包含日志所需的全部中间信息并负责输出日志
|
||||
@@ -198,10 +196,10 @@ func (entry Entry) log(ctx context.Context, level Level, message string) {
|
||||
readonlyEntry.Time = time.Now()
|
||||
}
|
||||
if newEntry.GetReportCaller() {
|
||||
readonlyEntry.Caller = runtimehelper.Caller(newEntry.callerSkip)
|
||||
readonlyEntry.Caller = getCaller(newEntry.callerSkip)
|
||||
}
|
||||
if newEntry.GetReportStack() {
|
||||
readonlyEntry.Stack = runtimehelper.Stack(newEntry.callerSkip, 32)
|
||||
readonlyEntry.Stack = getStack(newEntry.callerSkip, 32)
|
||||
}
|
||||
for _, processor := range newEntry.logger.getLevelProcessors(level) {
|
||||
processor.Process(readonlyEntry)
|
||||
@@ -211,8 +209,8 @@ func (entry Entry) log(ctx context.Context, level Level, message string) {
|
||||
// ReadonlyEntry 是日志系统收集到1条日志记录
|
||||
type ReadonlyEntry struct {
|
||||
Context context.Context `json:"-"`
|
||||
Caller runtimehelper.Frame
|
||||
Stack []runtimehelper.Frame
|
||||
Caller Frame
|
||||
Stack []Frame
|
||||
Time time.Time
|
||||
Message string
|
||||
Fields []KV
|
||||
|
||||
@@ -4,8 +4,6 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"git.blauwelle.com/go/crate/synchelper"
|
||||
)
|
||||
|
||||
// Option 配置日志处理对象
|
||||
@@ -14,9 +12,9 @@ type Option interface {
|
||||
}
|
||||
|
||||
// WithBufferPool 配置缓冲池
|
||||
func WithBufferPool(pool synchelper.BytesBufferPool) Option {
|
||||
func WithBufferPool(pool BytesBufferPool) Option {
|
||||
return optionFunc(func(cfg *config) {
|
||||
cfg.pool = pool
|
||||
cfg.bytesBufferPool = pool
|
||||
cfg.hasPool = true
|
||||
})
|
||||
}
|
||||
@@ -62,10 +60,10 @@ func newConfig(opts ...Option) *config {
|
||||
opt.apply(cfg)
|
||||
}
|
||||
if !cfg.hasPool {
|
||||
cfg.pool = synchelper.NewBytesBufferPool(512, 4096)
|
||||
cfg.bytesBufferPool = newBytesBufferPool(512, 4096)
|
||||
}
|
||||
if cfg.output == nil {
|
||||
cfg.output = synchelper.NewSyncWriter(os.Stderr)
|
||||
cfg.output = newSyncWriter(os.Stderr)
|
||||
}
|
||||
if cfg.timestampFormat == "" {
|
||||
cfg.timestampFormat = time.RFC3339Nano
|
||||
@@ -83,7 +81,7 @@ func defaultConfig() *config {
|
||||
}
|
||||
|
||||
type config struct {
|
||||
pool synchelper.BytesBufferPool
|
||||
bytesBufferPool BytesBufferPool
|
||||
output io.Writer
|
||||
timestampFormat string
|
||||
hasPool bool
|
||||
|
||||
38
log/logsdk/logjson/pool.go
Normal file
38
log/logsdk/logjson/pool.go
Normal file
@@ -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"
|
||||
|
||||
"git.blauwelle.com/go/crate/log/logsdk"
|
||||
"git.blauwelle.com/go/crate/runtimehelper"
|
||||
"git.blauwelle.com/go/crate/synchelper"
|
||||
)
|
||||
|
||||
var _ logsdk.EntryProcessor = &Processor{}
|
||||
@@ -18,7 +16,7 @@ var _ logsdk.EntryProcessor = &Processor{}
|
||||
func New(opts ...Option) *Processor {
|
||||
cfg := newConfig(opts...)
|
||||
return &Processor{
|
||||
bufferPool: cfg.pool,
|
||||
bytesBufferPool: cfg.bytesBufferPool,
|
||||
output: cfg.output,
|
||||
timeFormat: cfg.timestampFormat,
|
||||
disableTime: cfg.disableTime,
|
||||
@@ -29,7 +27,7 @@ func New(opts ...Option) *Processor {
|
||||
|
||||
// Processor 日志处理对象, 把日志处理成 JSON.
|
||||
type Processor struct {
|
||||
bufferPool synchelper.BytesBufferPool
|
||||
bytesBufferPool BytesBufferPool
|
||||
output io.Writer
|
||||
timeFormat string
|
||||
disableTime bool
|
||||
@@ -51,16 +49,16 @@ func (processor *Processor) Process(entry logsdk.ReadonlyEntry) {
|
||||
if entry.Caller.IsValid() {
|
||||
// 1次分配
|
||||
// 直接取 &entry.Caller 会增加堆内存分配
|
||||
m.Caller = &runtimehelper.Frame{
|
||||
m.Caller = &logsdk.Frame{
|
||||
Function: entry.Caller.Function,
|
||||
File: entry.Caller.File,
|
||||
Line: entry.Caller.Line,
|
||||
}
|
||||
}
|
||||
|
||||
buf := processor.bufferPool.Get()
|
||||
buf := processor.bytesBufferPool.Get()
|
||||
buf.Reset()
|
||||
defer processor.bufferPool.Put(buf)
|
||||
defer processor.bytesBufferPool.Put(buf)
|
||||
|
||||
encoder := json.NewEncoder(buf)
|
||||
if processor.prettyPrint {
|
||||
@@ -80,10 +78,10 @@ func (processor *Processor) Process(entry logsdk.ReadonlyEntry) {
|
||||
|
||||
// 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"`
|
||||
Message string `json:"msg"`
|
||||
Time string `json:"time,omitempty"`
|
||||
Caller *logsdk.Frame `json:"caller,omitempty"`
|
||||
Stack []logsdk.Frame `json:"stack,omitempty"`
|
||||
Fields []logsdk.KV `json:"fields,omitempty"`
|
||||
Level logsdk.Level `json:"level"`
|
||||
}
|
||||
|
||||
24
log/logsdk/logjson/writer.go
Normal file
24
log/logsdk/logjson/writer.go
Normal file
@@ -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)
|
||||
}
|
||||
52
log/logsdk/runtime.go
Normal file
52
log/logsdk/runtime.go
Normal file
@@ -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
|
||||
}
|
||||
Reference in New Issue
Block a user