log4j

log4j的实现原理与思考

2021-02-09  本文已影响0人  晴天哥_王志

系列

log4j的介绍

log4j的基本用法

log4j.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="https://jakarta.apache.org/log4j/" threshold="info" debug="false">

    <appender name="console" class="org.apache.log4j.ConsoleAppender">
        <param name="Target" value="System.out" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%-5p %c{1} - %m%n" />
        </layout>
        <filter class="org.apache.log4j.varia.LevelMatchFilter">
            <param name="LevelToMatch" value="INFO" />
            <param name="AcceptOnMatch" value="true" />
        </filter>
        <filter class="org.apache.log4j.varia.DenyAllFilter"/>
    </appender>

    <appender name="file" class="org.apache.log4j.RollingFileAppender">
        <param name="File" value="logs/main.log" />
        <param name="Append" value="true" />
        <param name="ImmediateFlush" value="true" />
        <param name="MaxFileSize" value="10MB" />
        <param name="MaxBackupIndex" value="5" />

        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d %d{Z} [%t] %-5p (%F:%L) - %m%n" />
        </layout>
    </appender>

    <logger name="com.journaldev.log4j" additivity="true">
        <level value="DEBUG" />
        <appender-ref ref="jdbc" />
    </logger>

    <logger name="com.journaldev.log4j.model" additivity="true">
        <level value="DEBUG" />
        <appender-ref ref="file" />
    </logger>

    <root>
        <priority value="DEBUG" />
        <appender-ref ref="console" />
    </root>

</log4j:configuration>

log4j使用

public static void main(String[] args) {
  DOMConfigurator.configure("log4j.xml");
  Logger logger = Logger.getLogger("org.apache.log4j.xml");

  logger.info("++++++++++");
}

log4j的核心组件介绍

log4j组件关系

// LogManager包含Hierarchy对象
public class LogManager {
  static private RepositorySelector repositorySelector;
  static {
    Hierarchy h = new Hierarchy(new RootLogger(Level.DEBUG));// Hierarchy保存Logger的所有信息
    repositorySelector = new DefaultRepositorySelector(h);
  }
}

// Hierarchy包含Logger对象
public class Hierarchy implements LoggerRepository, RendererSupport, ThrowableRendererSupport {
  Hashtable ht;   // 保存应用当中所有的Logger对象
  Logger root;    // 保存应用中的Root的Logger对象
  Level threshold; // 全局的日志打印范围
}

// Logger包含Appender对象
public class Category implements AppenderAttachable {
  protected String   name; // Logger的名字
  volatile protected Level level; // Logger的日志级别
  volatile protected Category parent; // Logger继承的父类
  AppenderAttachableImpl aai; //Logger的绑定的appender
  protected boolean additive = true; // Logger的是否继承的标记
}

public class AppenderAttachableImpl implements AppenderAttachable {
  protected Vector  appenderList; // appender的列表
}

// Appender对象包含Layout对象和Filter对象。
public abstract class AppenderSkeleton implements Appender, OptionHandler {
  protected Layout layout; // appender绑定的layout对象
  protected String name; // append的名称
  protected Priority threshold;
  protected Filter headFilter; // append绑定的filter列表的头指针
  protected Filter tailFilter;// append绑定的filter列表的尾指针
}

appender

org.apache.log4j.Appender(Appender的实现接口)

org.apache.log4j.net.SyslogAppender(打到远程日志服务器)
org.apache.log4j.jdbc.JDBCAppender(保存到数据库)
org.apache.log4j.RollingFileAppender(滚动文件,自动记录最新日志) 
org.apache.log4j.ConsoleAppender (控制台)  
org.apache.log4j.FileAppender (文件) 
org.apache.log4j.DailyRollingFileAppender (每天产生一个日志文件) 
org.apache.log4j.WriterAppender (将日志信息以流格式发送到任意指定的地方) 

Layout

org.apache.log4j.Layout

org.apache.log4j.helpers.DateLayout
org.apache.log4j.PatternLayout
org.apache.log4j.SimpleLayout

filter

org.apache.log4j.spi.Filter(Filter的实现接口)

org.apache.log4j.varia.LevelRangeFilter(日志等级范围过滤器)
org.apache.log4j.varia.StringMatchFilter(字符串匹配过滤器)
org.apache.log4j.varia.DenyAllFilter(拒绝所有日志的过滤器)
org.apache.log4j.varia.LevelMatchFilter(日志等级匹配过滤器)

log4j的日志输出过程

log4j的配置解析过程

log4j的日常应用

appender日志级别输出定制

 想实现将系统所有的warn日志统一收集到common-warn.log中,将系统所有的error日志统一收集到common-error.log中,通过配置appender当中的LevelRangeFilter过滤器来实现定制不同日志级别的日志输出。

日志脱敏

 想实现对日志中敏感信息进行脱敏,log4j打印日志最终是通过Appender来输出通过Layout格式化的日志,可以在自定义Appender或者自定义Layout来实现脱敏功能,当然暂时不考虑性能问题,只考虑可行性。

日志上报打点

 想实现通过打印日志来实现异常次数采集监控,log4j打印日志最终是通过Appender来输出日志,可以通过自定义Appender来实现日志拦截上报打点,也可以自定义Filter过滤器在过滤器执行过程中实现日志拦截上报打点。
 笔者所在的公司就是通过工程启动的时候在指定的logger对象的appender当中添加自定义的Filter对象来实现日志的拦截上报功能。

日志级别修改

 动态修改日志级别,LogManager提供动态获取Logger对象的接口进而可以修改日志级别。
 动态修改日志的Appender对象,Logger对象提供addAppender/removeAppender的扩展接口。
 动态修改日志的Filter对象,Appender对象提供addFilter的扩展接口。

上一篇 下一篇

猜你喜欢

热点阅读