-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathlog.go
156 lines (134 loc) · 4.17 KB
/
log.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
package log
import (
"fmt"
"io"
"os"
"path/filepath"
"time"
rotatelogs "github.com/lestrrat-go/file-rotatelogs"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
var defaultLogger = zap.New(zapcore.NewCore(zapcore.NewConsoleEncoder(zap.NewDevelopmentEncoderConfig()), zapcore.AddSync(os.Stdout), zap.DebugLevel))
var SugaredLogger = defaultLogger.Sugar()
var Logger = defaultLogger
// LogConfig 日志配置
type LogConfig struct {
Level string // 日志级别
Path string // 路径
Name string // 文件名称
Console bool // 是否输出到控制台
MaxAge time.Duration // 保存多久的日志,默认15天
RotationTime time.Duration // 多久分割一次日志
Caller bool // 是否打印文件行号
SplitLevel bool // 是否把不同级别的日志打到不同文件
}
var printCaller = false
// Init 初始化日志库
func Init(conf *LogConfig) error {
// 默认保存最近15天日志
if conf.MaxAge == 0 {
conf.MaxAge = time.Hour * 24 * 15
}
if conf.RotationTime == 0 {
conf.RotationTime = time.Hour
}
printCaller = conf.Caller
return newLog(conf)
}
func newLog(conf *LogConfig) error {
// 建立日志目录
if err := os.MkdirAll(conf.Path+"/", os.ModePerm); err != nil {
fmt.Println("init log path error.")
return err
}
// 设置一些基本日志格式 具体含义还比较好理解,直接看zap源码也不难懂
encoder := zapcore.NewConsoleEncoder(zapcore.EncoderConfig{
MessageKey: "msg",
LevelKey: "level",
EncodeLevel: zapcore.CapitalLevelEncoder,
TimeKey: "ts",
EncodeTime: func(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
enc.AppendString(t.Format("2006-01-02 15:04:05.000"))
},
CallerKey: "file",
EncodeCaller: zapcore.ShortCallerEncoder,
EncodeDuration: func(d time.Duration, enc zapcore.PrimitiveArrayEncoder) {
enc.AppendInt64(int64(d) / 1000000)
},
})
level := new(zapcore.Level)
err := level.Set(conf.Level)
if err != nil {
return err
}
lv := *level
cores := []zapcore.Core{}
if conf.SplitLevel {
if lv <= zapcore.DebugLevel {
debugLevel := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
return lvl <= zapcore.DebugLevel
})
debugWriter, err := getWriter(conf.Path+"/"+conf.Name+"_debug", conf)
if err != nil {
return err
}
cores = append(cores, zapcore.NewCore(encoder, zapcore.AddSync(debugWriter), debugLevel))
}
if lv <= zapcore.InfoLevel {
infoLevel := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
return lvl < zapcore.WarnLevel && lvl > zapcore.DebugLevel
})
infoWriter, err := getWriter(conf.Path+"/"+conf.Name+"_info", conf)
if err != nil {
return err
}
cores = append(cores, zapcore.NewCore(encoder, zapcore.AddSync(infoWriter), infoLevel))
}
if lv <= zapcore.WarnLevel {
warnLevel := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
return lvl >= zapcore.WarnLevel
})
warnWriter, err := getWriter(conf.Path+"/"+conf.Name+"_error", conf)
if err != nil {
return err
}
cores = append(cores, zapcore.NewCore(encoder, zapcore.AddSync(warnWriter), warnLevel))
} else {
// 级别是 error 以上
errorLevel := lv
errorWriter, err := getWriter(conf.Path+"/"+conf.Name+"_error", conf)
if err != nil {
return err
}
cores = append(cores, zapcore.NewCore(encoder, zapcore.AddSync(errorWriter), errorLevel))
}
} else {
writer, err := getWriter(conf.Path+"/"+conf.Name, conf)
if err != nil {
return err
}
cores = append(cores, zapcore.NewCore(encoder, zapcore.AddSync(writer), lv))
}
if conf.Console {
consoleWriter := os.Stdout
cores = append(cores, zapcore.NewCore(encoder, zapcore.AddSync(consoleWriter), lv))
}
// 最后创建具体的Logger
core := zapcore.NewTee(cores...)
Logger = zap.New(core)
SugaredLogger = Logger.Sugar()
return nil
}
func getWriter(filename string, conf *LogConfig) (io.Writer, error) {
hook, err := rotatelogs.New(
filename+".%Y-%m-%d/%H.log",
rotatelogs.WithLinkName(filepath.Join(conf.Path, filename+".log")),
rotatelogs.WithMaxAge(conf.MaxAge),
rotatelogs.WithRotationTime(conf.RotationTime),
)
if err != nil {
return nil, err
}
return hook, nil
}