log4j主要包含三个组件,分别对应为:Loggers、appenders与layouts。他们彼此协作,使得程序可以依据不同层次记录日志,在运行时控制这些日志的输出格式以及将这些日志记录到对应的场所。
在log4j中,一个Logger可以多种方式输出某条日志记录。而每个格式都有一个appender表示,具体的输出方式有:控制台,文件,GUI 组件,远程socket流,JMS等........ 一个logger可以映射到多个appender对象上面。框架在实现appender功能时,也实现了继承属性。即在命名层次中,子结点可以继承祖先结点的appender对应的输出方式。当然子结点也可以选择不继承这种属性,那么对应的子节点logger对象可以调用addAdditivity函数取消祖先结点遗留下来的appender功能。如下图所示:
日志对象名 | 自行添加的appenders功能 | 叠加(additivity)标志 | 输出日志方式 | 注释 |
---|---|---|---|---|
root | A1 | not applicable | A1 | The root logger is anonymous but can be accessed with the Logger.getRootLogger() method. There is no default appender attached to root. |
x | A-x1, A-x2 | true | A1, A-x1, A-x2 | Appenders of "x" and root. |
x.y | none | true | A1, A-x1, A-x2 | Appenders of "x" and root. |
x.y.z | A-xyz1 | true | A1, A-x1, A-x2, A-xyz1 | Appenders in "x.y.z", "x" and root. |
security | A-sec | false | A-sec | No appender accumulation since the additivity flag is set tofalse . |
security.access | none | true | A-sec | Only appenders of "security" because the additivity flag in "security" is set to false . |
大多数时间,我们在实现输出日志信息时都伴随着日志输出格式的设定。这就需要将layouts关联到某个appender上,layouts的职责便是按照用户的需求格式化对应的输出信息。在标准log4j版本中使用PatternLayout制定输出格式,有点C中的printf的味道。例如在PatternLayout中使用"%r [%t] %-5p %c - %m%n"参数会输出下面的内容:176 [main] INFO org.foo.Bar - Located nearest gas station
其中%r对应为:使用这个系统所消耗的毫秒时间
%t:使用这个log请求对应的线程
%-5p:log语句对应的级别
%c: 对应的对应的使用对象
%m%n: 为最终的用户自己定义的输出内容。