拆分logger库

This commit is contained in:
白茶清欢 2022-05-14 13:04:01 +08:00
parent 90239ac34f
commit 941e7a1871
9 changed files with 1189 additions and 1 deletions

2
README.md Normal file
View File

@ -0,0 +1,2 @@
# go-logger
基于zap log的包装,方便引入使用

427
config.go Normal file
View File

@ -0,0 +1,427 @@
// Package logger...
//
// Description : config 日志配置
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2021-01-02 3:07 下午
package logger
import (
"fmt"
"os"
"strings"
"time"
"go.uber.org/zap/zapcore"
)
// TimeIntervalType 日志时间间隔类型
type TimeIntervalType uint
const (
// TimeIntervalTypeMinute 按分钟切割
TimeIntervalTypeMinute = TimeIntervalType(0)
// TimeIntervalTypeHour 按小时切割
TimeIntervalTypeHour = TimeIntervalType(1)
// TimeIntervalTypeDay 按天切割
TimeIntervalTypeDay = TimeIntervalType(2)
// TimeIntervalTypeMonth 按月切割
TimeIntervalTypeMonth = TimeIntervalType(3)
// TimeIntervalTypeYear 按年切割
TimeIntervalTypeYear = TimeIntervalType(4)
)
const (
// DefaultDivisionChar 默认的时间格式分隔符
DefaultDivisionChar = "-"
)
// RotateLogConfig 日志切割的配置
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 3:08 下午 2021/1/2
type RotateLogConfig struct {
TimeIntervalType TimeIntervalType `json:"time_interval_type" yaml:"time_interval_type"` // 日志切割的时间间隔类型 0 - 小时 1 - 天 2 - 月 3 - 年
TimeInterval time.Duration `json:"time_interval" yaml:"time_interval"` // 日志切割的时间间隔
LogPath string `json:"log_path" yaml:"log_path"` // 存储日志的路径
LogFileName string `json:"log_file_name" yaml:"log_file_name"` // 日志文件名
DivisionChar string `json:"division_char" yaml:"division_char"` // 日志文件拼时间分隔符
FullLogFormat string `json:"full_log_format" yaml:"full_log_format"` // 完整的日志格式
MaxAge time.Duration `json:"max_age" yaml:"max_age"` // 日志最长保存时间
}
// SetRotateLogConfigFunc 设置日志切割的选项
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 3:13 下午 2021/1/2
type SetRotateLogConfigFunc func(rlc *RotateLogConfig)
// WithTimeIntervalType 设置日志切割时间间隔
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 3:34 下午 2021/1/2
func WithTimeIntervalType(timeIntervalType TimeIntervalType) SetRotateLogConfigFunc {
return func(rlc *RotateLogConfig) {
rlc.TimeIntervalType = timeIntervalType
}
}
// WithDivisionChar 设置分隔符
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 3:49 下午 2021/1/2
func WithDivisionChar(divisionChar string) SetRotateLogConfigFunc {
return func(rlc *RotateLogConfig) {
rlc.DivisionChar = divisionChar
}
}
// WithMaxAge 设置日志保存时间
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 5:03 下午 2021/1/2
func WithMaxAge(maxAge time.Duration) SetRotateLogConfigFunc {
return func(rlc *RotateLogConfig) {
rlc.MaxAge = maxAge
}
}
// NewRotateLogConfig 生成日志切割的配置
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 3:53 下午 2021/1/2
func NewRotateLogConfig(logPath string, logFile string, option ...SetRotateLogConfigFunc) (*RotateLogConfig, error) {
if len(logPath) == 0 || len(logFile) == 0 {
return nil, LogPathEmptyError()
}
c := &RotateLogConfig{
TimeIntervalType: TimeIntervalTypeHour,
LogPath: logPath,
LogFileName: logFile,
DivisionChar: "",
}
for _, o := range option {
o(c)
}
if err := formatConfig(c); nil != err {
return nil, err
}
return c, nil
}
// formatConfig 格式化配置
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 4:23 下午 2021/1/2
func formatConfig(c *RotateLogConfig) error {
if len(c.DivisionChar) == 0 {
c.DivisionChar = DefaultDivisionChar
}
// 格式化路径
logPathByte := []byte(c.LogPath)
if string(logPathByte[len(logPathByte)-1]) != "/" {
c.LogPath = c.LogPath + "/"
}
// 检测路径是否存在,不存在自动创建
if _, err := os.Stat(c.LogPath); nil != err {
if !os.IsNotExist(err) {
// 异常不是路径不存在,抛异常
return DealLogPathError(err, c.LogPath)
}
if err := os.Mkdir(c.LogPath, os.ModePerm); nil != err {
return DealLogPathError(err, "创建日志目录失败")
}
}
// 生成格式化日志全路径
switch c.TimeIntervalType {
case TimeIntervalTypeMinute:
c.TimeInterval = time.Minute
c.FullLogFormat = c.LogPath + "%Y" + c.DivisionChar + "%m" + c.DivisionChar + "%d" + c.DivisionChar + "%H" + c.DivisionChar + "%M" + c.DivisionChar + c.LogFileName
case TimeIntervalTypeHour:
c.TimeInterval = time.Hour
c.FullLogFormat = c.LogPath + "%Y" + c.DivisionChar + "%m" + c.DivisionChar + "%d" + c.DivisionChar + "%H" + c.DivisionChar + c.LogFileName
case TimeIntervalTypeDay:
c.TimeInterval = time.Hour * 24
c.FullLogFormat = c.LogPath + "%Y" + c.DivisionChar + "%m" + c.DivisionChar + "%d" + c.DivisionChar + c.LogFileName
case TimeIntervalTypeMonth:
c.TimeInterval = time.Hour * 24 * 30
c.FullLogFormat = c.LogPath + "%Y" + c.DivisionChar + "%m" + c.DivisionChar + c.LogFileName
case TimeIntervalTypeYear:
c.TimeInterval = time.Hour * 24 * 365
c.FullLogFormat = c.LogPath + "%Y" + c.DivisionChar + c.LogFileName
default:
return LogSplitTypeError(c.TimeIntervalType)
}
return nil
}
// ============== 以下为zap相关配置
const (
// defaultMessageKey 默认的message key
defaultMessageKey = "message"
// defaultLevelKey 默认的level
defaultLevelKey = "level"
// defaultTimeKey 默认时间key
defaultTimeKey = "time"
// defaultCallerKey 默认的文件key
defaultCallerKey = "file"
// defaultUserShortCaller 是否使用短的文件调用格式
defaultUseShortCaller = true
// defaultUseJsonFormat 日志默认使用json格式
defaultUseJsonFormat = true
)
// defaultTimeEncoder 默认的时间处理
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 11:53 下午 2021/1/2
func defaultTimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
sec := t.UnixNano() / 1e9
ms := t.UnixNano() / 1e6 % 1e3
ns := t.UnixNano() % 1e6
enc.AppendString(time.Unix(sec, ns).Format("2006-01-02 15:04:05") + "." + fmt.Sprintf("%v", ms) + "+" + fmt.Sprintf("%v", ns))
}
// SecondTimeEncoder 秒级时间戳格式化
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 8:34 下午 2021/1/3
func SecondTimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
enc.AppendString(t.Format("2006-01-02 15:04:05"))
}
// MsTimeEncoder 毫秒时间格式化方法
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 8:35 下午 2021/1/3
func MsTimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
sec := t.UnixNano() / 1e9
ms := t.UnixNano() / 1e6 % 1e3
enc.AppendString(time.Unix(sec, 0).Format("2006-01-02 15:04:05") + "." + fmt.Sprintf("%v", ms))
}
// defaultEncodeDuration 默认的原始时间处理
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 11:56 下午 2021/1/2
func defaultEncodeDuration(d time.Duration, enc zapcore.PrimitiveArrayEncoder) {
enc.AppendInt64(int64(d) / 1000000)
}
// OptionLogger 日志配置的选项
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 11:41 下午 2021/1/2
type OptionLogger struct {
UseJsonFormat bool // 日志使用json格式
MessageKey string // message 字段
LevelKey string // level 字段
TimeKey string // 时间字段
CallerKey string // 记录日志的文件的代码行数
UseShortCaller bool // 使用短的调用文件格式
TimeEncoder zapcore.TimeEncoder // 格式化时间的函数
EncodeDuration zapcore.DurationEncoder // 原始时间信息
WithCaller bool // 是否打印文件行号
WithCallerSkip int // 跳过的调用数
ConsoleOutput bool // 控制台输出
Encoder zapcore.Encoder // 编码函数
}
// SetLoggerOptionFunc 设置日志配置
type SetLoggerOptionFunc func(o *OptionLogger)
// WithCaller 打开文件行号记录
func WithCaller() SetLoggerOptionFunc {
return func(o *OptionLogger) {
o.WithCaller = true
}
}
// WithCallerSkip ...
func WithCallerSkip(skip int) SetLoggerOptionFunc {
return func(o *OptionLogger) {
o.WithCallerSkip = skip
}
}
// WithConsoleOutput 日志控制台输出
func WithConsoleOutput() SetLoggerOptionFunc {
return func(o *OptionLogger) {
o.ConsoleOutput = true
}
}
// WithEncoder ...
func WithEncoder(encoder zapcore.Encoder) SetLoggerOptionFunc {
return func(o *OptionLogger) {
o.Encoder = encoder
}
}
// WithUseJsonFormat 日志是否使用json格式数据
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 12:30 上午 2021/1/3
func WithUseJsonFormat(isJsonFormat bool) SetLoggerOptionFunc {
return func(o *OptionLogger) {
o.UseJsonFormat = isJsonFormat
}
}
// WithMessageKey 使用message key
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 12:32 上午 2021/1/3
func WithMessageKey(messageKey string) SetLoggerOptionFunc {
return func(o *OptionLogger) {
messageKey = strings.Trim(messageKey, " ")
if len(messageKey) == 0 {
return
}
o.MessageKey = messageKey
}
}
// WithLevelKey 设置level key
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 12:33 上午 2021/1/3
func WithLevelKey(levelKey string) SetLoggerOptionFunc {
return func(o *OptionLogger) {
levelKey = strings.Trim(levelKey, " ")
if len(levelKey) == 0 {
return
}
o.LevelKey = levelKey
}
}
// WithTimeKey 设置time key ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 12:34 上午 2021/1/3
func WithTimeKey(timeKey string) SetLoggerOptionFunc {
return func(o *OptionLogger) {
timeKey = strings.Trim(timeKey, " ")
if len(timeKey) == 0 {
return
}
o.TimeKey = timeKey
}
}
// WithCallerKey 设置caller key
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 12:37 上午 2021/1/3
func WithCallerKey(callerKey string) SetLoggerOptionFunc {
return func(o *OptionLogger) {
callerKey = strings.Trim(callerKey, " ")
if len(callerKey) == 0 {
return
}
o.CallerKey = callerKey
}
}
// WithShortCaller 是否使用短caller格式
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 12:39 上午 2021/1/3
func WithShortCaller(useShortCaller bool) SetLoggerOptionFunc {
return func(o *OptionLogger) {
o.UseShortCaller = useShortCaller
}
}
// WithTimeEncoder 设置格式化时间方法
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 12:41 上午 2021/1/3
func WithTimeEncoder(encoder zapcore.TimeEncoder) SetLoggerOptionFunc {
return func(o *OptionLogger) {
if nil == encoder {
return
}
o.TimeEncoder = encoder
}
}
// WithEncodeDuration 原始时间
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 12:42 上午 2021/1/3
func WithEncodeDuration(encoder zapcore.DurationEncoder) SetLoggerOptionFunc {
return func(o *OptionLogger) {
if nil == encoder {
return
}
o.EncodeDuration = encoder
}
}
// GetEncoder 获取空中台输出的encoder
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 6:24 下午 2021/1/2
func GetEncoder(option ...SetLoggerOptionFunc) zapcore.Encoder {
ol := &OptionLogger{
UseJsonFormat: defaultUseJsonFormat,
MessageKey: defaultMessageKey,
LevelKey: defaultLevelKey,
TimeKey: defaultTimeKey,
TimeEncoder: defaultTimeEncoder,
CallerKey: defaultCallerKey,
EncodeDuration: defaultEncodeDuration,
UseShortCaller: defaultUseShortCaller,
}
for _, o := range option {
o(ol)
}
ec := zapcore.EncoderConfig{
MessageKey: ol.MessageKey,
LevelKey: ol.LevelKey,
EncodeLevel: zapcore.CapitalLevelEncoder,
TimeKey: ol.TimeKey,
EncodeTime: ol.TimeEncoder,
CallerKey: ol.CallerKey,
EncodeCaller: zapcore.ShortCallerEncoder,
EncodeDuration: ol.EncodeDuration,
}
if !ol.UseShortCaller {
ec.EncodeCaller = zapcore.FullCallerEncoder
}
if !ol.UseJsonFormat {
return zapcore.NewConsoleEncoder(ec)
}
return zapcore.NewJSONEncoder(ec)
}

26
debug.go Normal file
View File

@ -0,0 +1,26 @@
// Package logger...
//
// Description : logger...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2021-01-03 12:58 上午
package logger
import (
"bytes"
"encoding/json"
)
// FormatJson 格式化输出json
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 1:06 上午 2021/1/3
func FormatJson(src interface{}) string {
byteData, _ := json.Marshal(src)
var str bytes.Buffer
_ = json.Indent(&str, byteData, "", " ")
return str.String()
}

64
error.go Normal file
View File

@ -0,0 +1,64 @@
// Package logger...
//
// Description : error 定义日志处理过程中的各种错误
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2021-01-02 2:44 下午
package logger
import "github.com/pkg/errors"
// CreateLogFileError 创建日志文件失败
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2:55 下午 2021/1/2
func CreateLogFileError(err error, logFilePath string) error {
return errors.Wrapf(err, "创建日志文件失败,日志文件路径 : %s", logFilePath)
}
// LogPathEmptyError 日志路径为空
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 4:03 下午 2021/1/2
func LogPathEmptyError() error {
return errors.Wrap(errors.New("日志存储路径或者日志文件名为空"), "日志存储路径或者日志文件名为空")
}
// CustomTimeIntervalError 自定义日志切割时间间隔错误
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 4:11 下午 2021/1/2
func CustomTimeIntervalError() error {
return errors.Wrap(errors.New("自定义时间间隔错误,必须是大于0的值"), "自定义时间间隔错误,必须是大于0的值")
}
// DealLogPathError 日志路径处理异常
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 4:31 下午 2021/1/2
func DealLogPathError(err error, logPath string) error {
return errors.Wrapf(err, "日志路径检测处理异常, 日志路径 : %s", logPath)
}
// LogSplitTypeError 日志切割类型错误
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 4:50 下午 2021/1/2
func LogSplitTypeError(splitType TimeIntervalType) error {
return errors.Wrapf(errors.New("日志切割时间类型错误"), "日志切割时间类型错误, 传入类型 : %v", splitType)
}
// CreateIOWriteError 创建日志实例失败
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 5:20 下午 2021/1/2
func CreateIOWriteError(err error) error {
return errors.Wrapf(err, "创建日志实例失败")
}

35
go.mod
View File

@ -1,3 +1,36 @@
module git.zhangdeman.cn/zhangdeman/logger
go 1.18
go 1.17
require (
git.zhangdeman.cn/zhangdeman/gopkg v0.0.0-20220404153548-f65ee3641a1e
github.com/gin-gonic/gin v1.7.7
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible
github.com/pkg/errors v0.9.1
go.uber.org/zap v1.20.0
gorm.io/gorm v1.22.4
)
require (
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-playground/locales v0.14.0 // indirect
github.com/go-playground/universal-translator v0.18.0 // indirect
github.com/go-playground/validator/v10 v10.10.1 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.4 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/leodido/go-urn v1.2.1 // indirect
github.com/lestrrat-go/strftime v1.0.5 // indirect
github.com/mattn/go-isatty v0.0.12 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/ugorji/go/codec v1.2.7 // indirect
go.uber.org/atomic v1.9.0 // indirect
go.uber.org/multierr v1.7.0 // indirect
golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29 // indirect
golang.org/x/sys v0.0.0-20220403205710-6acee93ad0eb // indirect
golang.org/x/text v0.3.7 // indirect
google.golang.org/protobuf v1.28.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
)

155
go.sum Normal file
View File

@ -0,0 +1,155 @@
git.zhangdeman.cn/zhangdeman/gopkg v0.0.0-20220404153548-f65ee3641a1e h1:sSemK4Q1HmqM9ZM8KXre9polJeXVScNrPsXIDih5Xys=
git.zhangdeman.cn/zhangdeman/gopkg v0.0.0-20220404153548-f65ee3641a1e/go.mod h1:YuvLB+lJbmG1oFRUIMF7JVnrfLqeXUYoZqKt103xsOg=
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.7.7 h1:3DoBmSbJbZAWqXJC3SLjAPfutPJJRN1U5pALB7EeTTs=
github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U=
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU=
github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho=
github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
github.com/go-playground/validator/v10 v10.10.1 h1:uA0+amWMiglNZKZ9FJRKUAe9U3RX91eVn1JYXMWt7ig=
github.com/go-playground/validator/v10 v10.10.1/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.3/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/jinzhu/now v1.1.4 h1:tHnRBy1i5F2Dh8BAFxqFzxKqqvezXrL2OW1TnX+Mlas=
github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9qUBdQ=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc h1:RKf14vYWi2ttpEmkA4aQ3j4u9dStX2t4M8UM6qqNsG8=
github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc/go.mod h1:kopuH9ugFRkIXf3YoqHKyrJ9YfUFsckUU9S7B+XP+is=
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible h1:Y6sqxHMyB1D2YSzWkLibYKgg+SwmyFU9dF2hn6MdTj4=
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible/go.mod h1:ZQnN8lSECaebrkQytbHj4xNgtg8CR7RYXnPok8e0EHA=
github.com/lestrrat-go/strftime v1.0.5 h1:A7H3tT8DhTz8u65w+JRpiBxM4dINQhUXAZnhBa2xeOE=
github.com/lestrrat-go/strftime v1.0.5/go.mod h1:E1nN3pCbtMSu1yjSVeyuRFVm/U0xoR76fd03sz+Qz4g=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0=
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/multierr v1.7.0 h1:zaiO/rmgFjbmCXdSYJWQcdvOCsthmdaHfr3Gm2Kx4Ec=
go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
go.uber.org/zap v1.20.0 h1:N4oPlghZwYG55MlU6LXk/Zp00FVNE9X9wrYO8CEs4lc=
go.uber.org/zap v1.20.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29 h1:tkVvjkPTB7pnW3jnid7kNyAMPVWllTNOf/qKDze4p9o=
golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220403205710-6acee93ad0eb h1:PVGECzEo9Y3uOidtkHGdd347NjLtITfJFO9BxFpmRoo=
golang.org/x/sys v0.0.0-20220403205710-6acee93ad0eb/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gorm.io/gorm v1.22.4 h1:8aPcyEJhY0MAt8aY6Dc524Pn+pO29K+ydu+e/cXSpQM=
gorm.io/gorm v1.22.4/go.mod h1:1aeVC+pe9ZmvKZban/gW4QPra7PRoTEssyc922qCAkk=

136
logger.go Normal file
View File

@ -0,0 +1,136 @@
// Package logger...
//
// Description : logger 日志文件
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2021-01-02 5:04 下午
package logger
import (
"io"
"os"
"github.com/pkg/errors"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
rotatelogs "github.com/lestrrat-go/file-rotatelogs"
)
// NewLogger 获取日志实例
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 5:05 下午 2021/1/2
func NewLogger(loggerLevel zapcore.Level, splitConfig *RotateLogConfig, optionFunc ...SetLoggerOptionFunc) (*zap.Logger, error) {
if nil == splitConfig {
return nil, errors.New("未配置日志切割规则")
}
o := &OptionLogger{}
for _, f := range optionFunc {
f(o)
}
if nil == o.Encoder {
o.Encoder = GetEncoder()
}
loggerLevelDeal := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
return lvl >= loggerLevel
})
l := &Logger{
splitConfig: splitConfig,
encoder: o.Encoder,
}
var (
err error
loggerWriter io.Writer
)
// 获取 日志实现
if loggerWriter, err = l.getWriter(); nil != err {
return nil, err
}
fileHandlerList := []zapcore.Core{
zapcore.NewCore(o.Encoder, zapcore.AddSync(loggerWriter), loggerLevelDeal),
}
// 设置控制台输出
if o.ConsoleOutput {
fileHandlerList = append(fileHandlerList, zapcore.NewCore(o.Encoder, zapcore.AddSync(os.Stdout), loggerLevelDeal))
}
// 最后创建具体的Logger
core := zapcore.NewTee(fileHandlerList...)
// 需要传入 zap.AddCaller() 才会显示打日志点的文件名和行数, 跳过一行可以直接显示业务代码行号,否则显示日志包行号
logConfList := make([]zap.Option, 0)
if o.WithCaller {
logConfList = append(logConfList, zap.AddCaller(), zap.AddCallerSkip(o.WithCallerSkip))
}
log := zap.New(core, logConfList...)
return log, nil
}
// NewConsoleLogger 获取控制台输出的日志实例
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 8:22 下午 2021/4/17
func NewConsoleLogger(loggerLevel zapcore.Level, optionFunc ...SetLoggerOptionFunc) (*zap.Logger, error) {
o := &OptionLogger{}
for _, f := range optionFunc {
f(o)
}
if nil == o.Encoder {
o.Encoder = GetEncoder()
}
loggerLevelDeal := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
return lvl >= loggerLevel
})
fileHandlerList := []zapcore.Core{
zapcore.NewCore(o.Encoder, zapcore.AddSync(os.Stdout), loggerLevelDeal),
}
// 最后创建具体的Logger
core := zapcore.NewTee(fileHandlerList...)
// 需要传入 zap.AddCaller() 才会显示打日志点的文件名和行数, 跳过一行可以直接显示业务代码行号,否则显示日志包行号
logConfList := make([]zap.Option, 0)
if o.WithCaller {
logConfList = append(logConfList, zap.AddCaller(), zap.AddCallerSkip(o.WithCallerSkip))
}
log := zap.New(core, logConfList...)
return log, nil
}
type Logger struct {
splitConfig *RotateLogConfig
encoder zapcore.Encoder
}
// getWriter 获取日志实例
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 5:08 下午 2021/1/2
func (l *Logger) getWriter() (io.Writer, error) {
option := make([]rotatelogs.Option, 0)
option = append(option, rotatelogs.WithRotationTime(l.splitConfig.TimeInterval))
if l.splitConfig.MaxAge > 0 {
option = append(option, rotatelogs.WithMaxAge(l.splitConfig.MaxAge))
}
var (
hook *rotatelogs.RotateLogs
err error
)
if hook, err = rotatelogs.New(l.splitConfig.FullLogFormat, option...); nil != err {
return nil, CreateIOWriteError(err)
}
return hook, nil
}

203
wrapper/gorm_v2.go Normal file
View File

@ -0,0 +1,203 @@
// Package wrapper...
//
// Description : gorm v2 版本接口实现
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2021/03/01 9:52 下午
package wrapper
import (
"context"
"fmt"
"strings"
"time"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
"go.uber.org/zap/zapcore"
"go.uber.org/zap"
logger2 "git.zhangdeman.cn/zhangdeman/logger"
"gorm.io/gorm/logger"
)
// NewGormV2 获取日志实例
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 9:56 下午 2021/3/1
func NewGormV2(loggerLevel zapcore.Level, consoleOutput bool, encoder zapcore.Encoder, splitConfig *logger2.RotateLogConfig, traceIDField string, skip int) (logger.Interface, error) {
logConfList := []logger2.SetLoggerOptionFunc{logger2.WithEncoder(encoder), logger2.WithCallerSkip(skip), logger2.WithCaller()}
if consoleOutput {
logConfList = append(logConfList, logger2.WithConsoleOutput())
}
logInstance, err := logger2.NewLogger(loggerLevel, splitConfig, logConfList...)
if nil != err {
return nil, err
}
if len(traceIDField) == 0 {
traceIDField = "trace_id"
}
return &Gorm{
instance: logInstance,
traceIDField: traceIDField,
}, nil
}
// NewGormLoggerWithInstance 获取gorm日志实现
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 3:36 PM 2021/12/24
func NewGormLoggerWithInstance(ctx *gin.Context, dbClient *gorm.DB, instance *zap.Logger, node string, extraCtxFieldList []string) logger.Interface {
return &Gorm{
dbClient: dbClient,
instance: instance,
traceIDField: "",
extraCtxFieldList: extraCtxFieldList,
flag: "",
node: node,
ctx: ctx,
}
}
// Gorm v2 版本库日志实现
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 9:55 下午 2021/3/1
type Gorm struct {
dbClient *gorm.DB
instance *zap.Logger // 日志实例
traceIDField string // 串联请求上下文的的ID
extraCtxFieldList []string // 从请求上线问提取的字段
flag string // 数据库标识
node string // 数据库节点 master / slave
ctx *gin.Context // gin上下文
}
// LogMode ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 10:08 下午 2021/3/1
func (g *Gorm) LogMode(level logger.LogLevel) logger.Interface {
return g
}
// Info 日志
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 10:18 下午 2021/3/1
func (g *Gorm) Info(ctx context.Context, s string, i ...interface{}) {
g.write(nil, "info")
}
// Warn ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 10:16 下午 2021/3/1
func (g *Gorm) Warn(ctx context.Context, s string, i ...interface{}) {
g.write(nil, "warn")
}
// Error 日志
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 10:18 下午 2021/3/1
func (g *Gorm) Error(ctx context.Context, s string, i ...interface{}) {
g.write(nil, "error")
}
// Trace Trace 记录
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 10:19 下午 2021/3/1
func (g *Gorm) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) {
start := begin.UnixNano()
end := time.Now().UnixNano()
sql := ""
affectRows := int64(0)
if nil != fc {
sql, affectRows = fc()
}
dataList := []zap.Field{
zap.String(g.traceIDField, g.getTraceID(ctx)),
zap.String("db_flag", g.flag),
zap.Int64("begin_time", start),
zap.Int64("finish_time", end),
zap.String("used_time", fmt.Sprintf("%fms", float64(end-start)/1e6)),
zap.String("sql", sql),
zap.Int64("affect_rows", affectRows),
zap.Error(err),
}
g.write(dataList, "info")
}
// write ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 4:11 PM 2021/12/24
func (g *Gorm) write(dataList []zap.Field, level string) {
if nil == g.instance {
// 未设置日志实例
return
}
if nil == dataList {
dataList = make([]zap.Field, 0)
}
if nil != g.ctx {
for _, extraField := range g.extraCtxFieldList {
dataList = append(dataList, zap.Any(extraField, g.ctx.Value(extraField)))
}
}
// 补齐 flag、node
sql := g.dbClient.Dialector.Explain(g.dbClient.Statement.SQL.String(), g.dbClient.Statement.Vars...)
affectRows := g.dbClient.RowsAffected
dataList = append(dataList, zap.String("db_node", g.node), zap.String("db_flag", g.flag), zap.String("execute_sql", sql), zap.Int64("affect_rows", affectRows))
message := "SQL执行记录"
switch strings.ToLower(level) {
case "info":
g.instance.Info(message, dataList...)
case "warn":
g.instance.Warn(message, dataList...)
case "error":
g.instance.Error(message, dataList...)
default:
g.instance.Info(message, dataList...)
}
}
// getTraceID 获取traceID
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 10:11 下午 2021/3/1
func (g *Gorm) getTraceID(ctx context.Context) string {
return fmt.Sprintf("%v", ctx.Value(g.traceIDField))
}
// GetGormSQL 获取trace fn
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 10:38 下午 2021/3/1
func GetGormSQL(dbClient *gorm.DB) func() (string, int64) {
return func() (string, int64) {
return dbClient.Dialector.Explain(dbClient.Statement.SQL.String(), dbClient.Statement.Vars...), dbClient.RowsAffected
}
}

142
wrapper/http_gin.go Normal file
View File

@ -0,0 +1,142 @@
// Package wrapper...
//
// Description : http_gin 使用gin框架时的记录日志
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2021-01-03 3:43 下午
package wrapper
import (
"encoding/json"
"git.zhangdeman.cn/zhangdeman/gopkg/logger"
logger2 "git.zhangdeman.cn/zhangdeman/gopkg/logger"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
// NewGinLogger 使用gin框架记录日志
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 3:45 下午 2021/1/3
func NewGinLogger(loggerLevel zapcore.Level, consoleOutput bool, encoder zapcore.Encoder, splitConfig *logger.RotateLogConfig, extractFieldList []string, skip int) (*Gin, error) {
var (
err error
l *zap.Logger
)
logConfList := []logger2.SetLoggerOptionFunc{logger2.WithEncoder(encoder), logger2.WithCaller(), logger2.WithCallerSkip(skip)}
if consoleOutput {
logConfList = append(logConfList, logger2.WithConsoleOutput())
}
if l, err = logger.NewLogger(loggerLevel, splitConfig, logConfList...); nil != err {
return nil, err
}
return &Gin{
loggerInstance: l,
extractFieldList: extractFieldList,
}, nil
}
// Gin 包装gin实例
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 3:59 下午 2021/1/3
type Gin struct {
loggerInstance *zap.Logger // zap 的日志实例
extractFieldList []string // 从gin中抽取的字段
}
// formatFieldList 格式化日志field列表
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 4:13 下午 2021/1/3
func (gw *Gin) formatFieldList(ginCtx *gin.Context, inputFieldList []zap.Field) []zap.Field {
if nil == inputFieldList {
inputFieldList = make([]zap.Field, 0)
}
if nil != ginCtx {
// 自动扩充抽取字段,字段不存在的话,忽略掉
for _, extractField := range gw.extractFieldList {
if v, exist := ginCtx.Get(extractField); exist {
byteData, _ := json.Marshal(v)
inputFieldList = append(inputFieldList, zap.String(extractField, string(byteData)))
}
}
}
return inputFieldList
}
// Debug 日志
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 4:14 下午 2021/1/3
func (gw *Gin) Debug(ginCtx *gin.Context, msg string, field ...zap.Field) {
fieldList := gw.formatFieldList(ginCtx, field)
gw.loggerInstance.Debug(msg, fieldList...)
}
// Info 日志
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 4:28 下午 2021/1/3
func (gw *Gin) Info(ginCtx *gin.Context, msg string, field ...zap.Field) {
fieldList := gw.formatFieldList(ginCtx, field)
gw.loggerInstance.Info(msg, fieldList...)
}
// Warn 日志
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 4:29 下午 2021/1/3
func (gw *Gin) Warn(ginCtx *gin.Context, msg string, field ...zap.Field) {
fieldList := gw.formatFieldList(ginCtx, field)
gw.loggerInstance.Warn(msg, fieldList...)
}
// Error 日志
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 4:29 下午 2021/1/3
func (gw *Gin) Error(ginCtx *gin.Context, msg string, field ...zap.Field) {
fieldList := gw.formatFieldList(ginCtx, field)
gw.loggerInstance.Error(msg, fieldList...)
}
// Panic 日志
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 4:29 下午 2021/1/3
func (gw *Gin) Panic(ginCtx *gin.Context, msg string, field ...zap.Field) {
fieldList := gw.formatFieldList(ginCtx, field)
gw.loggerInstance.Panic(msg, fieldList...)
}
// DPanic 日志
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 4:30 下午 2021/1/3
func (gw *Gin) DPanic(ginCtx *gin.Context, msg string, field ...zap.Field) {
fieldList := gw.formatFieldList(ginCtx, field)
gw.loggerInstance.DPanic(msg, fieldList...)
}
// GetZapLoggerInstance 获取zap日志实例
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2021/01/03 22:56:47
func (gw *Gin) GetZapLoggerInstance() *zap.Logger {
return gw.loggerInstance
}