日志模块的解析及应用

Context

日志的重要性不言而喻:定位单个问题、收集数据、汇总分析。

那么在当前的服务器越来越复杂的情况下,不清楚日志的记录时机、记录状态、所在位置,就会手足无措,不知道如何下手。

工欲善其事,必先利其器,首先对日志分个类吧。

日志的分类

类别 来源举例 收集分析工具 说明
访问日志 nginx、apache goaccess、 visitors 用户请求来源、IP、浏览器、最常用页面、出错页面
业务日志 python的logging模块 sentry、crashlog 业务的信息等出错信息
行为日志 业务自定义 自定义 分析用户的行为数据、如点击热点等
出错日志 代码级错误(crash) 如编译出错、导包问题等(500错误)

我们来分而治之。先介绍访问日志。

访问日志

用户发起HTTP请求,由服务器记录的当前访问的HTTP头信息,包括IP、请求URL、返回状态、来源、浏览器型号等。

主要由http服务器提供,时下流行的就有nginx, apache包括gunicorn等。

由于这种类型的日志格式较固定,因此对应的分析器也就非常容易了,常见的就是goaccess,visitors。

可以针对请求IP、请求URL、返回状态等进行自动分类整理,有利于对访客、访问量进行分析。

接下来就介绍业务日志。

业务日志

提到业务日志,这个就跟语言强相关了,不同的语言,处理框架不一样,因此可能在不同的语言里,也有不同的表现形式。

这里重点介绍python中的logging模块。

照例先介绍一下概念。

Logger(记录者)

用户区分不同的日志、相当于对于日志类的实例化对象。调用是使用logging.getLogger(logger_name),当logger_name不指定时,默认为root。

Handler(处理器)

用于处理日志的,一个日志输入可以有多个处理器,python中的常见处理器有这些处理器。
StreamHandler,流处理器,将日志输出到stdout或者stderr。
FileHandler,文件处理器,将日志输出到文件中,文件将一直增长下去。
RotatingFileHandler,自分割的文件处理器,会按文件大小,自动对文件切割。
TimedRotatingFileHandler,时间分割的文件处理器,会按时间来切割。
SocketHandler,套接字处理器,将数据发送到其它进程。
SMTPHandler,邮件处理器,发送邮件。

Formatter(格式)

定义的格式,一个处理器对应一个格式。

以下是它们的关系图

日志模块的关系图

可以看到,应用程序可以对应多个logger,而一个logger可以对应多个handler。

知道了他们的关系后,是能组合出非常多的功能的,比如下面的这些场景:

  1. 严重级别的错误,直接发送邮件知会
  2. 普通错误信息,汇总到一台服务器,进行收集整理,并可以与bug系统结合、用于跟踪解决。

行为日志

由于日志相对数据库来说,开销较小,数量也有较大上限,因此可以作为记录行为数据的最好载体。

比如用户在某一时间,做了什么操作,这个可以通过日志非常方便的管理与整理。

然后每天由定时任务自动对日志文件分析处理,再将分析之后的数据入库。

这个并没有现成的工具,需要结合业务自己来完成。

最后就是错误日志。

出错日志

其实像一些服务器500错误,这个是比较难定位的,很可能python编译都不通过(如缩进问题)。

甚至在logging模块加载前就出错了,这时日志里自然记录不到任何东西。

但是一般出错时,堆栈信息也会被扔到stderr中去,可以用另外的工具收集。