snail-log

一个灵活可扩展的轻量日志框架。

View project on GitHub

认识Snail Log

几条简单的基础概念

  1. Logger是日志记录器,Appender是实际上进行日志输出的类,Layout对日志输出消息进行格式化,他们都是一对一的关系;
  2. 在Slog中Logger通过相互基础的方法来实现灵活组合的日志输出,默认情况下每个Logger都会继承RootLogger
  3. Filter是Slog的核心功能,通过不同级别的过滤器相互配合能够实现日志精准的输出控制。

认识Logger和Logger的继承机制

Logger基础结构图

Logger是Slog的核心,通过操作Logger对象进行日志信息的输入输出,Appender是实际上进行日志信息输出的对象,LoggerAppender具有一对一的关系,当创建一条日志信息满足Logger设置的日志级别要求时,Logger将其封装成LoggingEvent消息实体传给AppenderAppender根据内部的Filter进行过滤,通过过滤后使用Layout将消息转换为指定的样式进行输出。

除了rootLogger根日志记录器以外,每个日志记录器必定有父日志记录器,当没有显式指定父日志记录器时,默认根日志记录器为父日志记录器。Logger处理完日志消息后都将传给父日志记录器进行处理,直到根日志记录器,但是如果生成日志未达到的日志记录器的打印级别,那么将直接跳过本次日志打印,不会再去寻找父日志记录器。Logger的继承关系有助于灵活的组合和不同的Appender打印要求。

认识Node

在Slog中,所有日志记录器配置class过滤信息都将生成为Node中的一条记录。根据.分隔Node将会被分成一个具有继承关系的链路,根节点为Null,如包名com.nineya.slog将生成如下一条关系链路:

Node的继承关系

Node链路中的配置同样具有继承关系,当产生一条日志消息时,将从Null节点开始往后遍历包名的节点,子节点具有更高的权重,但是当子节点未进行配置时,将返回已有的父节点的配置信息。这样的结构可以方便我们通过包名进行日志控制,当需要对指定包中的所有子包进行日志控制时,只需要对父包名进行配置。

Logger的消息过滤

日志输出流程

之所以在这里描述消息过滤是因为这个至关重要,消息的过滤与控制是本日志框架的核心功能。上图是一条日志消息输出的流程,一条日志消息要输出出来,它将经过过滤,通过所有过滤之后才可以进行输出。

首先,在生成一条日志消息时会对LoggerLevel进行过滤,如果过滤未通过则直接丢弃该条消息,这是最基础的过滤。通过过滤后将消息封装为LoggerEvent,接下来它将面临三层过滤。第一层是LoggerFilter的过滤,该过滤器对当前Logger有效,对父Logger无效;第二层是全局Logger,该过滤器对所有Logger的所有Appender都有效;通过这两层过滤后,消息将被传送给AppenderAppender将对LoggerEvent进行最后一次过滤,这次过滤通过后进行日志输出。