Log4j2使用笔记

项目背景

1 因为项目需要,需要对客户端的一个控件做访问日志记录。用以统计页面过去七天的平均数量。项目中一直使用Log4j1,这次升级使用Log4j2。准备将用户的登录id和设备id单独记录在一个日志文件中,每天生成一份文件,保留七天。

2 项目中使用Jetty作为web容器,Jetty将统一打印日志。但是这次的特殊统计,需要单独设置一个logger对象。输出到单独的日志文件。

第一部分: 原有的日志流程总结

1. log4j的配置方法

线上的日志应该是jetty打印的,log4j采用了SYSTEM_OUT的输出,没有指定。但是配置了具体的日志的格式和方法:

    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="[%date{yyyy-MM-dd HH:mm:ss.SSS}][%thread][%level][%class][%line]:%message%n"/>
        </Console>
    </Appenders>

说明:

  1. Console 的target是SYSTEM_OUT是输出到统一的输出流,没有指定日志文件

2. jetty的日志配置方法

jetty的启动配置文件xml在 jetty.xml

    <New id="ServerLog" class="java.io.PrintStream">
        <Arg>
            <New class="org.eclipse.jetty.util.RolloverFileOutputStream">
                <Arg>
                    <SystemProperty name="jetty.logs" default="./logs" />/<SystemProperty name="jetty.appkey" default="jetty" />.log.yyyy_mm_dd
                </Arg>
                <Arg type="boolean">true</Arg>
                <Arg type="int">10</Arg>
                <Arg>
                    <Call class="java.util.TimeZone" name="getTimeZone">
                        <Arg>GMT+8</Arg>
                    </Call>
                </Arg>
                <Arg type="string">yyyy-MM-dd</Arg>
                <Arg type="string"></Arg>
                <Get id="ServerLogName" name="datedFilename" />
            </New>
        </Arg>
    </New>

    <Call class="org.eclipse.jetty.util.log.Log" name="info">
        <Arg>Redirecting stderr/stdout to <Ref id="ServerLogName"/></Arg>
    </Call>
    <Call class="java.lang.System" name="setErr">
        <Arg>
            <Ref id="ServerLog"/>
        </Arg>
    </Call>
    <Call class="java.lang.System" name="setOut">
        <Arg>
            <Ref id="ServerLog"/>
        </Arg>
    </Call>

同时具体的参数配置在 boot.init 和 mms启动文件之中: 文件配置之中:

JVM_ARGS="-server -Dfile.encoding=UTF-8 -Dapp.key=apollo-item -Dsun.jnu.encoding=UTF-8 -Djava.io.tmpdir=/tmp -Djava.net.preferIPv6Addresses=false -Duser.timezone=GMT+08 -Djava.util.prefs.systemRoot=/home/sankuai/.java -XX:-LoopUnswitching -XX:-OmitStackTraceInFastThrow"

在mms的启动文件之中的代码。说明(mms文件时 线上的jetty启动配置文件)

    EXEC_JAVA=$EXEC_JAVA" -Djetty.appkey=$MODULE -Djetty.context=$CONTEXT -Djetty.logs=$LOG_ROOT"
    LOG_ROOT=/opt/logs/mobile

日志打印流程说明

  1. 配置文件log4j.xml 中的<Console name="Console" target="SYSTEM_OUT">表示 log4j2将日志配置到System.out输入到控制到输出流。

  2. Jetty中对于所有的控制台输出流统一进行处理,有一个ServerLog的配置部分代表将所有的
    控制台输出流统一输出到文件之中,使用到了org.eclipse.jetty.util.RolloverFileOutputStream类,这个类的定义式:
    RolloverFileOutputStream This output stream puts content in a file that is rolled over every 24 hours.代表将输出流放到一个每24小时产生一个新的文件的日志之中。

  3. 然后具体的文件输出地址与日志打印的格式都在<Arg>标签中进行了详细的配置。相应的参数从jetty的启动命令中获取。语句<SystemProperty name="jetty.logs" default="./logs" />/<SystemProperty name="jetty.appkey" default="jetty" />.log.yyyy_mm_dd 代表了日志的输出文件地址。


第二部分 - 新的日志配置

1 项目背景:

原有的项目中所有的日志都是统一到一个日志文件中,但是产品临时需要对一个功能进行统计分析,需要进行单独的日志处理。这时就需要设计一个新的日志对象并增加一个新的日志输出流,从其他的统一日志中进行区分,以用于单独的统计与分析功能。具体的配置过程如下ji:

2 具体配置

配置appender(日志输出源)

        #配置一个新的appender(输出流 - 直接打到文件输出流)
        <RollingFile name="Daijia" fileName="/opt/logs/mobile/apolloitem/daijia"
                     filePattern="'.'yyyy-MM" Append="true" >
            <PatternLayout pattern="%-5p:%d:%c{1} [%x] - %m%n"/>
            <Policies>
                <SizeBasedTriggeringPolicy size="16 MB"/>
            </Policies>
            <DefaultRolloverStrategy fileIndex="min" max="16"/>
        </RollingFile>

说明

  1. RollingFile代表新增加一个appender(输出源),日志名称是Daijia, fileName代表的则是 日志文件的输出地点,这里采用了绝对路径,也可以采用相对路径。

配置一个日志对象

        <logger name="com.meituan.apollo.item.filter.util.VListResultModelFilterUtil" level="info" additivity="false">
            <appender-ref ref="Daijia" />
        </logger>

在Root里面配置新的AppendRef

配置根日志

        <Root level="INFO">
            <AppenderRef ref="Console"/>
            #if($environment == 'online')
            <AppenderRef ref="Sentry"/>
            #end
            # <AppenderRef ref="Daijia"/>
        </Root>

说明

  1. Root里面都代表日志的根日志,所有其他的日志都集成来自Root,如果把一个Appender放到<Root>的根日志配置下面,则所有的log对象都会输出到这些源头。我们想单独记录记录E代驾的日志,所以就不把代驾的输出源放到根日志下面了.

3 配置log4j中应该注意的地方(或者说遇到的坑)

1 log4j迁移的问题

1)问题

2015-11-02 17:38:02,742 ERROR Appenders contains an invalid element or attribute "appender"
2015-11-02 17:38:02,746 ERROR Unable to locate appender Daijia for logger
2015-11-02 17:38:02,746 ERROR Unable to locate appender Daijia for logger com.meituan.apollo.item.controller.IndexControlle

2)原因与解决办法

appender这个标签在log4j.xml中是违法的,第一次出现这个问题的时候很纳闷,因为这是从网上复制拷贝的配置语法。但是仔细深入发现之后,问题在于<appender>标签是属于log4j 1的版本,升级到log4j2之后,不再支持原有<appender>标签。

log4j1的console输出源

  <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
    <layout class="org.apache.log4j.PatternLayout">
      <param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
    </layout>
  </appender>

迁移到log4j2之后的语法配置就应该是;

    <Console name="STDOUT" target="SYSTEM_OUT">
      <PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
    </Console>

同样对于所有的输出流式日志文件的<appender>标签同样是这样的配置语法。具体的log4j2迁移参考官网:Migrating from Log4j 1.x

2 RollingFile必须加上参数大小的配置

1)问题

2015-11-02 18:28:06,742 ERROR A TriggeringPolicy must be provided
2015-11-02 18:28:06,743 ERROR Null object returned for RollingFile in Appenders.
2015-11-02 18:28:06,747 ERROR Unable to locate appender Daijia for logger com.meituan.apollo.item.filter.util.VListResultModelFilterUtil
2015-11-02 18:28:06,748 ERROR Unable to locate appender Daijia for logger

2)原因与解决办法
出现这个问题是因为采用了<RollingFile>是因为,RollingFile的输出流代表指定输入到指定参数的文件之中,然后根据的指定的策略重新覆盖日志文件。所以<RollingFile>必须配置 TriggeringPolicy(触发策略) 和 RolloverStrategy(覆盖策略)这两个参数,否则出错。这里采取的策略是根据日志大小进行重新覆盖SizeBasedTriggeringPolicy.并采用了默认的覆盖行为DefaultRolloverStrategy进行重新覆盖。

详细的<RollingFile>的输出流配置可以参考:log4j2中Appender的配置


参考资料链接:

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

推荐阅读更多精彩内容

  • 在应用程序中添加日志记录总的来说基于三个目的:监视代码中变量的变化情况,周期性的记录到文件中供其他应用进行统计分析...
    时待吾阅读 4,924评论 1 13
  • 在应用程序中添加日志记录总的来说基于三个目的:监视代码中变量的变化情况,周期性的记录到文件中供其他应用进行统计分析...
    时待吾阅读 4,953评论 0 6
  • 一、Log4j简介 Log4j有三个主要的组件:Loggers(记录器),Appenders (输出源)和Layo...
    默默守护阅读 1,897评论 2 8
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,717评论 6 342
  • #########################################################...
    BearFaraway阅读 1,754评论 0 51