Log4j2配置文件詳解

 

目錄[-]java

1 系列目錄

2 默認配置

原本覺得Log4J2應該有一個默認的配置文件的,不過好像沒有找到(經過DefaultConfiguration,初始化一個最小化配置),下面這個配置文件等同於缺省配置:web

<?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能夠有四種方法(其中任何一種均可以):spring

  1. 經過一個格式爲XML或JSON的配置文件。
  2. 以編程方式,經過建立一個ConfigurationFactory工廠和Configuration實現
  3. 以編程方式,經過調用api暴露在配置界面添加組件的默認配置。
  4. 以編程方式,經過調用Logger內部類上的方法。

注意,與Log4j 1.x不同的地方,公開的Log4j 2 API沒有提供任何添加、修改或刪除 appender和過濾器或者操做配置文件的方法。apache

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配置json

咱們上面的這個配置文件裏面還定義了一個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這個配置了。api

那有人就要問了,他不是也應該繼承了root的配置了麼,那麼會不會輸出兩遍呢?咱們在配置文件中給瞭解釋,若是你設置了additivity="false",就不會輸出兩遍spring-mvc

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配置:

複製代碼

<?xml version="1.0" encoding="UTF-8"?>
<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>
        <!-- 讀取classpath 以 applicationContext 開頭的文件做爲spring 的配置文件 -->
        <param-value>classpath*:applicationContext-*.xml</param-value>
    </context-param>
    <!-- 解決中文亂碼問題,將參數編碼爲utf-8 -->
    <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>
相關文章
相關標籤/搜索