【阅读 GinSkeleton】日志管理

日志管理

推荐学习:

在Go语言项目中使用Zap日志库

使用zap接收gin框架默认的日志并配置日志归档

官方文档

因为日志模式分开发调试生产模式,所以需要根据配置文件生成相关得日志对象。

开发调试模式

	// 判断程序当前所处的模式,调试模式直接返回一个便捷的zap日志管理器地址,所有的日志打印到控制台即可
//挂载钩子函数
	if appDebug == true {
		if logger, err := zap.NewDevelopment(zap.Hooks(entry)); err == nil {
			return logger
		} else {
			log.Fatal("创建zap日志包失败,详情:" + err.Error())
		}
	}
复制代码

生产模式

这里生产模式采用的是定制logger方式,同时在生产模式日志就不应该打印到应用程序控制台中了,应该写入文件中。

第一步:Encoder:编码器(如何写入日志)。

	encoderConfig := zap.NewProductionEncoderConfig()
	var encoder zapcore.Encoder
	switch variable.ConfigYml.GetString("Logs.TextFormat") {
	case "console":
		encoder = zapcore.NewConsoleEncoder(encoderConfig) // 普通模式
	case "json":
		encoder = zapcore.NewJSONEncoder(encoderConfig) // json格式
	default:
		encoder = zapcore.NewConsoleEncoder(encoderConfig) // 普通模式
	}
复制代码

根据配置文件选择写入文件的方式。

第二步:WriterSyncer :指定日志将写到哪里去。

	
	//写入文件位置
	fileName := variable.BasePath + variable.ConfigYml.GetString("Logs.GoSkeletonLogName")
	//配置相关信息(日志切割归档功能)
	lumberJackLogger := &lumberjack.Logger{
		Filename:   fileName,                                     //日志文件的位置
		MaxSize:    variable.ConfigYml.GetInt("Logs.MaxSize"),    //在进行切割之前,日志文件的最大大小(以MB为单位)
		MaxBackups: variable.ConfigYml.GetInt("Logs.MaxBackups"), //保留旧文件的最大个数
		MaxAge:     variable.ConfigYml.GetInt("Logs.MaxAge"),     //保留旧文件的最大天数
		Compress:   variable.ConfigYml.GetBool("Logs.Compress"),  //是否压缩/归档旧文件
	}
	//写入器
	writer := zapcore.AddSync(lumberJackLogger)
复制代码

第三步:Log Level:哪种级别的日志将被写入。

	//debug级别支持后续调用的所有函数写日志,如果是 fatal 高级别,则级别>=fatal 才可以写日志
	//选择zap日志级别
	// DebugLevel logs are typically voluminous, and are usually disabled in
	// production.
	DebugLevel = zapcore.DebugLevel
	// InfoLevel is the default logging priority.
	InfoLevel = zapcore.InfoLevel
	// WarnLevel logs are more important than Info, but don't need individual
	// human review.
	WarnLevel = zapcore.WarnLevel
	// ErrorLevel logs are high-priority. If an application is running smoothly,
	// it shouldn't generate any error-level logs.
	ErrorLevel = zapcore.ErrorLevel
	// DPanicLevel logs are particularly important errors. In development the
	// logger panics after writing the message.
	DPanicLevel = zapcore.DPanicLevel
	// PanicLevel logs a message, then panics.
	PanicLevel = zapcore.PanicLevel
	// FatalLevel logs a message, then calls os.Exit(1).
	FatalLevel = zapcore.FatalLevel
复制代码

第四步:添加其他功能(时间等)(可选)

	//获取时间格式化的级别
	timePrecision := variable.ConfigYml.GetString("Logs.TimePrecision")
	//对时间进行格式化
	var recordTimeFormat string
	switch timePrecision {
	case "second":
		recordTimeFormat = "2006-01-02 15:04:05"
	case "millisecond":
		recordTimeFormat = "2006-01-02 15:04:05.000"
	default:
		recordTimeFormat = "2006-01-02 15:04:05"

	}
	//修改时间编码器
	encoderConfig.EncodeTime = func(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
		enc.AppendString(t.Format(recordTimeFormat))
	}
	//在日志文件中使用大写字母记录日志级别
	encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
复制代码

最后一步:创建zap日志对象

// 开始初始化zap日志核心参数,
	//参数一:编码器
	//参数二:写入器
	//参数三:参数级别,debug级别支持后续调用的所有函数写日志,如果是 fatal 高级别,则级别>=fatal 才可以写日志
	zapCore := zapcore.NewCore(encoder, writer, zap.InfoLevel)
//挂载钩子函数
	return zap.New(zapCore, zap.AddCaller(), zap.Hooks(entry))
复制代码

钩子

日志可以对接阿里云日志管理面板,ELK等管理,所以需要获取所有的日志信息,然后通过操作推送上去。

// GoSkeleton 系统运行日志钩子函数
// 1.单条日志就是一个结构体格式,本函数拦截每一条日志,您可以进行后续处理,例如:推送到阿里云日志管理面板、ElasticSearch 日志库等

func ZapLogHandler(entry zapcore.Entry) error {

	// 参数 entry 介绍
	// entry  参数就是单条日志结构体,主要包括字段如下:
	//Level      日志等级
	//Time       当前时间
	//LoggerName  日志名称
	//Message    日志内容
	//Caller     各个文件调用路径
	//Stack      代码调用栈

	//这里启动一个协程,hook丝毫不会影响程序性能,
	go func(paramEntry zapcore.Entry) {
		//fmt.Println(" GoSkeleton  hook ....,你可以在这里继续处理系统日志....")
		//fmt.Printf("%#+v\n", paramEntry)
	}(entry)
	return nil
}

复制代码

初始化

	// 5.初始化全局日志句柄,并载入日志钩子处理函数
	variable.ZapLog = zap_factory.CreateZapFactory(sys_log_hook.ZapLogHandler)
复制代码

使用

用法一:

    //常用方式。
	variable.ZapLog.Info("基本的运行提示类信息")
    variable.ZapLog.Warn("UserCreate接口参数非法警告,相关参数:",zap.String("userName","demo_name"),zap.Int("userAge",18))  
    variable.ZapLog.Panic("UserDestory接口参数异常,相关参数:",zap.String("userName","demo_name"),zap.String("password","pass123456") 
    variable.ZapLog.Error("UserDestory接口参数错误,相关参数:",zap.Error(error))  
    variable.ZapLog.Fatal("Mysql初始化参数错误,退出运行。相关参数:",zap.String("name","root"), zap.Int("端口",3306))  
复制代码

用法二:

 # 第一种的函数后面全部添加了一个 w ,相关的函数功能和第一种一模一样  
 variable.ZapLog.Sugar().Infow("基本的运行提示类信息",zap.String("name","root"))

# 格式化参数,第一种用法中的函数后面添加了一个 f 
 variable.ZapLog.Sugar().Infof("参数 userId %d\n",2020)

 variable.ZapLog.Sugar().Errorw("程序发生错误",zap.Error(error))
 variable.ZapLog.Sugar().Errorf("参数非法,程序出错,userId %d\n",2020)

 Warn  、 Panic 、Fatal用法类似
复制代码

温馨提示

gin的日志=nginx日志 gorm的日志=业务日志

分清楚每个日志的区别。不要把日志全部的混在一起。

在这里日志是这样管理的

  • 当处于调试模式,gin的日志会直接打出到控制台,gorm的日志会写入全局日志GoSkeletonLogName
  • 当处于开发模式,gin的日志会新建立一个文件GinLogName,写入到这里,然后其他日志写入全局日志中

总结:

zap是用来全局日志管理gorm日志。

根据模式是否开启gin日志。

//如果你用nginx做了代理,可以获取相关日志,不用gin去记录日志,开启生产模式
gin.SetMode(gin.ReleaseMode)
复制代码

猜你喜欢

转载自juejin.im/post/7034095392350273573