Coding 极简派

日志系统 - 福尔摩斯的线索(一)

fuermosi.jpeg

Everything comes in cycles.

近来负责发布项目的一个二方包给服务调用方, 即写一个client包给别人使用.
然后发现一个很重要的问题是,我们的代码部署在别人的机器上,出了问题很难定位. 所以解决方案是我们要打出规范的日志,然后日志上云做出业务统计分析以及故障报警等.

从门面说起 Facade design pattern

每个公司或者机构都有一个前台,比如银行, A想开户,B想找B1业务员询问基金信息. 如果没有前台,想象这个场景,每个人进去公司遍历查找,找到需要的人. 其间交错,冲突. 而如果有前台的化,每个人到前台说你要办理什么业务或者找什么人,前台小姐会把你自动转接给对应的业务人员,或者一个电话叫出你想要找的人.
这个就是门面的作用. 在设计模式中叫做Facade.
它有两个显而易见的好处:

  1. 对于客户端来说,它把系统内部复杂的组件隐藏封装起来,只向外暴露一个规范的高级接口. 降低了复杂性.
  2. 起到了解藕的作用,外部客户端和内部子系统之间的关系由Facade角色来实现,降低了系统的耦合.facade.png

挑选日志方案

SLF4J

全称是Simple Logging Facade for Java. 就是这样一个对于各种日志框架的接口/抽象,比如java.util.logging,logback, log4j.

  • 具体的日志框架是在发布时做binding的.SLF4J 的发布版本包含许多 jar包文件,作为”SLF4J bindings”,每一个binding都对应着一种它支持的日志框架.

    • slf4j-log4j12-1.7.22.jar 对应log4j version 1.2
    • slf4j-jdk14-1.7.22.jar Binding for java.util.logging, also referred to as JDK 1.4 logging
    • slf4j-nop-1.7.22.jar
      Binding for NOP, silently discarding all logging.

    • slf4j-simple-1.7.22.jar
      Binding for Simple implementation, which outputs all events to System.err. Only messages of level INFO and higher are printed. This binding may be useful in the context of small applications.

    • slf4j-jcl-1.7.22.jar
      Binding for Jakarta Commons Logging. This binding will delegate all SLF4J logging to JCL.

    • logback-classic-1.0.13.jar (requires logback-core-1.0.13.jar)
      NATIVE IMPLEMENTATION There are also SLF4J bindings external to the SLF4J project, e.g. logback which implements SLF4J natively. Logback’s ch.qos.logback.classic.Logger class is a direct implementation of SLF4J’s org.slf4j.Logger interface. Thus, using SLF4J in conjunction with logback involves strictly zero memory and computational overhead.

特征

  • 只需要在class path中放入slf4j api的jar包和对应binding的jar包(注意唯一性),在部署的时候,就会接入你想要的日志框架.
  • SLF4J 是不依赖于特定某一种类加载机制的. 每一个SLF4J binding是在编译时同对应的logging框架应链接的. 比如,slf4j-log4j12-1.7.22.jar binding在编译时同log4j绑定.
  • 对应的binding和下层日志框架见下图.

    bindings.png
  • 想要换日志系统,只要在class path中更新对应的binding,然后重启应用.

  • 如果类路径上没有binding,slf4j-api会默认使用no-operation implementation, 忽略所有的日志请求. 而不会因为找不到org.slf4j.impl.StaticLoggerBinder class而扔出NoCalssDefFoundError.

基本法则

  • embedded components 比如库或者框架不能声明依赖某一种SLF4J binding,而应该只依赖于slf4j-api.否则端用户就被迫依赖于某一种binding,这个和SLF4J的目的是相违背的.
  • 而对于普通的项目(非libraries,非frameworks),得益于maven的间接依赖,对于某种日志系统都可以通过一个简单的依赖声明
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.0.13</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.22</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId>
<version>1.7.22</version>
</dependency>

兼容性

slf4j-api.jar要和SLF4J binding的版本保持一直, 例如 slf4j-api-1.7.22.jar对应 slf4j-simple-1.7.22.jar, 而不能用slf4j-simple-1.5.5.jar,否则就会造成问题.
而不同version的 slf4j-api 不会发生冲突

Mapped Diagnostic Context (MDC) 支持

  • MDC 是应用程序提供的k-v pairs,日志框架维护并且插入到日志信息中.
  • MDC 数据可以很大程度上帮助信息过滤或者触发某些行为.
  • SLF4J 支持MDC,如果下层日志框架(logback,log4j)也支持,LSF4J会把工作delegate给下层框架的MDC,而如果下层logging框架不支持(j.u.l),SLF4J会自己存储MDC数据,之后需要用户自己编码来获取.

移花接木

如果你的系统里面已经使用了某种日志框架, SLF4J为你提供了平滑过度的桥接jar包.

  • 从Jakarta Commons Logging(JCL) 平滑迁移至SLF4J
    • jcl-over-slf4j.jar
      只需要把commons-logging.jar 换成jcl-over-slf4j.jar
    • 同时这个可以快速且永久地解决commons logging相关的类加载问题.
    • slf4j-jcl.jar 是SLF4J提供的JCL binding. 这个binding会把所有的logging calls 通过SLF4J delegate 给JCL.
    • 避免无限循环. 不能同时使用 jcl-over-slf4j.jar 和 slf4j-jcl.jar,因为前者会使JCL 把选择日志系统的职责交给SLF4J 但是后者会造成SLF4J 把职责交给JCL,造成一个infinite loop.
  • log4j-over-slf4j
    +log4j-over-slf4j.jar 和 slf4j-log4j12.jar 也不能同时使用
  • jul-to-slf4j bridge
    • 和上述两个模型 (reimplement log4j和commons-logging )不同的是, java.* namespace 下的package是不可替换的. 所以这里通过把LogRecord objects 翻译成对应的SLF4J equivalent. 这个翻译过程会带来很大的性能损失.
    • jul-to-slf4j.jar 和 slf4j-jdk14.jar 也不可以同时使用.legacy.png

SLF4J 官方文档的一个SLF4J优点总结

Advantage Description
Select your logging framework at deployment time The desired logging framework can be plugged in at deployment time by inserting the appropriate jar file (binding) on your class path.
Fail-fast operation Due to the way that classes are loaded by the JVM, the framework binding will be verified automatically very early on. If SLF4J cannot find a binding on the class path it will emit a single warning message and default to no-operation implementation.
Bindings for popular logging frameworks SLF4J supports popular logging frameworks, namely log4j, java.util.logging, Simple logging and NOP. The logback project supports SLF4J natively.
Bridging legacy logging APIs The implementation of JCL over SLF4J, i.e jcl-over-slf4j.jar, will allow your project to migrate to SLF4J piecemeal, without breaking compatibility with existing software using JCL. Similarly, log4j-over-slf4j.jar and jul-to-slf4j modules will allow you to redirect log4j and respectively java.util.logging calls to SLF4J. See the page on Bridging legacy APIs for more details.
Migrate your source code The slf4j-migrator utility can help you migrate your source to use SLF4J.
Support for parameterized log messages All SLF4J bindings support parameterized log messages with significantly improved performance results.

log4j

log4j是一套快而灵活的日志框架.(APIs)
可以通过配置文件在运行时动态配置. 对于它而言,日志可以分成不同的需求层次,并且可以有不同的destination.

3 main components:

  • loggers: Responsible for capturing logging information
  • appenders: Responsible for publishing logging information to vairious preferred destinations.
  • layouts: Responsible for formatting logging information in different styles.

架构

logback

现在logback越来越占据了工业界的主要地位.

日志采集系统架构

几乎所有的平台和系统每天哦读会产生大量的日志.一般是流式数据.对日志的分析可以为我们提供很多业务发展和系统监控所需的数据,所以需要一个日志采集系统来架起一座链接应用系统和日志分析系统的桥梁. 同时由于日志多是流式数据,希望这些系统可以支持近实时和离线的日志分析系统. 最后需要有高扩展性.

####所有典型的日志系统具有三个基本组件:

  • agent: 封装数据源,将数据源中的数据发送给collector.
  • collector: 接收多个agent的数据,并进行汇总后导入后端的storage中.
  • storage: 中央存储系统,应该具有可扩展性和可靠性.

####四个日志收集系统比较见下一篇博客

  • Facebook的scribe
  • Cloudera的Flume
  • LinkedIn的Kafka
  • Apache的Chukwa

reference:

m.blog.csdn.net/article/details?id=21240315
SLF4J官方文档 http://www.slf4j.org/manual.html
log4j官方文档

xubing wechat
奇闻共欣赏,疑义相与析.欢迎来我的微信公众号