文档章节

Java日志系统研究

landyking
 landyking
发布于 2016/07/18 23:23
字数 1130
阅读 147
收藏 7

基本功能

  1. 支持多个等级的日志打印:trace,debug,warning,error等等
  2. 支持按照不同的包名指定不同的等级
  3. 支持设置全局的默认日志等级
  4. 打印日志到单个或者多个文件,文件可以按指定大小或者按天进行滚动。

高级功能

NDC

NDC(Nested Diagnostic Context,嵌套诊断上下文)是基于栈的思想,信息可以被放到栈上或者从栈中移除。而栈中的值可以被Logger访问,并且Logger无需显式想日志方法中传入任何值。 代码示例:

String username = "admin";
String sessionID = "1234";
NDC.push(username);
NDC.push(sessionID);
try {
  // tmpFile doesn't exist, causing an exception.
  FileReader fr = new FileReader("tmpFile");
}
catch (Exception ex) {
  logger.error("Unable to open file.");
}
finally {
  NDC.pop();
  NDC.pop();
  NDC.remove();
}

Log4j的PatternLayout类通过%x转换字符从NDC中提取值。 代码配套配置:

<PatternLayout pattern="%x %-5p - %m%n" />

得到的结果:

admin 1234 ERROR – Unable to open file.

MDC

MDC(Mapped Diagnostic Context,映射调试上下文),是 log4j 和 logback 提供的一种方便在多线程条件下记录日志的功能。 MDC 可以看成是一个与当前线程绑定的哈希表,可以往其中添加键值对。MDC 中包含的内容可以被同一线程中执行的代码所访问。当前线程的子线程会继承其父线程中的 MDC 的内容。当需要记录日志时,只需要从 MDC 中获取所需的信息即可。MDC 的内容则由程序在适当的时候保存进去。对于一个 Web 应用来说,通常是在请求被处理的最开始保存这些数据。

代码示例:

public class MdcSample { 
    private static final Logger LOGGER = Logger.getLogger("mdc"); 
    public void log() { 
        MDC.put("username", "Alex"); 
        if (LOGGER.isInfoEnabled()) { 
            LOGGER.info("This is a message."); 
        } 
    } 
 }

配套的配置示例:

log4j.appender.stdout.layout.ConversionPattern=%X{username} %d{yyyy-MM-dd HH:mm:ss} [%p] %c - %m%n

将日志发送到syslog

SyslogAppenders将日志记录发送给本地或者远程系统的日志服务。syslog是一个接收日志事件服务,这些日志事件来自操作系统、进程、其它服务或者其它设备。 Log4j和Logback都内置支持SyslogAppenders。在Log4j中,我们创建SyslogAppender时,需要指定syslog服务监听的主机号、端口号以及协议。下面的示例演示了如何设定装置:

<Appenders>
  <Syslog name="SyslogAppender" host="localhost" port="514" protocol="UDP" facility="Auth" />
</Appenders>

在Logback中,我们可以实现同样的效果:

<appender name="SyslogAppender" class="ch.qos.Logback.classic.net.SyslogAppender">
  <syslogHost>localhost</syslogHost>
  <port>514</port>
  <facility>Auth</facility>
</appender>

动态设置日志等级

  1. 通过spring中的Log4jConfigListener,指定log4jConfigLocation和log4jRefreshInterval,例如:

     <context-param>
         <param-name>log4jConfigLocation</param-name>
         <param-value>classpath:log4j.xml</param-value>
     </context-param>
     <context-param>
         <param-name>log4jRefreshInterval</param-name>
         <param-value>60000</param-value>
     </context-param>
     <listener>
         <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
     </listener>
    

    这样spring会定时检查配置文件,然后更新日志等级。

    而Logback的参数中自带了一个定时扫描的参数,开箱即用。

  2. 对外暴漏接口,比如web接口。通过调用日志框架的API,运行时改变日志等级。例如:

     org.apache.log4j.Logger#setLevel(level:org.apache.log4j.Level)
     ch.qos.logback.classic.Logger(level:ch.qos.logback.classic.Level)
    

    注意改变等级前要先记录下原来的等级,要提供reset功能,回退到原始状态。

  3. 通过JMX调用更改。

各个日志框架之间的关系

纯接口抽象框架:

  1. JCL(Jakarta commons logger),日志接口,自带简单实现。apache社区的项目。
  2. SLF4J(Simple Logging Facade for Java),日志接口。

具有实现的框架:

  1. JUL(java util logger),JDK1.4之后提供的日志api。
  2. log4j,历史悠久,功能强大,使用广泛的一个日志库。不过性能不高,据说现在已经停止维护了。
  3. logback,是由log4j创始人设计的又一个开源日志组件。算是log4j的改良版,并且其实现了SLF4J API,意味着可以支持所有使用SLF4J的程序。
  4. log4j2,看名字就知道是log4j的后续升级版,同归于apache社区。受益于来自LMAX的Disruptor框架,log4j2在性能上有了很大提升,据说比log4j,logback都好。

转换

  1. JCL转换为SLF4J

        commons-logging#commons-logging -> org.slf4j#jcl-over-slf4j
    
  2. SLF4J转换为JCL

        org.slf4j#slf4j-api -> org.slf4j#slf4j-jcl
    

适配

  1. JCL适配log4j

        commons-logging#commons-logging -> log4j#log4j
    
  2. JCL适配logback

        commons-logging#commons-logging -> org.slf4j#jcl-over-slf4j -> ch.qos.logback#logback-classic		
    
  3. JCL适配log4j2

        commons-logging#commons-logging -> org.apache.logging.log4j#log4j-jcl -> org.apache.logging.log4j#log4j-core
    
  4. SLF4J适配log4j

        org.slf4j#slf4j-api -> org.slf4j#slf4j-log4j12 -> log4j#log4j
    
  5. SLF4J适配logback

        org.slf4j#slf4j-api -> ch.qos.logback#logback-classic
    
  6. SLF4J适配log4j2

        org.slf4j#slf4j-api -> org.apache.logging.log4j#log4j-slf4j-impl -> org.apache.logging.log4j#log4j-core
    

转换与适配示例代码

参考资料

  1. Java 日志管理最佳实践
  2. Java日志终极指南
  3. Log4jConfigListener动态改变记录级别及实现
  4. 动态修改log4j日志级别
  5. jdk-logging、log4j、logback日志介绍及原理

© 著作权归作者所有

共有 人打赏支持
landyking
粉丝 11
博文 50
码字总数 28330
作品 0
郑州
高级程序员
私信 提问
数据库中间件 Sharding-JDBC 源码分析 —— 分布式事务(一)之最大努力型

摘要: 原创出处 http://www.iocoder.cn/Sharding-JDBC/transaction-bed/ 「芋道源码」欢迎转载,保留摘要,谢谢! 本文主要基于 Sharding-JDBC 1.5.0 正式版 1. 概述 2. 最大努力送达型 3. 柔...

芋道源码
2017/11/05
0
1
Was(WebSphere)不能正常打印程序日志问题

【was日志配置】 服务器 -- 服务器类型 ——webSphere Appliaction server -- 选择sever -- java和进程管理 -- 进程定义 -- java虚拟机 ,调整“通用JVM参数”。 例如Log4j日志变量名称为:打...

gerry_pang
2014/01/09
0
0
Linux后台运行java -jar

问题描述 我打好的jar包,放在服务器上之后,在windows里面用xshell打开一个连接,然后运行java -jar 。。。。执行这个jar文件,当我关闭这个链接的时候为什么程序停止了呢? 打开XShell连接...

汪纬
2018/04/12
0
0
Java程序员该如何突破瓶颈!

一、源码分析 源码分析是一种临界知识,掌握了这种临界知识,能不变应万变,源码分析对于很多人来说很枯燥,生涩难懂。 源码阅读,我觉得最核心有三点:技术基础+强烈的求知欲+耐心。 我认为...

JAVA高级架构开发
2018/08/31
0
0
【转】Java Crash原因汇总

如果是Java进程不知道什么原因退出或被杀死,想要分析具体原因,一般来说分下面几步: 1. 拿到Java应用程序的日志文件 2. 查找JVM的致命错误日志 3. 查找操作系统的core dump文件 4. 使用Dtr...

mj4738
2011/12/04
0
0

没有更多内容

加载失败,请刷新页面

加载更多

四、RabbitMQ3.7在CentOS7下的安装

安装依赖 sudo yum install -y gcc gcc-c++ glibc-devel make ncurses-devel openssl-devel autoconf java-1.8.0-openjdk-devel git 创建yum源 vi /etc/yum.repos.d/rabbitmq-erlang.repo [......

XuePeng77
今天
2
0
android 延长Toast的时长

示例:myToast(5000,"hello"); public void myToast(int showTime, String msg) { Toast hello = Toast.makeText(getActivity(), msg, Toast.LENGTH_SHORT); new CountDownTimer(......

雨焰
昨天
4
0
浅谈mybatis的日志适配模式

Java开发中经常用到的日志框架有很多,Log4j、Log4j2、slf4j等等,Mybatis定义了一套统一的日志接口供上层使用,并为上述常用的日志框架提供了相应的适配器。有关适配器模式例子可以参考 设计...

算法之名
昨天
13
0
大数据教程(13.6)sqoop使用教程

上一章节,介绍了sqoop数据迁移工具安装以及简单导入实例的相关知识;本篇博客,博主将继续为小伙伴们分享sqoop的使用。 一、sqoop数据导入 (1)、导入关系表到HIVE ./sqoop import --connect...

em_aaron
昨天
3
0
Git cherry-pick 使用总结

应用背景:假设现在有两个分支:dev_01, dev_02. 如果我想把dev_01分支上的某几个commit合并到dev_02分支, 那么怎么办呢? 这就是cherry-pick的工作了。cherry-pick会捡选某些commit, 即把某...

天王盖地虎626
昨天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部