美文网首页程序员
log4j及log4j2在Spring MVC中的使用.md

log4j及log4j2在Spring MVC中的使用.md

作者: 7f2aceb77681 | 来源:发表于2018-07-28 08:22 被阅读70次

    项目已上线许久,项目中使用的是log4j 1.x版本,本来日志也可以正常记录,但是运维报怨说,你们的日志太大了,catalina.out日志输出无限大,以致有些应用出现服务器存储告警,所以建议我们:

    “应用日志必须对接公司统一日志平台,若同时也存放在本地服务器,则统一放在容器根目录下的单独文件夹,文件夹名称带有log字样,日志文件按日期或大小归档,单个日志文件超过20M的文件需要在归档时同时压缩,默认只保留最近一个月的日志,由代码实现自动清理。”

    总结日志管理需求:

    1. 日志写入到统一日志平台(ELK日志平台);
    2. 本地日志文件需按日期或大小归档;
    3. 单个日志文件如超过20M需在归档时压缩;
    4. 自动清理日志,默认保留近一个月日志;
    5. 关闭catalina.out日志输出;

    鉴于以上需求,我发现log4j 1.x版本有些做不到,而log4j 2.x版本正好可以很好的满足:

    1. Tomcat标准部署通过log4j配置无法关闭catalina.out日志输出;
    2. 无法自动清理日志,仅保存近一个月日志;
    3. 无法对超过20M的日志文件在归档时自动压缩;

    备注:不升级log4j,如何解决以上问题?
    1.通过Tomcat配置关闭catalina.out日志输出。

    # 直接找到Tomcat下bin/catalina.sh文件中以下代码片段:
    if [ -z "$CATALINA_OUT" ] ; then
      CATALINA_OUT="$CATALINA_BASE"/logs/catalina.out
    
    # 将上面的内容修改成下面内容即可:
    if [ -z "$CATALINA_OUT" ] ; then
      CATALINA_OUT=/dev/null # 输入到/dev/null黑洞
    

    2.通过编写服务器脚本、定时任务实现日志清理和压缩;

    以上两种方法也可以达到同样的目的,但是运维的同学才不愿意这么干,给你们提供个web容器,其它最好你们程序自己实现:)

    log4j2是log4j的升级版,log4j2除了可以满足以上需求,听说性能也更好,将旧项目中的log4j升级到log4j2的成本也较低。

    [TOC]

    一、log4j配置

    官方文档:http://logging.apache.org/log4j/1.2/apidocs

    1. Maven包引入

        <dependency>
          <groupId>org.slf4j</groupId>
          <artifactId>slf4j-api</artifactId>
          <version>1.7.19</version>
        </dependency>
        <dependency>
          <groupId>org.slf4j</groupId>
          <artifactId>slf4j-log4j12</artifactId>
          <version>1.7.19</version>
        </dependency>
        <dependency>
          <groupId>log4j</groupId>
          <artifactId>log4j</artifactId>
          <version>1.2.17</version>
        </dependency>
    

    2. log4j.properties配置文件

    log4j.properties配置文件

    log4j约定了其配置文件在默认加载类的路径下,即classpath的根路径,所以如最终发布在classpath根路径下,则在使用时无需指定路径。

    ### set log levels ###
    log4j.rootLogger=debug,stdout,debug,error,rsyslog
    #log4j.rootLogger=debug,debug,error,rsyslog
    
    ### 配置根Logger:设定日志记录的最低级别 ###
    log4j.category.org.springframework=ERROR
    log4j.category.org.apache=INFO
    log4j.logger.org.hibernate=ERROR
    
    ### 输出到控制台 ###
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.Target=System.out
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern=[%p][%d{yyyy-MM-dd HH:mm:ss}][%t] %l %m %n
    
    ### 输出到日志文件 ###
    log4j.appender.debug=org.apache.log4j.DailyRollingFileAppender
    log4j.appender.debug.File = ${catalina.home}/msp-logs/info.log
    log4j.appender.debug.datePattern='.'yyyy-MM-dd
    log4j.appender.debug.append=true
    log4j.appender.debug.Threshold=DEBUG
    log4j.appender.debug.layout=org.apache.log4j.PatternLayout
    log4j.appender.debug.layout.ConversionPattern=[%p][%d{yyyy-MM-dd HH:mm:ss}][%t] %l %m %n
    
    ### ERROR输出到日志文件 ###
    log4j.appender.error=org.apache.log4j.DailyRollingFileAppender
    log4j.appender.error.File = ${catalina.home}/msp-logs/error.log
    log4j.appender.error.datePattern='.'yyyy-MM-dd
    log4j.appender.error.append=true
    log4j.appender.error.Threshold=ERROR
    log4j.appender.error.layout=org.apache.log4j.PatternLayout
    log4j.appender.error.layout.ConversionPattern=[%p][%d{yyyy-MM-dd HH:mm:ss}] %l %m %n
    
    #appender rsyslog 端口不可配置,使用默认的:514
    log4j.appender.rsyslog=org.apache.log4j.net.SyslogAppender
    log4j.appender.rsyslog.syslogHost=11.4.74.26
    log4j.appender.rsyslog.Facility=local1
    log4j.appender.rsyslog.FacilityPrinting=true
    log4j.appender.rsyslog.header=true
    log4j.appender.rsyslog.layout=org.apache.log4j.PatternLayout
    log4j.appender.rsyslog.layout.conversionPattern=WEIXIN-MSP %d [%-5p] [%t] - %m%n
    

    3. web.xml配置

    web.xml配置文件中添加log4j监听器,其中webAppRootKey配置,可将对应日志写入到对应的项目下,缺省值是“webapp.root”,最好要定义,值随便填写,否则对于tomcat部署多个项目时,会冲突。

    <!-- log4j配置 -->
    <!-- 配置文件如放默认路径,log4jConfigLocation可不配 -->
    <context-param>
        <param-name>log4jConfigLocation</param-name>
        <param-value>WEB-INF/log4j.properties</param-value>
    </context-param>
    <context-param>
        <param-name>log4jRefreshInterval</param-name>
        <param-value>600000</param-value>
    </context-param>
    <context-param>
        <param-name>webAppRootKey</param-name>
        <param-value>webName.root</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.util.WebAppRootListener</listener-class>
    </listener>
    

    二、log4j2配置

    1. Maven包引入

            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
                <version>1.7.21</version>
            </dependency>
            <dependency>
                <groupId>org.apache.logging.log4j</groupId>
                <artifactId>log4j-api</artifactId>
                <version>2.3</version>
            </dependency>
            <dependency>
                <groupId>org.apache.logging.log4j</groupId>
                <artifactId>log4j-core</artifactId>
                <version>2.3</version>
            </dependency>
            <dependency>
                <groupId>org.apache.logging.log4j</groupId>
                <artifactId>log4j-slf4j-impl</artifactId>
                <version>2.3</version>
            </dependency>
    

    2. log4j2.xml配置文件

    <?xml version="1.0" encoding="UTF-8"?>
    <!--status指定log4j本身(log4j2这个程序)打印日志的级别-->
    <Configuration status="WARN" packages="">
        <Appenders>
            <!--输出至控制台的配置-->
            <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout charset="utf-8" pattern="%d{yyyy-MM-dd HH:mm:ss} %class{36} [%p] %m%n"/>
            </Console>
            <!--输出至日志文件的配置-->
            <RollingFile name="errorFile" fileName="${sys:catalina.base}/logs/error.log"
            filePattern="${sys:catalina.base}/logs/error.log.%d{yyyyMMdd}">
            <PatternLayout charset="utf-8" pattern="%d{yyyy-MM-dd HH:mm:ss} %class{36} [%p] %m%n"/>
            <Policies>
            <TimeBasedTriggeringPolicy modulate="true"/>
            </Policies>
            </RollingFile>
            <RollingFile name="infoFile" fileName="${sys:catalina.base}/wx-logs/info.log"
                         filePattern="${sys:catalina.base}/wx-logs/info.log.%d{yyyyMMdd}">
                <PatternLayout charset="utf-8" pattern="%d{yyyy-MM-dd HH:mm:ss} %class{36} [%p] %m%n"/>
                <Policies>
                    <TimeBasedTriggeringPolicy modulate="true"/>
                </Policies>
            </RollingFile>
            <!--输出至日志平台的配置 log4j2写入日志平台无法识别appName,希望采用facility=auth能与其它系统区别开-->
            <Syslog name="SYSLOG" format="RFC5424" host="11.4.74.26" port="514"
                    protocol="UDP" appName="WEIXIN-VUE-API" includeMDC="true"
                    facility="USER" enterpriseNumber="18060" newLine="true"
                    messageId="Audit" mdcId="mdc" id="App"
                    connectTimeoutMillis="1000" reconnectionDelayMillis="5000">
                <LoggerFields>
                    <KeyValuePair key="thread" value="%t"/>
                    <KeyValuePair key="priority" value="%p"/>
                    <KeyValuePair key="category" value="%c"/>
                    <KeyValuePair key="exception" value="%ex"/>
                    <KeyValuePair key="message" value="%m"/>
                </LoggerFields>
            </Syslog>
        </Appenders>
        <!--日志级别:All < Trace < Debug < Info < Warn < Error < Fatal < OFF.-->
        <Loggers>
            <!--只有定义了logger并引入的appender,appender才会生效-->
            <Logger name="error" level="error" additivity="false">
            <!--Logger的子节点,用来指定该日志输出到哪个Appender,如果没有指定,就会默认继承自Root.
            如果指定了,那么会在指定的这个Appender和Root的Appender中都会输出,此时我们可以设置Logger的additivity="false"
            只在自定义的Appender中进行输出-->
                <AppenderRef ref="SYSLOG"/>
                <AppenderRef ref="errorFile"/>
            </Logger>
            <!--Root用来指定项目的根日志,没有单独指定Logger,会统一输出到Root中-->
            <Root level="Info" additivity="false">
                <AppenderRef ref="SYSLOG"/>
                <AppenderRef ref="infoFile"/>
            </Root>
        </Loggers>
    </Configuration>
    

    3. 使用方式

    import org.apache.logging.log4j.LogManager;
    import org.apache.logging.log4j.Logger;
    
    // 普通使用
    private static final Logger LOGGER = LogManager.getLogger(HelloController.class);
    
    LOGGER.error("error log.");  // 会命中log4j2配置的Root项
    
    // 高级使用
    LogManager.getLogger("LoggerName01").error(error log.); 会命中log4j2配置的LoggerName01项
    
    LogManager.getLogger("LoggerName02").error(error log.); 会命中log4j2配置的LoggerName02项
    

    4. 按天分日志文件

            <RollingFile name="error_appender" fileName="${sys:catalina.base}/wx-logs/error.log" filePattern="${sys:catalina.base}/wx-logs/error-%d{yyyy-MM-dd}.log">
                <PatternLayout pattern="%-d{yyyy-MM-dd HH:mm:ss} [%thread] %m%n"/>
                <Policies>
                    <TimeBasedTriggeringPolicy modulate="true" interval="1"/>
                </Policies>
            </RollingFile>
    

    5. 按大小分日志文件

            <RollingFile name="error_appender" fileName="${sys:catalina.base}/wx-logs/error.log" filePattern="${sys:catalina.base}/wx-logs/error-%d{yyyy-MM-dd}-%i.log.gz">
                <PatternLayout pattern="%-d{yyyy-MM-dd HH:mm:ss} [%thread] %m%n"/>
                <SizeBasedTriggeringPolicy size="100 MB" />
            </RollingFile>
    

    相关文章

      网友评论

        本文标题:log4j及log4j2在Spring MVC中的使用.md

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