Log4j2配置文件详解

Stella981
• 阅读 1117

目录[-]

1 系列目录

2 默认配置

本来以为Log4J2应该有一个默认的配置文件的,不过好像没有找到(通过DefaultConfiguration,初始化一个最小化配置),下面这个配置文件等同于缺省配置:

    <?xml version="1.0" encoding="UTF-8"?>  
    <configuration status="OFF">  
        <appenders>  
            <Console name="Console" target="SYSTEM_OUT">  
                <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>  
            </Console>  
        </appenders>  
        <loggers>  
            <root level="error">  
                <appender-ref ref="Console"/>  
            </root>  
        </loggers>  
    </configuration>

3 第一个配置例子

配置Log4j 2可以有四种方法(其中任何一种都可以):

  1. 通过一个格式为XML或JSON的配置文件。
  2. 以编程方式,通过创建一个ConfigurationFactory工厂和Configuration实现
  3. 以编程方式,通过调用api暴露在配置界面添加组件的默认配置。
  4. 以编程方式,通过调用Logger内部类上的方法。

注意,与Log4j 1.x不一样的地方,公开的Log4j 2 API没有提供任何添加、修改或删除 appender和过滤器或者操作配置文件的方法。

Log4j能够自动配置本身在初始化期间。当Log4j启动它将定位所有的ConfigurationFactory插件和安排然后在加权从最高到最低。Log4j包含两个ConfigurationFactory实现,一个用于JSON和XML。加载配置文件流程如下:

  1. Log4j将检查“Log4j的配置文件“系统属性,如果设置,将尝试加载配置使用 ConfigurationFactory 匹配的文件扩展

  2. 如果没有系统属性设置JSON ConfigurationFactory log4j2-test将寻找。 json或 log4j2-test。json在类路径中。

  3. 如果没有这样的文件发现XML ConfigurationFactory log4j2-test将寻找。 xml在 类路径。

  4. 如果一个测试文件无法找到JSON ConfigurationFactory log4j2将寻找。 log4j2.jsn json或 在类路径中。

  5. 如果一个JSON文件无法找到XML ConfigurationFactory将试图定位 log4j2。 xml在类路径中。

  6. 如果没有配置文件可以找到了 DefaultConfiguration 将被使用。 这将导致日志输出到控制台。

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration status="OFF">
        <appenders>
            <Console name="Console" target="SYSTEM_OUT">
                <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
            </Console>
        </appenders>
        <loggers>
            <!--我们只让这个logger输出trace信息,其他的都是error级别-->
            <!--
            additivity开启的话,由于这个logger也是满足root的,所以会被打印两遍。
            不过root logger 的level是error,为什么Bar 里面的trace信息也被打印两遍呢
            -->
            <logger name="cn.lsw.base.log4j2.Hello" level="trace" additivity="false">
                <appender-ref ref="Console"/>
            </logger>
            <root level="error">
                <appender-ref ref="Console"/>
            </root>
        </loggers>
    </configuration>
    

我们这里看到了配置文件里面是name很重要,没错,这个name可不能随便起(其实可以随便起)。这个机制意思很简单。就是类似于java package一样,比如我们的一个包:cn.lsw.base.log4j2。而且,可以发现我们前面生成Logger对象的时候,命名都是通过 Hello.class.getName(); 这样的方法,为什么要这样呢? 很简单,因为有所谓的Logger 继承的问题。比如 如果你给cn.lsw.base定义了一个logger,那么他也适用于cn.lsw.base.lgo4j2这个logger。名称的继承是通过点(.)分隔的。然后你可以猜测上面loggers里面有一个子节点不是logger而是root,而且这个root没有name属性。这个root相当于根节点。你所有的logger都适用与这个logger,所以,即使你在很多类里面通过类名.class.getName() 得到很多的logger,而且没有在配置文件的loggers下面做配置,他们也都能够输出,因为他们都继承了root的log配置

我们上面的这个配置文件里面还定义了一个logger,他的名称是 cn.lsw.base.log4j2.Hello ,这个名称其实就是通过前面的Hello.class.getName(); 得到的,我们为了给他单独做配置,这里就生成对于这个类的logger,上面的配置基本的意思是只有cn.lsw.base.log4j2.Hello 这个logger输出trace信息,也就是他的日志级别是trace,其他的logger则继承root的日志配置,日志级别是error,只能打印出ERROR及以上级别的日志。如果这里logger 的name属性改成cn.lsw.base,则这个包下面的所有logger都会继承这个log配置(这里的包是log4j的logger name的“包”的含义,不是java的包,你非要给Hello生成一个名称为“myhello”的logger,他也就没法继承cn.lsw.base这个配置了。

那有人就要问了,他不是也应该继承了root的配置了么,那么会不会输出两遍呢?我们在配置文件中给了解释,如果你设置了additivity="false",就不会输出两遍

4 复杂一点的配置

    <?xml version="1.0" encoding="UTF-8"?>
    <!--
        Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出。 
    -->
    <!--
        monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数。
    -->
    <configuration status="error" monitorInterval=”30″>
        <!--先定义所有的appender-->
        <appenders>
            <!--这个输出控制台的配置-->
            <Console name="Console" target="SYSTEM_OUT">
                <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
                <ThresholdFilter level="trace" onMatch="ACCEPT" onMismatch="DENY"/>
                <!--这个都知道是输出日志的格式-->
                <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
            </Console>
            <!--文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,这个也挺有用的,适合临时测试用-->
            <File name="log" fileName="log/test.log" append="false">
                <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
            </File> 
            <!-- 这个会打印出所有的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
            <RollingFile name="RollingFile" fileName="logs/app.log"
                     filePattern="log/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">
                <PatternLayout pattern="%d{yyyy-MM-dd 'at' HH:mm:ss z} %-5level %class{36} %L %M - %msg%xEx%n"/>
                <SizeBasedTriggeringPolicy size="50MB"/>
                <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件,这里设置了20 -->
                <DefaultRolloverStrategy max="20"/>
            </RollingFile>
        </appenders>
        <!--然后定义logger,只有定义了logger并引入的appender,appender才会生效-->
        <loggers>
            <!--建立一个默认的root的logger-->
            <root level="trace">
                <appender-ref ref="RollingFile"/>
                <appender-ref ref="Console"/>
            </root> 
        </loggers>
    </configuration>
  • 扩展组件

    1. ConsoleAppender:输出结果到System.out或是System.err。
    2. FileAppender:输出结果到指定文件,同时可以指定输出数据的格式。append=“false”指定不追加到文件末尾
    3. RollingFileAppender:自动追加日志信息到文件中,直至文件达到预定的大小,然后自动重新生成另外一个文件来记录之后的日志。
  • 过滤标签

    1. ThresholdFilter:用来过滤指定优先级的事件。
    2. TimeFilter:设置start和end,来指定接收日志信息的时间区间。

4.1 Appender之Syslog配置

log4j2中对syslog的简单配置,这里就不重复展示log4j2.xml了:

<Syslog name="SYSLOG" host="localhost" port="514" protocol="UDP" facility="LOCAL3"/>

host是指你将要把日志写到的目标机器,可以是ip(本地ip或远程ip,远程ip在实际项目中很常见,有专门的日志服务器来存储日志),也可以使用主机名,如果是本地,还可以使用localhost或127.0.0.1。

Port指定端口,默认514,参见/etc/rsyslog.conf(以Fedora系统为例,下同)。protocol指定传输协议,这里是UDP,facility是可选项,后面可以看到用法。

4.2 Syslog及Syslog-ng相关配置(Fedora)

在运行程序之前,需要修改:/etc/rsyslog.conf

把这两行前的#去掉,即取消注释:

#$ModLoad imudp
#$UDPServerRun 514

这里启用udp监听,514是默认监听端口,重启syslog:

service syslog restart

大部分日志会默认写到/var/log/messages中,如果不想写到这个文件里,可以按下面修改,这样local3的日志就会写到app.log中。这里的local3即 log4j2.xml中facility的配置。

*.info;mail.none;authpriv.none;cron.none;local3.none                /var/log/messages

新增一行:

local3.*                                                            /var/log/app.log

除了使用自带的syslog,我们也可以使用syslog的替代品,比如syslog-ng,这对于log4j2.xml配置没有影响。 安装:

yum install syslog-ng

启动:

service syslog-ng start

其配置文件为:

/etc/syslog-ng/syslog-ng.conf

启动前把source一节中这一行取消注释即可:

#udp(ip(0.0.0.0) port(514));

这个端口会和syslog冲突,可以使用别的端口比如50014,同时修改log4j2.xml中的port属性。另外提一下,使用非默认端口,要求log4j版本在1.2.15或以上。

syslog-ng本身也可以设置把日志送到远程机器上,在源机器上的syslog-ng.conf中添加:

destination d_remote1 {udp(153.65.171.73 port(514));};

这表示源机器上的syslog-ng会把接收到的日志送到远程主机153.65.171.73的514端口上,只要保证153.65.171.73上的syslog-ng正常运行并监听对应的端口即可。

5 Log4j2与Spring集成

web.xml配置:

Log4j2配置文件详解

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app\_3\_1.xsd" id="WebApp_ID" version="3.1"> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:applicationContext-*.xml</param-value> </context-param> <filter> <filter-name>encodingFilter</filter-name> <filter-class> org.springframework.web.filter.CharacterEncodingFilter </filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>

<filter\>
    <filter-name\>shiroFilter</filter-name\>
    <filter-class\>org.springframework.web.filter.DelegatingFilterProxy</filter-class\>
    <init-param\>
        <param-name\>targetFilterLifecycle</param-name\>
        <param-value\>true</param-value\>
    </init-param\>
</filter\>

<!-- Make sure any request you want accessible to Shiro is filtered. /\* catches all \-->
<!-- requests.  Usually this filter mapping is defined first (before all others) to \-->
<!-- ensure that Shiro works in subsequent filters in the filter chain: \-->

<filter-mapping\>
    <filter-name\>shiroFilter</filter-name\>
    <url-pattern\>/\*</url-pattern\>
</filter-mapping\>

<!-- log4j2-begin for servlet 2.5
  <listener>
        <listener-class>org.apache.logging.log4j.web.Log4jServletContextListener</listener-class>
    </listener>
    <filter>
        <filter-name>log4jServletFilter</filter-name>
        <filter-class>org.apache.logging.log4j.web.Log4jServletFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>log4jServletFilter</filter-name>
        <url-pattern>/\*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>INCLUDE</dispatcher>
        <dispatcher>ERROR</dispatcher>
    </filter-mapping>
     log4j2-end \-->

<!-- log4j2-begin for servlet version >3.0\-->
<context-param\>
    <param-name\>log4jConfigLocation</param-name\>
    <param-value\>/WEB-INF/classes/log4j2.xml</param-value\>
</context-param\>

<listener\>
    <listener-class\>org.springframework.web.context.ContextLoaderListener</listener-class\>
</listener\>
<servlet\>
    <servlet-name\>dispatcher</servlet-name\>
    <servlet-class\>org.springframework.web.servlet.DispatcherServlet</servlet-class\>
    <init-param\>
        <param-name\>contextConfigLocation</param-name\>
        <param-value\>classpath\*:spring-mvc.xml</param-value\>
    </init-param\>
    <load-on-startup\>1</load-on-startup\>
    <async-supported\>true</async-supported\>
</servlet\>
<servlet-mapping\>
    <servlet-name\>dispatcher</servlet-name\>
    <url-pattern\>/</url-pattern\>
</servlet-mapping\>

<display-name\>IotSupport</display-name\>

</web-app>

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
Java获得今日零时零分零秒的时间(Date型)
publicDatezeroTime()throwsParseException{    DatetimenewDate();    SimpleDateFormatsimpnewSimpleDateFormat("yyyyMMdd00:00:00");    SimpleDateFormatsimp2newS
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这