服务分层后统一的日志
2 日志的处理
服务分层后各个模块都将有日志记录产生,将这些日志分类存储的同时保障检索查看的便利是一件不容易的事情。
2.1 日志的控制台输出
我们可以使用fmt或者 log 直接在控制台显示日志,但是大多数时候,我们希望较为清晰的记录用户和系统的行为,并为服务运行提供指导建议。
操作系统,服务,业务都在输出日志,现在有不同的工具帮助我们在不同级别实现记录。 在实时数据检索和分析场景提供帮助。
2.2 使用 logrus
logrus 是一个可插拔的、结构化的日志框架。
*1.日志级别:
logrus 拥有六种日志级别:debug、info、warn、error、fatal 和 panic。
*2.Hook 机制:
允许使用者通过 hook 的方式将日志分发到任意地方。
*3.日志格式:
可以定制日志输出格式,另外logrus 集成了JSONFormatter 和 TextFormatter两种日志格式
*4.Field 机制:
logrus 鼓励通过 Field 机制进行精细化的、结构化的日志记录,而不是通过冗长的消息来记录日志
日志轮换相关函数
`WithLinkName` 为最新日志建立软连接
`WithROtationTime` 设置日志分割时间,多久袼一次
`WithMaxAge` 设置清理文件前 最长保留时间
`WithRotationCount` 设置文件清理前最多保持的 个数
我们显现文件名和行号, 记录日志文件路径 和 文件名,并以浮点数形式返回 持续时间,
我们配置为每隔1分钟轮转一个新文件,保留最近3分钟的 ,其他的则删除, 记录自定义日志。
然后在系统层调用这个返回的对象,就可以使用 不同级别的日志,并且自动每天轮换。
也记录 翻转失败的错误。
func InitLog() *logs.Logger {
Logger := logs.New()
Logger.SetReportCaller(true)
writer, err := rotatelogs2.New(
paths+"\\webserver.%Y%m%d%H.log",
rotatelogs2.WithLinkName(paths+"\\webserver.log"),
rotatelogs2.WithMaxAge(24*time.Hour),
rotatelogs2.WithRotationTime(time.Duration(3600)*time.Second),
)
if err != nil {
Logger.Printf("failed to create rotatelogs: %s", err)
}
Logger.SetOutput(writer)
Logger.SetFormatter(&logs.TextFormatter{
ForceColors: true,
DisableColors: false,
ForceQuote: true,
DisableQuote: false,
EnvironmentOverrideColors: true,
DisableTimestamp: false,
FullTimestamp: true,
TimestampFormat: "2006-01-02 15:04:05.8156471 +0800 CST",
DisableSorting: false,
DisableLevelTruncation: true,
PadLevelText: false,
QuoteEmptyFields: true,
})
return Logger
}
logrus已经处于维护状态,因此在中小型项目中使用即可。在某些大型开源项目中有适应, 现在维护者并不推荐在大型项目使用。
2.3 使用 zap
uper提供的开源组件zap是另一个中大型项目的选项,它完美的把不同模块的内容记录在不同地方。
只需要定义名称即可
logger = NewZapLogger("apis-zoos")
我们可以使用日期和模块名称去区分它们。
y, month, d := time.Now().Date()
minthInt := MonthDate[month.String()]
days := fmt.Sprintf("%v%v%v/", y, minthInt, d)
if TName == "" {
TName = ProjectName
}
logFileName := BaseLog + days + TName + "_access.log"
accessLogger, err := logger.NewJSONLogger(
logger.WithDisableConsole(),
logger.WithField("configs", fmt.Sprintf("%s[%s]", TName, env.Active().Value())),
logger.WithTimeLayout(timeutil.CSTLayout),
logger.WithFileP(logFileName),
)
if err != nil {
panic(err)
}
return accessLogger
其输出结果如下。
d----- 7:20 20221220
d----- 7:20 202311
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 7:30 1801 apis-zoos_access.log
-a---- 7:19 18010 db-cron_access.log
-a---- 7:24 650 db-redis-main.log
-a---- 7:25 4334 db-redis_access.log
-a---- 7:44 162 services_access.log
-a---- 7:44 39090 systems-zoos_access.log
具体内容如下:
{"level":"info","time":"2021-01-01 14:25:55","caller":"zoos/sys_zoo.go:126","msg":"new case:10 exec:WhatTheRightThingToDoTheClaimsOfCommunity.mp4","configs":"systems-zoos[test]"}
2.4 使用数据库架构
诸如ELK,EBK的结构(Elasticsearch, Logstash,Kibana),它解决了记录的搜索和查找问题。 但是也增加了相当的复杂度。
它包括各种插件以方便将日志输出到不同数据库,支持处理nginx,postfix,ossec,windows,mysql,java等等日志处理。
并且提供监控平台,和支持缓存扩展。 它也支持插件开发扩展功能。
有机会专门立文介绍。
3 小结
本节简单介绍几个日志系统的使用方式。
每一个系统都有良好的社区文档支持,适应不同的场景。
- 点赞
- 收藏
- 关注作者
评论(0)