log4j配置总结

数字沐虹人
• 阅读 3604
转载请注明文章出处:https://tlanyan.me/log4j-conf...

log4j是阿帕奇日志服务(Apache Logging Services)旗下的一款强大的开源日志输出工具。log4j使用上简洁便利,高效且拓展性强,几乎是Java编程的必备依赖包。除Java专用的log4j,阿帕奇日志服务网站还有log4net、log4php等其他编程语言对应的包。

项目使用log4j作为日志组件,出于细分日志的需求,要对配置文件做较大变动。之前对一些概念理解不是很到位,趁此机会抽空回顾官方的教程,收获不少。因项目使用的1.2系列的jar包,本文整理自1.2版本的官方文档。

重要概念

先回顾log4j中的三个重要概念:logger、appender和layout。三者合力决定日志是否应该输出、输出到哪里、输出格式是什么。

Logger

logger是输出日志的对象实例。除根logger外,其余均是命名logger,通常以调用的类名为其名字。名字中的点(.)是log4j划分层级的依据(与包package的组织方式相同),例如名字为com.tlanyan的logger是com.tlanyan.service的logger的父级。

根logger是logger中的特殊存在,原因有三:

  1. 它总是存在,无需手动创建;
  2. 它的输出等级不能为空(null);
  3. 不能通过名字获取其引用,只能通过Logger.getRootLogger获取。

信息分为六种等级:trace、debug、info、warn、error和fatal,分别对应Logger类的六个打印方法。等级之间有大小关系,trace等级最低,fatal最高。

理解logger的层级和继承是正确使用log4j的关键,即log4j不能确定某个值时,默认会向上回溯直到找到根logger。例如根logger的appender默认总是被子logger继承,会导致子logger中的信息多次输出,冗余又低效;子级的level继承自父级,低于父级的信息会被无意间过滤,等等。

Appender

appender是日志输出的目的地,每个appender是实现了Appender接口的类具现化实例。常用的appender类有:

  1. FileAppender及其子类:将日志输出到文件中;
  2. ConsoleAppender,将日志输出到标准输出;
  3. JDBCAppender,将日志保存到数据库。

除了配置常规属性值,appender中一个重要的特性是过滤器(filter)。过滤器对到达appender的信息做进一步过滤,最终确定是否输出。常用的过滤器有LevelRangeFilterStringMatchFilter

Layout

layout(布局)隶属于appender,对信息进行输出前的格式化。例如增加打印时间,调用的文件名、线程等,或者按照xml格式输出日志。最常用的布局是PatternLayout,可配置的成员变量是ConversionPattern,格式与C语言中的printf函数相同,具体含义请参考官方文档。

配置

配置log4j的方式主要有三种:1. 通过程序代码;2. 键值对形式的properties配置文件;3. xml配置文件。后两者简单易懂,且支持修改文件后配置即时生效,建议采用。

layout在appender中配置,所以配置文件主要由两部分组成:logger和appender。xml文件格式良好,层级关系更明显,相对properties文件本人更偏爱xml格式。下面是log4j的一个简单xml配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>

    <appender name="INFO" class="org.apache.log4j.RollingFileAppender">
        <param name="File" value="./logs/app-info.log"/>
        <param name="Append" value="true"/>
        <param name="MaxFileSize" value="50MB"/>
                 <param name="MaxBackupIndex" value="10"/>
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="[%-5r][%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l %m%n"/>
        </layout>
        <filter class="org.apache.log4j.varia.LevelRangeFilter">
            <param name="LevelMin" value="INFO"/>
            <param name="LevelMax" value="INFO"/>
        </filter>
    </appender>

    <appender name="pay" class="org.apache.log4j.DailyRollingFileAppender">
        <param name="File" value="./logs/pay-data.log"/>
        <param name="DatePattern" value="'.'yyyy-MM-dd"/>
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="[%-5r][%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l %m%n"/>
        </layout>
    </appender>

    <appender name="ERROR" class="org.apache.log4j.RollingFileAppender">
        <param name="File" value="./logs/app-error.log"/>
        <param name="Append" value="true"/>
        <param name="MaxFileSize" value="50MB" />
        <param name="MaxBackupIndex" value="20" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="[%-5r][%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l %m%n"/>
        </layout>
        <filter class="org.apache.log4j.varia.LevelRangeFilter">
            <param name="LevelMin" value="WARN"/>
            <param name="LevelMax" value="ERROR"/>
        </filter>
    </appender>

    <logger name="com.tlanyan.pay" additivity="false">
        <level value="info"/>
        <appender-ref ref="pay"/>
    </logger>

    <root>
        <level value="info"/>
        <appender-ref ref="INFO"/>
        <appender-ref ref="ERROR"/>
    </root>

</log4j:configuration>

配置文件定义了三个appender,两个logger。注意根logger没有名字,要用root来引用。名字为pay的logger不继承父级(additivity="false"),所以其中的信息不会输出到app-info.log中。

建议在程序入口配置log4j并监听配置文件:

 DOMConfigurator.configureAndWatch("config/log4j.xml", 10000L);

通过监听文件变化,可实现配置在修改后即时生效,无需改动代码,也无需重启程序。

参考

  1. http://logging.apache.org/log...
  2. http://logging.apache.org/log...
点赞
收藏
评论区
推荐文章
blmius blmius
4年前
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
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Wesley13 Wesley13
4年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Karen110 Karen110
4年前
一篇文章带你了解JavaScript日期
日期对象允许您使用日期(年、月、日、小时、分钟、秒和毫秒)。一、JavaScript的日期格式一个JavaScript日期可以写为一个字符串:ThuFeb02201909:59:51GMT0800(中国标准时间)或者是一个数字:1486000791164写数字的日期,指定的毫秒数自1970年1月1日00:00:00到现在。1\.显示日期使用
Jacquelyn38 Jacquelyn38
4年前
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
4年前
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
4年前
PHP创建多级树型结构
<!lang:php<?php$areaarray(array('id'1,'pid'0,'name''中国'),array('id'5,'pid'0,'name''美国'),array('id'2,'pid'1,'name''吉林'),array('id'4,'pid'2,'n
Easter79 Easter79
4年前
TurnipBit开发板DIY呼吸的吃豆人教程实例
  转载请以链接形式注明文章来源(MicroPythonQQ技术交流群:157816561,公众号:MicroPython玩家汇)  0x00前言  吃豆人是耳熟能详的可爱形象,如今我们的TurnipBit也集成了这可爱的图形,我们这就让他来呼吸了~。  0x01效果展示  先一起看下最终的成品演示视频:  http:/
Wesley13 Wesley13
4年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
4年前
C++笔记002:VS2010报错:LINK fatal error LNK1123 转换到 COFF 期间失败文件无效或损坏
 原创笔记,转载请注明出处!点击【关注】,关注也是一种美德~错误描述:1已启动生成:项目:FirstCode,配置:DebugWin321生成启动时间为2018/2/521:00:30。1InitializeBuildStatus:1 正在
Python进阶者 Python进阶者
2年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
数字沐虹人
数字沐虹人
Lv1
他乡共酌金花酒,万里同悲鸿雁天
文章
2
粉丝
0
获赞
0