任何线上系统运行日志log都是至关重要的,当系统规模比较小时不存在系统间的调用完全是一个自治的系统,当系统发展到一定阶段势必需要和周边关联系统进行交互,尤其是在当今微服务盛行的时代,系统间的调用关系变得错综复杂,此时log将变得更加至关重要。
当系统崩溃、调用链失败等情况发生时,log将成为排查问题的唯一入手点,也可作为“甩锅”的证据。
在开发阶段我们可以直接输出到控制台,便于开发调试。但是,在生产环境我们需要把日志输出的文件以便查询和监控统计。那是不是说,任何情况下所有的日志都要输出,各种日志越详细越好呢?其实不然,日志输出到文件势必涉及到IO操作,大量的日志输出肯定会影响系统的性能。所以,不同场景配置不同的日志很重要。
任何开发语言的日志组件都分成了不同的级别,包括debug、info、warn、error等级别。一般在生产环境会将日志调整为error级别兼顾性能和排错。
Go作为一款优秀的定位为服务端分布式集群开发的语言其内置了标准log的支持。
我们先看一下Go语言内置log的简单使用。
以上日志输出
通过简单的日志使用,我们看到日志输出格式是日期时间 日志的msg。在通过日志排错定位问题的时候我们希望知道日志信息是从哪个代码文件的什么位置抛出的,go log为我们提供了自定义日志格式的功能,下面是go log包的我们可以控制日志输出参数,我们可以通过组合的方式进行日志格式的定义,以方便我们定位问题排错。
运行看看结果
我们看到,日志按照我们定义的格式进行了输出,这样我们就能快速定位到日志输出的位置以便排错。在项目开发过程中,为了规划整个项目的日志格式我们一般会通过init方法统一设定日志格式。
在实际的生产环境中我们会将日志统一集中汇集到我们的统一日志处理集群,比如大多数公司都在使用的ELK,此时区分不同项目的日志就显得尤为重要,go log也为我们考虑到了,可以通过调用SetPrefix方法来设置日志统一的前缀。
以上我们看到日志都是直接输出到控制台,在项目上线后,我们会将日志输出到文件,通过以下方式我们可以设置日志打印输出的位置。
执行 go run 后我们查看日志文件,我们可以看到日志正常输出到了我们指定的文件:
上面我们提到日志分级输出,我们可以通过go log包为我们提供的基础功能实现自己的分级日志输出功能,我们创建一个mylog的目录(包),编写一个log_util 的日志类 如下:
运行go run example.go
以上是我们通过go语言自带的log来实现的自己的日志工具。Go社区很强大,社区的大佬们为我们实现了更加强大好用的工具类,比如支持按照日期、大小滚动切割文件输出;有着更细致的日志级别有更高的更好的性能;支持各种插件可以直接对接elk、prometheus等。下面为大家介绍两款日志框架:
logrus : https://github.com/sirupsen/logrus
seelog:https://github.com/cihub/seelog
本节完。