130 lines
4.4 KiB
Go
130 lines
4.4 KiB
Go
package logger
|
||
|
||
import (
|
||
"fmt"
|
||
"os"
|
||
"path/filepath"
|
||
"time"
|
||
|
||
"github.com/gin-gonic/gin"
|
||
"github.com/natefinch/lumberjack"
|
||
"go.uber.org/zap"
|
||
"go.uber.org/zap/zapcore"
|
||
"joylink.club/bj-rtsts-server/config"
|
||
)
|
||
|
||
const DefaultLogPath = "/var/logs"
|
||
|
||
// 初始化日志
|
||
func InitLogger() error {
|
||
logLevel := map[string]zapcore.Level{
|
||
"debug": zapcore.DebugLevel,
|
||
"info": zapcore.InfoLevel,
|
||
"warn": zapcore.WarnLevel,
|
||
"error": zapcore.ErrorLevel,
|
||
}
|
||
|
||
// 根据配置创建编码器
|
||
encoder := newEncoder()
|
||
level, ok := logLevel[config.Config.Logging.Level]
|
||
if !ok {
|
||
level = logLevel["info"]
|
||
}
|
||
|
||
writeSyncer, err := newLogWriter()
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
core := zapcore.NewCore(encoder, writeSyncer, level)
|
||
logger := zap.New(core, zap.AddCaller())
|
||
|
||
zap.ReplaceGlobals(logger)
|
||
return nil
|
||
}
|
||
|
||
// 日志编码器
|
||
func newEncoder() zapcore.Encoder {
|
||
encoderConfig := zap.NewProductionEncoderConfig()
|
||
encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
|
||
encoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder
|
||
if config.Config.Logging.Format == "json" {
|
||
return zapcore.NewJSONEncoder(encoderConfig)
|
||
}
|
||
return zapcore.NewConsoleEncoder(encoderConfig)
|
||
}
|
||
|
||
func newLogWriter() (zapcore.WriteSyncer, error) {
|
||
logging := config.Config.Logging
|
||
fmt.Println(logging)
|
||
// 判断日志路径是否存在,如果不存在就创建
|
||
if logging.Path == "" {
|
||
logging.Path = DefaultLogPath
|
||
}
|
||
if exist := IsExist(logging.Path); !exist {
|
||
fmt.Println("不存在", logging.Path)
|
||
if err := os.MkdirAll(logging.Path, os.ModePerm); err != nil {
|
||
return nil, err
|
||
}
|
||
}
|
||
|
||
// 日志文件 与 日志切割 配置
|
||
if logging.FileName == "" {
|
||
logging.FileName = "server.log"
|
||
}
|
||
lumberJackLogger := &lumberjack.Logger{
|
||
Filename: filepath.Join(logging.Path, logging.FileName), // 日志文件路径
|
||
MaxSize: logging.FileMaxSize, // 单个日志文件最大多少 mb
|
||
MaxBackups: logging.FileMaxBackups, // 日志备份数量
|
||
MaxAge: logging.MaxAge, // 日志最长保留时间
|
||
LocalTime: true, // 日志备份使用本地时间
|
||
Compress: logging.Compress, // 是否压缩日志
|
||
}
|
||
if logging.Stdout {
|
||
// 日志同时输出到控制台和日志文件中
|
||
return zapcore.NewMultiWriteSyncer(zapcore.AddSync(lumberJackLogger), zapcore.AddSync(os.Stdout)), nil
|
||
} else {
|
||
// 日志只输出到日志文件
|
||
return zapcore.AddSync(lumberJackLogger), nil
|
||
}
|
||
}
|
||
|
||
// IsExist 判断文件或者目录是否存在
|
||
func IsExist(path string) bool {
|
||
_, err := os.Stat(path)
|
||
fmt.Println(err)
|
||
return err == nil || os.IsExist(err)
|
||
}
|
||
|
||
// GinLogger 接收gin框架默认的日志
|
||
func GinLogger() gin.HandlerFunc {
|
||
return func(c *gin.Context) {
|
||
start := time.Now()
|
||
path := c.Request.URL.Path // 请求路径 eg: /test
|
||
query := c.Request.URL.RawQuery //query类型的请求参数:?name=1&password=2
|
||
// 挂起当前中间件,执行下一个中间件
|
||
c.Next()
|
||
|
||
cost := time.Since(start)
|
||
|
||
// Field 是 Field 的别名。给这个类型起别名极大地提高了这个包的 API 文档的可导航性。
|
||
// type Field struct {
|
||
// Key string
|
||
// Type FieldType // 类型,数字对应具体类型,eg: 15--->string
|
||
// Integer int64
|
||
// String string
|
||
// Interface interface{}
|
||
//}
|
||
zap.S().Info("处理请求:",
|
||
zap.String("method", c.Request.Method), // 请求方法类型 eg: GET
|
||
zap.String("path", path), // 请求路径 eg: /test
|
||
zap.Int("status", c.Writer.Status()), // 状态码 eg: 200
|
||
zap.String("query", query), // 请求参数 eg: name=1&password=2
|
||
zap.String("ip", c.ClientIP()), // 返回真实的客户端IP eg: ::1(这个就是本机IP,ipv6地址)
|
||
zap.String("user-agent", c.Request.UserAgent()), // 返回客户端的用户代理。 eg: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36
|
||
zap.String("errors", c.Errors.ByType(gin.ErrorTypePrivate).String()), // 返回Errors 切片中ErrorTypePrivate类型的错误
|
||
zap.Duration("cost", cost), // 返回花费时间
|
||
)
|
||
}
|
||
}
|