美文网首页
log4j2的使用(3)_实现一个满足自己需求的配置

log4j2的使用(3)_实现一个满足自己需求的配置

作者: BinaryBang | 来源:发表于2019-08-14 11:25 被阅读0次
    log4j2.jpg

    首先约定几个值:
    [ProjectName],代表自己的项目的名称;
    [CatalinaHome],代表自己的Tomcat服务器所在的目录;

    现在自己需要的日志系统需求如下:
    1,把系统info,warn,error和fatal级别的信息分别分开输出到[CatalinaHome]/logs/[ProjectName]/info.log,warn.log,error.log,fatal.log临时文件中,每次重启后删除原来的文件,记录重启后的信息;
    2,debug级别以及以上的信息输出到控制台;
    3,trace以及以上级别的信息,按照记录到[CatalinaHome]/logs/[ProjectName]/DetailLog/[ProjectName].log文件中;
    并且每过一天进行一次备份,备份的文件格式为:
    [CatalinaHome]/logs/[ProjectName]/DetailLog/[ProjectName]-%d{yyyy-MM-dd}.log

    我先给出最终实现了该功能的配置,然后针对该配置进行说明;
    log4j2.xml:

    <?xml version="1.0" encoding="UTF-8"?>
    
    <Configuration status="warn" monitorInterval="30">
     
         <Properties>
            <Property name="ProjectName">Study</Property>
            <Property name="infoLogFilePath">${sys:catalina.home}/logs/${ProjectName}/info.log</Property>
            <Property name="warnLogFilePath">${sys:catalina.home}/logs/${ProjectName}/warn.log</Property>
            <Property name="errorLogFilePath">${sys:catalina.home}/logs/${ProjectName}/error.log</Property>
            <Property name="fatalLogFilePath">${sys:catalina.home}/logs/${ProjectName}/fatal.log</Property>
            <Property name="traceLogFilePath">${sys:catalina.home}/logs/${ProjectName}/DetailLog/${ProjectName}.log</Property>
            <Property name="traceLogFilePattern">${sys:catalina.home}/logs/${ProjectName}/DetailLog/${ProjectName}-%d{yyyy-MM-dd}.log</Property>
            <Property name="pattern">[%d][%-5level][%logger]:%m%n</Property>
            <Property name="detailPattern">[%d{yyyy-MM-dd HH:mm:ss}][%-5level][%class{50}-%M-%L]:%msg%n</Property>
        </Properties>
        
        <Appenders>
        
             <Console name="CustomConsole" target="SYSTEM_OUT">
                <PatternLayout pattern="${pattern}"/>
             </Console>
             
              <File name="faInfo" fileName="${infoLogFilePath}" append="yes">
                 <PatternLayout pattern="${pattern}"/>
                 <Filters>
                    <ThresholdFilter level="debug" onMatch="deny" onMismatch="neutral"/>
                    <ThresholdFilter level="info" onMatch="accept" onMismatch="deny"/>
                </Filters>
             </File>
             
             <File name="faWarn" fileName="${warnLogFilePath}" append="yes">
                 <PatternLayout pattern="${pattern}"/>
                 <Filters>
                    <ThresholdFilter level="error" onMatch="deny" onMismatch="neutral"/>
                    <ThresholdFilter level="warn" onMatch="accept" onMismatch="deny"/>
                </Filters>
             </File>
             
             <File name="faError" fileName="${errorLogFilePath}" append="yes">
                 <PatternLayout pattern="${pattern}"/>
                 <Filters>
                    <ThresholdFilter level="fatal" onMatch="deny" onMismatch="neutral"/>
                    <ThresholdFilter level="error" onMatch="accept" onMismatch="deny"/>
                </Filters>
             </File>
             
             <File name="faFatal" fileName="${fatalLogFilePath}" append="yes">
                 <PatternLayout pattern="${pattern}"/>
                 <Filters>
                    <ThresholdFilter level="fatal" onMatch="accept" onMismatch="deny"/>
                </Filters>
             </File>
             
            <RollingFile name="rfaTrace" fileName="${traceLogFilePath}" filePattern="${traceLogFilePattern}">
                <PatternLayout pattern="${detailPattern}"/>
                <Policies>
                    <TimeBasedTriggeringPolicy  interval="1"/>
                </Policies>
                <DefaultRolloverStrategy max="3"/>
            </RollingFile>
            
         </Appenders>
         
         <Loggers>
             <Root  level="debug">
                 <AppenderRef ref="CustomConsole"/>
             </Root>
             <Logger name="fileLogger" level="fatal">
                <AppenderRef ref="faInfo"/>
                <AppenderRef ref="faWarn"/>
                <AppenderRef ref="faError"/>
                <AppenderRef ref="faFatal"/>
             </Logger>
             <Logger name="fileLogger.rollingFile" level="trace">
                <AppenderRef ref="rfaTrace" />
             </Logger>
         </Loggers>
     </Configuration>
    
    

    2 Properties元素

      <Properties>
        <Property name="name1">value1</Property>
        <Property name="name2" value="value2"/>
        <Property name="name3">value3</Property>
      </Properties>
    

    1,Properties元素是可选的,在Properties中可以定义若干个Property子元素;
    2,每个Property元素,以name和value的方式,定义了一个键值对,在后续的配置中,可以使用name来使用其对应的value;
    3,这种键值对方式的常量定义的优势具有普遍的意义,即:一改全改; 如果有很多地方需要使用一个name1的值value1,但是后期变动value1的值需要更改的时候,只需要修改name1常量定义的value1的值就好了,而不需要在每个使用name1的地方去修改;
    4,使用的方式为 ${name1}来通过变量的名称来获取变量的值;

    3 File元素

    File元素,指的是将LogEvent输出到指定的文件中,且该文件在每次重启的时候,会被删除重建,用来记录临时的信息;
    主要的属性有3个,name,fileName,append;

    • name,指定Appender的名称,在后续配置的Logger对象中,进行关联;
    • fileName,指定产生的日志文件的目录;
      元素都有一个fileName的属性,用来指定产生的日志的路径,
      如果使用相对路径,例如 fileName = "log/test.log"
      如果是run as java application,输出在本地项目文件的 LocalProject/log/test.log中;
      如果是在servlet中访问,日志是在 [UserDesktop]/log/test.log中;

    而为了让日志在tomcat的logs文件夹中,我们需要使用绝对路径,如:
    {sys:catalina.home}/logs/{ProjectName}/info.log
    其中${sys:catalina.home}这种方式,可以获得tomcat的目录;

    • append,值为yes和no,指定每次输出是否追加;yes,代表追加,这样在一次服务器启动的期间,输出的日志都可以保留;no,只保留最新输出的日志;
      可以包含的子元素有两个,PatternLayout,和Filters;
    • PatternLayout,用来指定日志的输出格式,详情可以参考球球第2章的文章;
    • Filters,定义过滤器,过滤器的使用可以查看本章第5节;

    4 RollingFile元素

    RollingFile,是将日志输出到指定文件,和File相比有两个区别:

    1. 重启之后不会删除原来的日志文件,而是继续在原来文件的后部写入;
    2. 可以按照指定的策略,对日志文件进行备份,然后创建新的文件进行记录,这个动作,叫做rollover;
      RollingFile元素的主要属性有,name,fileName,filePattern;
      name和fileName的作用和File元素一致,特有的是filePattern属性,该属性指定了当rollover条件满足时,对日志备份的备份文件的命名规则;
      RollingFile元素特有的子元素为Policies,用来指定rollover的条件,其中,TimeBasedTriggeringPolicy用来说明时间达到指定条件时rollover,interval属性需要和filePattern结合起来解释:

    示范配置中给定的fileName和filePatter分别为:

    fileName:
    <Property name="traceLogFilePath">${sys:catalina.home}/logs/${ProjectName}/DetailLog/${ProjectName}.log</Property>
    
    filePattern:
    <Property name="traceLogFilePattern">${sys:catalina.home}/logs/${ProjectName}/DetailLog/${ProjectName}-%d{yyyy-MM-dd}.log</Property>
    

    使用了%d{yyyy-MM-dd},表示rollover时,按照yyyy-MM-dd的格式将原来的文件进行备份;
    其中最小的时间单位为天;
    然后interval的值为1,那么结合起来就是每一天备份一次;

    假如服务器启动的时间为2019-08-14,初始启动的时候,所有的日志都记录在Study.log中,(球球的项目名称为Study);然后当2019-08-15再输出日志时,会触发rollover条件,首先将Study.log重命名为Study-2019-08-14.log,然后重新生成一个Study.log记录当日的日志,以此类推;

    5 只输出一个级别的日志:过滤器的使用规则

    1,每个appender中,可以通过定义Filters来详细指定输出的event级别;
    2,每个filter的主要属性有:

    • level,用来指明该过滤器的等级;
    • onMatch,值为3个deny,accept,neutral;当传递过来的LogEvent的等级大于等于level中指定的级别时,使用onMatch指定的策略处理该LogEvent.
      -- deny,表示丢弃该LogEvent,该Appender的后续Filter也没有机会处理该LogEvent;
      -- accept,表示处理该LogEvent,即按照该Appender的方式进行输出,后续的Filter也不会再处理该LogEvent;
      -- neutral,如果当前Filter为最后一个Filter,那么作用相当于Accept;如果不是,将该LogEvent传递给后续Filter处理;
    • onMismatch,当传递过来的LogEvent的等级小于当前FIlter指定的等级时的处理策略,对应的值也是3个,deny,accept,neutral;作用和上面是一样的;

    下面通过讨论几个过滤器的实际作用:

    5.1 只输出debug级别以下的信息;

    <Filters>
        <ThresholdFilter level="debug" onMatch="deny" onMismatch="neutral"/>
    </Filters>
    

    该过滤器说明:
    当LogEvent传递过来时,大于等于debug级别的,都不处理,丢弃,也不会传给后面的过滤器;
    因为当前是最后一个filter,neutral的作用和accept是一样的,所以小于debug级别的,处理并输出;
    最终效果是输出debug级别以下的信息;

    5.2 只输出info级别以上的信息;

    <Filters>
        <ThresholdFilter level="info" onMatch="accept" onMismatch="deny"/>
    </Filters>
    

    该过滤器说明:
    当LogEvent传递过来时,大于等于info级别的,进行输出;
    级别小于info的,丢弃掉;
    最终效果是输出info级别以上的信息;

    5.3 只输出info级别的信息;

    <Filters>
        <ThresholdFilter level="debug" onMatch="deny" onMismatch="neutral"/>
        <ThresholdFilter level="info" onMatch="accept" onMismatch="deny"/>
    </Filters>
    

    该过滤器是将前面两个过滤器结合起来了,说明如下:
    1a,大于等于debug级别的,都不打印,丢弃掉;
    1b,小于debug级别的,交给第二个过滤器定夺;
    1b.a,大于等于info级别的,进行输出;
    1b.b,小于info级别的,丢弃掉;
    最终效果是,只输出info级别的信息;
    通常要指定只输出一个级别的信息,需要两个过滤器的搭配使用;

    6 Logger和Appender的关联

    在配置Logger的时候,使用AppenderRef元素来讲该Logger和对应的Appender关联起来,这样,在使用该Logger对象产生LogEvent的时候,就会分配给每个与该Logger关联的Appender进行处理;
    所以,一个重要的问题就是要弄清楚每个Logger究竟管关联了哪些Appender;
    每个Logger关联的Appender有两部分:

    1. Logger自己关联Appender;

    2. Logger继承的父Logger关联的Appender;
      所以,需要理解以下Logger的继承

    6.1 Logger的定义和继承

    主要的规则如下:

    1. 首先需要配置一个根Logger,每个其他的Logger都会继承这个根Logger,定义方式为:
     <Root  level="debug">
                 <AppenderRef ref="CustomConsole"/>
    </Root>
    
    • level指定了该Logger所处理的日志级别,只有大于等于指定level的LogEvent,才会交给Appender进行处理,不满足条件的丢弃掉;
    • AppenderRef,就是指定当前Logger直接关联的Appender;
    1. 其余的Logger,根据name属性确定继承关系,定义方式为:
    <Logger name="fileLogger" level="info">
                <AppenderRef ref="faInfo"/>
                <AppenderRef ref="faWarn"/>
                <AppenderRef ref="faError"/>
                <AppenderRef ref="faFatal"/>
    </Logger>
    

    加入定义了4个其他的Logger,名字分别为a,a.b,a.b.c,a.c,这几个Logger的继承关系为:


    继承1.jpg

    就是通过符号'.'来表示继承关系,如果一个LoggerA的名字,和另一个LoggerB名字的.的前面部分一致,那么这个LoggerA就是LoggerB的父类;

    6.2 配置中Logger和Appender的关系

    配置中每个Logger和Appender的关系可以用下图表示:


    继承2.jpg

    所以最后那个Logger实际关联了6个Appender,也是满足本章一开始提的需求的logger了;

    6.3 实际使用

    实际使用时,使用如下代码获取名为fileLogger.rollingFile的logger并记录:

    Logger logger = LogManager.getLogger("fileLogger.rollingFile");
    logger.error("This is an error message!");
    logger.fatal("This is a fatal message");
    logger.info("This is an info message");
    logger.trace("This is a trace message");
    logger.debug("This is a debug message");
    logger.warn("This is a warn message");
    

    Reference

    1,log4j2配置文件详解
    2,log4j2子节点浅析
    3,5-log4j2.xml配置文件各个节点详解
    4,log4j2的log输出到tomcat/logs目录下及使用
    5,Log4j2研究之lookup
    6,Log4j2中RollingFile的文件滚动更新机制

    相关文章

      网友评论

          本文标题:log4j2的使用(3)_实现一个满足自己需求的配置

          本文链接:https://www.haomeiwen.com/subject/ejfgjctx.html