234 lines
6.2 KiB
Go
234 lines
6.2 KiB
Go
package log
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"time"
|
|
|
|
"go_dreamfactory/lego/utils/pools"
|
|
)
|
|
|
|
func newSys(options *Options) (sys *Logger, err error) {
|
|
hook := LogFileOut{
|
|
Filename: options.FileName, //日志文件路径
|
|
MaxAge: options.MaxAgeTime, //备份日志保存天数
|
|
CupTime: time.Duration(options.CupTimeTime) * time.Hour, //日志切割间隔时间
|
|
Compress: options.Compress, //是否压缩 disabled by default
|
|
MaxBackups: options.MaxBackups, //最大备份数
|
|
LocalTime: true, //使用本地时间
|
|
}
|
|
if !options.IsDebug {
|
|
if err = hook.openNew(); err != nil {
|
|
return
|
|
}
|
|
}
|
|
out := make(writeTree, 0, 2)
|
|
out = append(out, AddSync(&hook))
|
|
if options.IsDebug {
|
|
out = append(out, Lock(os.Stdout))
|
|
}
|
|
sys = &Logger{
|
|
config: NewDefEncoderConfig(),
|
|
formatter: NewConsoleEncoder(),
|
|
out: out,
|
|
level: options.Loglevel,
|
|
addCaller: options.ReportCaller,
|
|
callerSkip: options.CallerSkip,
|
|
addStack: FatalLevel,
|
|
}
|
|
return
|
|
}
|
|
|
|
type Logger struct {
|
|
config *EncoderConfig //编码配置
|
|
level LevelEnabler //日志输出级别
|
|
formatter Formatter //日志格式化
|
|
name string //日志标签
|
|
out IWrite //日志输出
|
|
addCaller LevelEnabler //是否打印堆栈信息
|
|
addStack LevelEnabler //堆栈信息输出级别
|
|
callerSkip int //堆栈输出深度
|
|
}
|
|
|
|
func (this *Logger) Clone(name string, skip int) ILogger {
|
|
return &Logger{
|
|
config: this.config,
|
|
formatter: this.formatter,
|
|
name: name,
|
|
out: this.out,
|
|
level: this.level,
|
|
addCaller: this.addCaller,
|
|
callerSkip: skip,
|
|
addStack: this.addStack,
|
|
}
|
|
}
|
|
func (this *Logger) SetName(name string) {
|
|
this.name = name
|
|
}
|
|
func (this *Logger) Enabled(lvl Loglevel) bool {
|
|
return this.level.Enabled(lvl)
|
|
}
|
|
func (this *Logger) Debug(msg string, args ...Field) {
|
|
this.Log(DebugLevel, msg, args...)
|
|
}
|
|
func (this *Logger) Info(msg string, args ...Field) {
|
|
this.Log(InfoLevel, msg, args...)
|
|
}
|
|
func (this *Logger) Print(msg string, args ...Field) {
|
|
this.Log(InfoLevel, msg, args...)
|
|
}
|
|
func (this *Logger) Warn(msg string, args ...Field) {
|
|
this.Log(WarnLevel, msg, args...)
|
|
}
|
|
func (this *Logger) Error(msg string, args ...Field) {
|
|
this.Log(ErrorLevel, msg, args...)
|
|
}
|
|
func (this *Logger) Panic(msg string, args ...Field) {
|
|
this.Log(PanicLevel, msg, args...)
|
|
}
|
|
func (this *Logger) Fatal(msg string, args ...Field) {
|
|
this.Log(FatalLevel, msg, args...)
|
|
os.Exit(1)
|
|
}
|
|
func (this *Logger) Log(level Loglevel, msg string, args ...Field) {
|
|
if this.level.Enabled(level) {
|
|
this.log(level, msg, args...)
|
|
}
|
|
}
|
|
func (this *Logger) Debugf(format string, args ...interface{}) {
|
|
this.Logf(DebugLevel, format, args...)
|
|
}
|
|
func (this *Logger) Infof(format string, args ...interface{}) {
|
|
this.Logf(InfoLevel, format, args...)
|
|
}
|
|
func (this *Logger) Printf(format string, args ...interface{}) {
|
|
this.Logf(InfoLevel, format, args...)
|
|
}
|
|
func (this *Logger) Warnf(format string, args ...interface{}) {
|
|
this.Logf(WarnLevel, format, args...)
|
|
}
|
|
func (this *Logger) Errorf(format string, args ...interface{}) {
|
|
this.Logf(ErrorLevel, format, args...)
|
|
}
|
|
func (this *Logger) Fatalf(format string, args ...interface{}) {
|
|
this.Logf(FatalLevel, format, args...)
|
|
os.Exit(1)
|
|
}
|
|
func (this *Logger) Panicf(format string, args ...interface{}) {
|
|
this.Logf(PanicLevel, format, args...)
|
|
}
|
|
func (this *Logger) Logf(level Loglevel, format string, args ...interface{}) {
|
|
if this.level.Enabled(level) {
|
|
this.log(level, fmt.Sprintf(format, args...))
|
|
}
|
|
}
|
|
func (this *Logger) Debugln(args ...interface{}) {
|
|
this.Logln(DebugLevel, args...)
|
|
}
|
|
func (this *Logger) Infoln(args ...interface{}) {
|
|
this.Logln(InfoLevel, args...)
|
|
}
|
|
func (this *Logger) Println(args ...interface{}) {
|
|
this.Logln(InfoLevel, args...)
|
|
}
|
|
func (this *Logger) Warnln(args ...interface{}) {
|
|
this.Logln(WarnLevel, args...)
|
|
}
|
|
func (this *Logger) Errorln(args ...interface{}) {
|
|
this.Logln(ErrorLevel, args...)
|
|
}
|
|
func (this *Logger) Fatalln(args ...interface{}) {
|
|
this.Logln(FatalLevel, args...)
|
|
os.Exit(1)
|
|
}
|
|
func (this *Logger) Panicln(args ...interface{}) {
|
|
this.Logln(PanicLevel, args...)
|
|
}
|
|
func (this *Logger) Logln(level Loglevel, args ...interface{}) {
|
|
if this.level.Enabled(level) {
|
|
this.log(level, this.sprintlnn(args...))
|
|
}
|
|
}
|
|
|
|
func (this *Logger) log(level Loglevel, msg string, args ...Field) {
|
|
entry := this.check(level, msg, args...)
|
|
this.write(entry)
|
|
if level <= PanicLevel {
|
|
panic(entry)
|
|
}
|
|
putEntry(entry)
|
|
}
|
|
|
|
func (this *Logger) check(level Loglevel, msg string, args ...Field) (entry *Entry) {
|
|
entry = getEntry()
|
|
entry.Name = this.name
|
|
entry.Time = time.Now()
|
|
entry.Level = level
|
|
entry.Message = msg
|
|
entry.WithFields(args...)
|
|
addStack := this.addStack.Enabled(level)
|
|
addCaller := this.addCaller.Enabled(level)
|
|
if !addCaller && !addStack {
|
|
return
|
|
}
|
|
stackDepth := stacktraceFirst
|
|
if addStack {
|
|
stackDepth = stacktraceFull
|
|
}
|
|
stack := captureStacktrace(this.callerSkip+callerSkipOffset, stackDepth)
|
|
defer stack.Free()
|
|
if stack.Count() == 0 {
|
|
if addCaller {
|
|
if entry.Err != "" {
|
|
entry.Err = entry.Err + ",error: failed to get caller"
|
|
} else {
|
|
entry.Err = "error:failed to get caller"
|
|
}
|
|
}
|
|
return
|
|
}
|
|
frame, more := stack.Next()
|
|
if addCaller {
|
|
entry.Caller.Defined = frame.PC != 0
|
|
entry.Caller.PC = frame.PC
|
|
entry.Caller.File = frame.File
|
|
entry.Caller.Line = frame.Line
|
|
entry.Caller.Function = frame.Function
|
|
entry.Caller.Stack = ""
|
|
}
|
|
if addStack {
|
|
buffer := pools.BufferPoolGet()
|
|
defer buffer.Free()
|
|
stackfmt := newStackFormatter(buffer)
|
|
stackfmt.FormatFrame(frame)
|
|
if more {
|
|
stackfmt.FormatStack(stack)
|
|
}
|
|
entry.Caller.Stack = buffer.String()
|
|
}
|
|
return
|
|
}
|
|
|
|
func (this *Logger) write(entry *Entry) {
|
|
buf, err := this.formatter.Format(this.config, entry)
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err)
|
|
return
|
|
}
|
|
err = this.out.WriteTo(buf.Bytes())
|
|
buf.Free()
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "Failed to obtain write, %v\n", err)
|
|
return
|
|
}
|
|
if entry.Level < ErrorLevel {
|
|
this.out.Sync()
|
|
}
|
|
return
|
|
}
|
|
|
|
func (this *Logger) sprintlnn(args ...interface{}) string {
|
|
msg := fmt.Sprintln(args...)
|
|
return msg[:len(msg)-1]
|
|
}
|