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

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的文件滚动更新机制

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,165评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,720评论 1 298
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,849评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,245评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,596评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,747评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,977评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,708评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,448评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,657评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,141评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,493评论 3 258
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,153评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,890评论 0 198
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,799评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,685评论 2 272