日志介绍 (一)
lumberjack 可以选择 v2 版本 ,地址:https://github.com/natefinch/lumberjack/tree/v2.1
这个库的主要作用如下:
1.定义日志文件的大小和超过文件设置的数量开心的文件。
2.按保留天数去删除历史日志文件。
3.现存日志文件进行压缩。
func NewLog(){
//省略部分
fileConfig := &lumberjack.Logger{
Filename: viper.GetString(`settings.log.path`), // 日志文件名
MaxSize: viper.GetInt(`settings.log.maxsize`), // 日志文件大小
MaxAge: viper.GetInt(`settings.log.maxsave`), // 最长保存天数
MaxBackups: viper.GetInt(`settings.log.maxBackups`), // 最多备份几个
LocalTime: viper.GetBool(`settings.log.localtime`), // 日志时间戳
Compress: viper.GetBool(`settings.log.compress`), // 是否压缩文件,使用gzip
}
}
lumberjack.Logger 是一个结构体
地址:https://github.com/natefinch/lumberjack/blob/v2.1/lumberjack.gotype可以看到 Logger struct{......}
上面的 MaxAge 和 MaxBackups 都为 0,则不会删除日志文件,fileConfig 被传入到第一个文章里面的。
func NewLog(){
var writers []zapcore.WriteSyncer
//上面fileConfig设置。
if viper.GetBool("settings.log.consoleStdout") {
//追加到zapcore的写入缓存和zapcore同步输出日志到控制台
writers = append(writers, zapcore.AddSync(os.Stdout))
}
if viper.GetBool("settings.log.fileStdout") {
//同步输出到output文件,fileConfig后面会讲到,因为zap没有包含这部分功能。
writers = append(writers, zapcore.AddSync(fileConfig))
}
}
基础四件套 Debug,Info,Warn,Error 和他们的 fmt 版本。
func Debug(args ...interface{}) {
log.Debug(args...)
}
func Debugf(format string, args ...interface{}) {
log.Debugf(format, args...)
}
func Info(args ...interface{}) {
log.Info(args...)
}
func Infof(format string, args ...interface{}) {
log.Infof(format, args...)
}
func Warn(args ...interface{}) {
log.Warn(args...)
}
func Warnf(format string, args ...interface{}) {
log.Warnf(format, args...)
}
func Error(args ...interface{}) {
log.Error(args...)
}
func Errorf(format string, args ...interface{}) {
log.Errorf(format, args...)
}
log.Fatal 和 log.Panic 这个不推荐,所以这里不会列出来。如果要上生产和高精度工具,可以对于 Panic 和 Fatal(不可恢复)可以建其他方法去处理,类似以下的方法。
func PanicError(c *gin.Context) {
defer func(){
if err := recover();err!=nil{
//当前的context被终止了,该方法返回true
if c.IsAborted(){
c.Status(http.StatusOK)
}
}
}()
c.Next() //核心是这句话
}
gin 下面一段稍微做一些介绍,日志文件基本内容告一个段落。
对日志文件包装了一层 wrapLogFiles(),提供给 golang 封装 saas 的使用,比如 gin。 gin 这里先不做特别介绍,日志是放在工程的 middleware 里面的,wrapLogFiles 如下:
func WrapLogFiles() gin.HandlerFunc {
return func(c *gin.Context) {
startTime := time.Now()
c.Next() //核心方法
endTime := time.Now()
latencyTime := endTime.Sub(startTime)
reqMethod := c.Request.Method // 请求方式
reqUri := c.Request.RequestURI // 请求路由
statusCode := c.Writer.Status() //通过上下文写入状态码
clientIP := c.ClientIP() // 请求IP
logger.Infof(" %s %3d %13v %15s %s %s",
startTime.Format("2006-01-02 15:04:05.9999"),
statusCode,
latencyTime,
clientIP,
reqMethod,
reqUri,
)
}
}
添加到 gin web 框架方式如下:
func NewRouter(r *gin.Engine){
r := gin.New()
g := r.Group("/api/v1", wrapLogFiles(),gin.Recovery())
{
g.POST("api名称",HandlerChain)
//其他的Http请求方式
}
}
WrapLogFiles() 里面有上下文的 c.next(),所以 gin.Recovery() 后面的会生效,Group 第二个参数是传入不定长的 HandlerFunc。
也可以用以下的方式,更建议是用 InitMiddleware(),设置和路由 Group 分开。
func NewRouter(r *gin.Engine){
r := gin.New()
g := r.Group("/api/v1")
g.Use(wrapLogFiles())
g.Use(gin.Recovery())
{
g.POST("api名称",HandlerChain)
//其他的Http请求方式
}
}
gin 部分这个篇幅先不继续写了,就如上面这样被添加进去的。