1 Star 1 Fork 2

allan577 / go-lib-logger

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
log.go 17.52 KB
一键复制 编辑 原始数据 按行查看 历史
allan577 提交于 2021-04-11 21:26 . init
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574
package logger
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"os"
"sync"
"time"
"gitee.com/allan577/go-lib-logger/internal"
)
// Log interface defines an extensible log.
type Log interface {
// Name returns the logger name.
Name() string
// WithField adds the given extended data to the log.
WithField(string, interface{}) Log
// WithError adds the given error to the log.
// This method is relative to WithField("error", error).
WithError(error) Log
// WithFields adds the given multiple extended data to the log.
WithFields(map[string]interface{}) Log
// WithContext adds the given context to the log.
WithContext(context.Context) Log
// WithCaller forces the caller report of the current log to be enabled.
WithCaller(...int) Log
// Log uses the given parameters to record a log of the specified level.
// If the given log level is PanicLevel, the given panic function will be
// called automatically after logging is completed.
// If the given log level is FatalLevel, the given exit function will be
// called automatically after logging is completed.
// If the given log level is invalid, the log will be discarded.
Log(Level, ...interface{})
// Logln uses the given parameters to record a log of the specified level.
// If the given log level is PanicLevel, the given panic function will be
// called automatically after logging is completed.
// If the given log level is FatalLevel, the given exit function will be
// called automatically after logging is completed.
// If the given log level is invalid, the log will be discarded.
Logln(Level, ...interface{})
// Logf uses the given parameters to record a log of the specified level.
// If the given log level is PanicLevel, the given panic function will be
// called automatically after logging is completed.
// If the given log level is FatalLevel, the given exit function will be
// called automatically after logging is completed.
// If the given log level is invalid, the log will be discarded.
Logf(Level, string, ...interface{})
// Trace uses the given parameters to record a TraceLevel log.
Trace(...interface{})
// Traceln uses the given parameters to record a TraceLevel log.
Traceln(...interface{})
// Tracef uses the given parameters to record a TraceLevel log.
Tracef(string, ...interface{})
// Print uses the given parameters to record a TraceLevel log.
Print(...interface{})
// Println uses the given parameters to record a TraceLevel log.
Println(...interface{})
// Printf uses the given parameters to record a TraceLevel log.
Printf(string, ...interface{})
// Debug uses the given parameters to record a DebugLevel log.
Debug(...interface{})
// Debugln uses the given parameters to record a DebugLevel log.
Debugln(...interface{})
// Debugf uses the given parameters to record a DebugLevel log.
Debugf(string, ...interface{})
// Info uses the given parameters to record a InfoLevel log.
Info(...interface{})
// Infoln uses the given parameters to record a InfoLevel log.
Infoln(...interface{})
// Infof uses the given parameters to record a InfoLevel log.
Infof(string, ...interface{})
// Echo uses the given parameters to record a InfoLevel log.
Echo(...interface{})
// Echoln uses the given parameters to record a InfoLevel log.
Echoln(...interface{})
// Echof uses the given parameters to record a InfoLevel log.
Echof(string, ...interface{})
// Warn uses the given parameters to record a WarnLevel log.
Warn(...interface{})
// Warnln uses the given parameters to record a WarnLevel log.
Warnln(...interface{})
// Warnf uses the given parameters to record a WarnLevel log.
Warnf(string, ...interface{})
// Warning uses the given parameters to record a WarnLevel log.
Warning(...interface{})
// Warningln uses the given parameters to record a WarnLevel log.
Warningln(...interface{})
// Warningln uses the given parameters to record a WarnLevel log.
Warningf(string, ...interface{})
// Error uses the given parameters to record a ErrorLevel log.
Error(...interface{})
// Errorln uses the given parameters to record a ErrorLevel log.
Errorln(...interface{})
// Errorf uses the given parameters to record a ErrorLevel log.
Errorf(string, ...interface{})
// Fatal uses the given parameters to record a FatalLevel log.
// After the log record is completed, the system will automatically call
// the exit function given in advance.
Fatal(...interface{})
// Fatalln uses the given parameters to record a FatalLevel log.
// After the log record is completed, the system will automatically call
// the exit function given in advance.
Fatalln(...interface{})
// Fatalf uses the given parameters to record a FatalLevel log.
// After the log record is completed, the system will automatically call
// the exit function given in advance.
Fatalf(string, ...interface{})
// Panic uses the given parameters to record a PanicLevel log.
// After the log record is completed, the system will automatically call
// the panic function given in advance.
Panic(...interface{})
// Panicln uses the given parameters to record a PanicLevel log.
// After the log record is completed, the system will automatically call
// the panic function given in advance.
Panicln(...interface{})
// Panicf uses the given parameters to record a PanicLevel log.
// After the log record is completed, the system will automatically call
// the panic function given in advance.
Panicf(string, ...interface{})
}
// The core type defines the collection of shared attributes within the log,
// and each independent Logger shares the same core instance.
type core struct {
name string
level Level
formatter Formatter
writer io.Writer
levelWriter map[Level]io.Writer
pool sync.Pool
hooks HookBag
timeFormat string
nowFunc func() time.Time
exitFunc func(int)
panicFunc func(string)
caller *internal.CallerReporter
levelCaller map[Level]*internal.CallerReporter
}
// Create a new core instance and bind the logger name.
func newCore(name string) *core {
return &core{
name: name,
level: TraceLevel,
writer: os.Stdout,
levelWriter: make(map[Level]io.Writer),
pool: sync.Pool{New: func() interface{} { return new(logEntity) }},
hooks: NewHookBag(),
timeFormat: internal.DefaultTimeFormat,
nowFunc: internal.DefaultNowFunc,
exitFunc: internal.DefaultExitFunc,
panicFunc: internal.DefaultPanicFunc,
levelCaller: make(map[Level]*internal.CallerReporter),
}
}
// Get a log entity from the pool and initialize it.
func (c *core) getEntity(l *log, level Level, message, caller string) *logEntity {
o := c.pool.Get().(*logEntity)
o.name = c.name
o.time = c.nowFunc()
o.timeFormat = c.timeFormat
o.level = level
o.message = message
o.fields = l.fields
o.ctx = l.ctx
o.caller = caller
return o
}
// Clean up and recycle the given log entity.
func (c *core) putEntity(o *logEntity) {
// If the log size exceeds 1KB, we need to discard this buffer to
// free memory faster.
if o.buffer.Cap() > 1024 {
o.buffer = bytes.Buffer{}
} else {
o.buffer.Reset()
}
o.name = ""
o.timeFormat = ""
o.message = ""
o.fields = nil
o.ctx = nil
o.caller = ""
c.pool.Put(o)
}
// Internal implementation of the Log interface.
type log struct {
core *core
ctx context.Context
fields internal.Fields
caller *internal.CallerReporter
}
// Name returns the logger name.
func (o *log) Name() string {
return o.core.name
}
// WithField adds the given extended data to the log.
func (o *log) WithField(key string, value interface{}) Log {
r := &log{core: o.core, fields: o.fields.Clone(1), ctx: o.ctx, caller: o.caller}
r.fields[key] = value
return r
}
// WithError adds the given error to the log.
// This method is relative to WithField("error", error).
func (o *log) WithError(err error) Log {
return o.WithField("error", err)
}
// WithFields adds the given multiple extended data to the log.
func (o *log) WithFields(fields map[string]interface{}) Log {
return &log{core: o.core, fields: o.fields.With(fields), ctx: o.ctx, caller: o.caller}
}
// WithContext adds the given context to the log.
func (o *log) WithContext(ctx context.Context) Log {
return &log{core: o.core, fields: o.fields.Clone(0), ctx: ctx, caller: o.caller}
}
// WithCaller forces the caller report of the current log to be enabled.
func (o *log) WithCaller(skip ...int) Log {
var n int
if len(skip) > 0 && skip[0] > 0 {
n = skip[0]
}
// If the caller is equaled, we don't need to create a new log instance.
if o.caller != nil && o.caller.Equal(n) {
return o
}
return &log{core: o.core, fields: o.fields.Clone(0), ctx: o.ctx, caller: internal.NewCallerReporter(n)}
}
// Format and record the current log.
func (o *log) record(level Level, message string) {
entity := o.core.getEntity(o, level, message, o.getCaller(level))
defer o.core.putEntity(entity)
if err := o.format(entity); err != nil {
// When the format log fails, we terminate the logging and report the error.
internal.EchoError("Failed to format log: %s", err)
} else {
err = o.core.hooks.Fire(entity)
if err != nil {
internal.EchoError("Failed to fire log hook: %s", err)
}
err = o.write(entity)
if err != nil {
internal.EchoError("Failed to write log: %s", err)
}
}
if level < ErrorLevel {
switch level {
case FatalLevel:
o.core.exitFunc(1)
case PanicLevel:
o.core.panicFunc(message)
}
}
}
// Format the current log.
func (o *log) format(entity *logEntity) error {
if formatter := o.core.formatter; formatter != nil {
return formatter.Format(entity, &entity.buffer)
}
kv := map[string]interface{}{
"name": entity.name,
"time": entity.TimeString(),
"level": entity.level.String(),
"message": entity.message,
}
if len(o.fields) > 0 {
kv["fields"] = internal.StandardiseFieldsForJSONEncoder(o.fields)
}
if entity.caller != "" {
kv["caller"] = entity.caller
}
return json.NewEncoder(&entity.buffer).Encode(kv)
}
// Write the current log.
func (o *log) write(entity *logEntity) (err error) {
if writer, found := o.core.levelWriter[entity.level]; found && writer != nil {
_, err = writer.Write(entity.Bytes())
} else {
_, err = o.core.writer.Write(entity.Bytes())
}
return
}
// Get the caller report. If caller reporting is not enabled in the current
// log, an empty string is always returned.
func (o *log) getCaller(level Level) string {
if o.caller != nil {
return o.caller.GetCaller()
}
if caller, found := o.core.levelCaller[level]; found {
return caller.GetCaller()
}
if o.core.caller != nil {
return o.core.caller.GetCaller()
}
return ""
}
// Log uses the given parameters to record a log of the specified level.
// If the given log level is PanicLevel, the given panic function will be
// called automatically after logging is completed.
// If the given log level is FatalLevel, the given exit function will be
// called automatically after logging is completed.
// If the given log level is invalid, the log will be discarded.
func (o *log) Log(level Level, args ...interface{}) {
o.log(level, fmt.Sprint(args...))
}
// Uses the given parameters to record a log of the specified level.
func (o *log) log(level Level, args ...interface{}) {
if !o.core.level.IsEnabled(level) {
return
}
o.record(level, fmt.Sprint(args...))
}
// Logln uses the given parameters to record a log of the specified level.
// If the given log level is PanicLevel, the given panic function will be
// called automatically after logging is completed.
// If the given log level is FatalLevel, the given exit function will be
// called automatically after logging is completed.
// If the given log level is invalid, the log will be discarded.
func (o *log) Logln(level Level, args ...interface{}) {
o.logln(level, args...)
}
// Uses the given parameters to record a log of the specified level.
func (o *log) logln(level Level, args ...interface{}) {
if !o.core.level.IsEnabled(level) {
return
}
s := fmt.Sprintln(args...)
o.record(level, s[:len(s)-1])
}
// Logf uses the given parameters to record a log of the specified level.
// If the given log level is PanicLevel, the given panic function will be
// called automatically after logging is completed.
// If the given log level is FatalLevel, the given exit function will be
// called automatically after logging is completed.
// If the given log level is invalid, the log will be discarded.
func (o *log) Logf(level Level, format string, args ...interface{}) {
o.logf(level, format, args...)
}
// Uses the given parameters to record a log of the specified level.
func (o *log) logf(level Level, format string, args ...interface{}) {
if !o.core.level.IsEnabled(level) {
return
}
o.record(level, fmt.Sprintf(format, args...))
}
// Trace uses the given parameters to record a TraceLevel log.
func (o *log) Trace(args ...interface{}) {
o.log(TraceLevel, args...)
}
// Traceln uses the given parameters to record a TraceLevel log.
func (o *log) Traceln(args ...interface{}) {
o.logln(TraceLevel, args...)
}
// Tracef uses the given parameters to record a TraceLevel log.
func (o *log) Tracef(format string, args ...interface{}) {
o.logf(TraceLevel, format, args...)
}
// Print uses the given parameters to record a TraceLevel log.
func (o *log) Print(args ...interface{}) {
o.log(TraceLevel, args...)
}
// Println uses the given parameters to record a TraceLevel log.
func (o *log) Println(args ...interface{}) {
o.logln(TraceLevel, args...)
}
// Printf uses the given parameters to record a TraceLevel log.
func (o *log) Printf(format string, args ...interface{}) {
o.logf(TraceLevel, format, args...)
}
// Debug uses the given parameters to record a DebugLevel log.
func (o *log) Debug(args ...interface{}) {
o.log(DebugLevel, args...)
}
// Debugln uses the given parameters to record a DebugLevel log.
func (o *log) Debugln(args ...interface{}) {
o.logln(DebugLevel, args...)
}
// Debugf uses the given parameters to record a DebugLevel log.
func (o *log) Debugf(format string, args ...interface{}) {
o.logf(DebugLevel, format, args...)
}
// Info uses the given parameters to record a InfoLevel log.
func (o *log) Info(args ...interface{}) {
o.log(InfoLevel, args...)
}
// Infoln uses the given parameters to record a InfoLevel log.
func (o *log) Infoln(args ...interface{}) {
o.logln(InfoLevel, args...)
}
// Infof uses the given parameters to record a InfoLevel log.
func (o *log) Infof(format string, args ...interface{}) {
o.logf(InfoLevel, format, args...)
}
// Echo uses the given parameters to record a InfoLevel log.
func (o *log) Echo(args ...interface{}) {
o.log(InfoLevel, args...)
}
// Echoln uses the given parameters to record a InfoLevel log.
func (o *log) Echoln(args ...interface{}) {
o.logln(InfoLevel, args...)
}
// Echof uses the given parameters to record a InfoLevel log.
func (o *log) Echof(format string, args ...interface{}) {
o.logf(InfoLevel, format, args...)
}
// Warn uses the given parameters to record a WarnLevel log.
func (o *log) Warn(args ...interface{}) {
o.log(WarnLevel, args...)
}
// Warnln uses the given parameters to record a WarnLevel log.
func (o *log) Warnln(args ...interface{}) {
o.logln(WarnLevel, args...)
}
// Warnf uses the given parameters to record a WarnLevel log.
func (o *log) Warnf(format string, args ...interface{}) {
o.logf(WarnLevel, format, args...)
}
// Warning uses the given parameters to record a WarnLevel log.
func (o *log) Warning(args ...interface{}) {
o.log(WarnLevel, args...)
}
// Warningln uses the given parameters to record a WarnLevel log.
func (o *log) Warningln(args ...interface{}) {
o.logln(WarnLevel, args...)
}
// Warningf uses the given parameters to record a WarnLevel log.
func (o *log) Warningf(format string, args ...interface{}) {
o.logf(WarnLevel, format, args...)
}
// Error uses the given parameters to record a ErrorLevel log.
func (o *log) Error(args ...interface{}) {
o.log(ErrorLevel, args...)
}
// Errorln uses the given parameters to record a ErrorLevel log.
func (o *log) Errorln(args ...interface{}) {
o.logln(ErrorLevel, args...)
}
// Errorf uses the given parameters to record a ErrorLevel log.
func (o *log) Errorf(format string, args ...interface{}) {
o.logf(ErrorLevel, format, args...)
}
// Fatal uses the given parameters to record a FatalLevel log.
// After the log record is completed, the system will automatically call
// the exit function given in advance.
func (o *log) Fatal(args ...interface{}) {
o.log(FatalLevel, args...)
}
// Fatalln uses the given parameters to record a FatalLevel log.
// After the log record is completed, the system will automatically call
// the exit function given in advance.
func (o *log) Fatalln(args ...interface{}) {
o.logln(FatalLevel, args...)
}
// Fatalf uses the given parameters to record a FatalLevel log.
// After the log record is completed, the system will automatically call
// the exit function given in advance.
func (o *log) Fatalf(format string, args ...interface{}) {
o.logf(FatalLevel, format, args...)
}
// Panic uses the given parameters to record a PanicLevel log.
// After the log record is completed, the system will automatically call
// the panic function given in advance.
func (o *log) Panic(args ...interface{}) {
o.log(PanicLevel, args...)
}
// Panicln uses the given parameters to record a PanicLevel log.
// After the log record is completed, the system will automatically call
// the panic function given in advance.
func (o *log) Panicln(args ...interface{}) {
o.logln(PanicLevel, args...)
}
// Panicf uses the given parameters to record a PanicLevel log.
// After the log record is completed, the system will automatically call
// the panic function given in advance.
func (o *log) Panicf(format string, args ...interface{}) {
o.logf(PanicLevel, format, args...)
}
1
https://gitee.com/allan577/go-lib-logger.git
git@gitee.com:allan577/go-lib-logger.git
allan577
go-lib-logger
go-lib-logger
v1.0.0

搜索帮助