Log4j优化(一)扩展Log4j来实现性能优化的异步日志收集器

日志收集在互联网企业尤其是大数据时代是一件非常重要的事情,日志记录着用户行为和系统行为,是一种重要的数据来源。Log4j是Java应用程序使用的最多的一种日志收集工作。目前大量的Java应用程序都使用着Lo4j 1.2.X版本,Log4j 1.X版本饱受诟病的原因是使用了大量的锁,在高并发的情况下影响了系统的性能。这篇简单提供一种思路,说说如何扩展一下Log4j,提升一下Log4j的性能。


网上有很多分析Log4j源码的文章,这里不重复说了,只简单分析一下最重要的几个组件。

先看一下Log4j的配置文件log4j.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
	<appender name="rootAppender" class="org.apache.log4j.DailyRollingFileAppender">
		<param name="File" value="test.log" />
		<param name="DatePattern" value="'.'yyyy-MM-dd" />
		<layout class="org.apache.log4j.PatternLayout">
			<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %5p %c{1}:%L - %m%n" />
		</layout>
	</appender>
    <logger name="com.test" additivity="false">
        <level value="debug" />
        <appender-ref ref="rootAppender" />
    </logger>
	<root>
		<level value="debug" />
		<appender-ref ref="rootAppender" />
	</root>
</log4j:configuration>

从log4j.xml里面我们就可以看到Log4j最主要的几个组件

1. Logger,表示日志收集器,包含了各种Level下收集日志的方法,比如debug, info, error等。Logger的一个重要属性是additivity,表示是否附加到父Logger。Logger被设置成单根的树形结构,根就是Root,收集日志时,可以从叶子Logger一直往上直到Root。

Logger还包含了level表示级别,包含了一个appender列表,一个Logger可以对应多个Appender

2. Appender,表示如何处理日志,可以写本地文件,可以写远程文件,也可以输出到消息队列,等等。最常见的场景就是写本地文件。写文件的抽象是WriterAppender,封装了一个过滤器流QuietWriter。既然是过滤器流,那么可以包装节点流,默认的就是FileOutputStream流。Log4j也支持Buffer流,在WriterAppender的子类FileAppender里面有bufferedIO属性,如果采用Buffer流,就会在FileOutputStream外包一层BufferedWriter,最后在包到QuietWriter中。

 public
  synchronized
  void setFile(String fileName, boolean append, boolean bufferedIO, int bufferSize)
                                                            throws IOException {
    LogLog.debug("setFile called: "+fileName+", "+append);

    if(bufferedIO) {
      setImmediateFlush(false);
    }

    reset();
    FileOutputStream ostream = null;
    try {
          ostream = new FileOutputStream(fileName, append);
    } catch(FileNotFoundException ex) {
          String parentName = new File(fileName).getParent();
          if (parentName != null) {
             File parentDir = new File(parentName);
             if(!parentDir.exists() && parentDir.mkdirs()) {
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值