log4j
Posted Desneo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了log4j相关的知识,希望对你有一定的参考价值。
1. 描述和备注
a). 两种配置方式,log4j.xml和log4j.properties
b). 由3个东西组成,
"logger"--负责采集日志,程序中使用,有继承关系
"appender"--负责日志输出到哪里,控制台或文件
"layout"--定义日志输出的格式
1.1 Maven
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
1.14 日志打印时组件调用顺序
a). 日志信息传入 Logger.
b). 将日志信息封装成 LoggingEvent 对象并传入 Appender.
c). 在 Appender 中调用 Filter 对日志信息进行过滤,调用 Layout 对日志信息进行格式化,然后输出.
3. log4j.xml
3.1. 参考使用规则
a). 对于info、warning和error这几种错误,都需要输出到文件去,而且是不同的文件
b). 自动按天新建文件,避免单个日志文件过大
c). debug信息不需要输出到文件,只需要在控制台中显示
d). spring框架输出的debug信息太多,要屏蔽
3.2 Appender--日志位置
Log4j 提供的 appender 有以下几种:
1).org.apache.log4j.ConsoleAppender (控制台),
2).org.apache.log4j.FileAppender (文件),
3).org.apache.log4j.DailyRollingFileAppender (每天产生一个日志文件),
4).org.apache.log4j.RollingFileAppender (文件大小到达指定尺寸的时候产生一个 新的文件)
5).org.apache.log4j.WriterAppender (将日志信息以流格式发送到任意指定的地方)
3.2.1 示例-每天输出一个日志
<!--设置通道名称是:file,输出方式DailyRollingFileAppender-->
<appender name="FILE" class="org.jboss.logging.appender.DailyRollingFileAppender">
<!--日志文件路径和文件名称 -->
<param name="File" value="${jboss.server.home.dir}/log/server.log"/>
<!-- 设置是否在重新启动服务时,在原有日志的基础添加新日志 -->
<param name="Append" value="false"/>
<!-- Rollover at midnight each day -->
<param name="DatePattern" value="‘.‘yyyy-MM-dd"/>
<!-- Rollover at the top of each hour <param name="DatePattern" value="‘.‘yyyy-MM-dd-HH"/> -->
<!-- 日志输出格式 -->
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p [%c] %m%n"/>
</layout>
</appender>
3.2.2 cmi中实际使用示例
<appender name="SYSTEM_RUN_FILE"
class="com.huawei.mdn.cms.log.CMSAppender">
<param name="File" value="../logs/run/CMI_system_run" />
<param name="MaxFileSize" value="&runLogSize;" />
<param name="MaxBackupIndex" value="20" />
<param name="Append" value="true" />
<layout class="com.huawei.mdn.cms.log.MdnSystemRunLogLayout"/>
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="LevelMin" value="INFO"/>
<param name="LevelMax" value="FATAL"/>
</filter>
</appender>
3.2.3 filter标签
<!--过滤器设置输出的级别-->
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="levelMin" value="debug" />
<param name="levelMax" value="warn" />
<param name="AcceptOnMatch" value="true" />
</filter>
3.2.5 自定义Appender--如把日志发送到flute
继承AppenderSkeleton类-->[一般]实现Append方法即可
3.4. layout--日志格式
//内置layout
org.apache.log4j.htmlLayout(以HTML表格形式布局),
org.apache.log4j.PatternLayout(可自定义布局和输出内容)-- 常用
org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串),
org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息)
Log4J采用类似C的printf函数的格式化日志,打印参数如下: -- 常用 “[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n”
%m 输出代码中指定的消息
%p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL
%r 输出自应用启动到输出该log信息耗费的毫秒数
%c 输出所属的类目,通常就是所在类的全名
%t 输出产生该日志事件的线程名
%n 输出一个回车换行符,Windows平台为“rn”,Unix平台为“n”
%d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS},输出类似:2002年10月18日 22:10:28,921
%l 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。举例:Testlog4.main(TestLog4.java:10)
%M 调用logger的方法名。
3.4.1 示例参见3.3.1节
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p [%c] %m%n"/>
</layout>
</appender>
3.4.2 自定义layout--自定义输出格式
继承 TTCCLayout等内置的layout,或是layout接口-->实现format方法即可
public class MdnDebugLogLayout extends TTCCLayout
{
private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS";
public MdnDebugLogLayout()
{
}
@SuppressWarnings("unchecked")
public String format(LoggingEvent event)
{
LocationInfo locationInfo = event.getLocationInformation();
String lineNumber = locationInfo.getLineNumber();
String fileName = locationInfo.getFileName();
String threadName = event.getThreadName();
String message = event.getRenderedMessage();
setDateFormat(DATE_FORMAT);
buf.setLength(0);
buf.append("[");
buf.append(threadName);
buf.append("]");
dateFormat(buf, event);//日期时间
buf.append("|");
buf.append(event.getLevel().toString());//级别为debug
buf.append("|");
buf.append("CMI");//模块
buf.append("|");
String traceID = TraceContextHolder.getDataContext().getTraceID();//traceID
if (traceID != null)
{
buf.append(traceID);
}
buf.append("|");
buf.append(message);//代码中指定的消息
buf.append("|||");
buf.append(fileName);
buf.append("-");
buf.append(lineNumber);
buf.append(Layout.LINE_SEP);
return buf.toString();
}
@Override
public void dateFormat(StringBuffer buf, LoggingEvent event)
{
if (dateFormat != null)
{
date.setTime(event.timeStamp);
dateFormat.format(date, buf, pos);
}
}
}
3.5 catagory/root标签--定义打印日志的包
Logger Logger = LogManager.getLogger("categorylog"); (<category标签的name属性>) --> category --> Appender
category的name,指定的是控制某个包下的日志 , 可以按照业务逻辑进行日志分类输出打印
root是控制整个工程的日志
root和category都是通过<appender-ref ref="CONSOLE"/>执行具体appender中的日志策略,配置哪个appender执行哪个
root和category是父子关系,root标签可以不写,category也可以不写 , 但是必须写一个
category的属性additivity="false"表示在category中定义日志输在root中过滤掉
例如:定义name = “userManagerLog” , 那么在代码中与用户管理相关的业务引入日志的时候 LogManager.getLogger(“userManagerLog”) ,
则可以通过控制一个业务逻辑的日志打到一个文件下
<appender name="FILE-DEBUG" class="org.apache.log4j.DailyRollingFileAppender">
<param name="DatePattern" value="‘.‘yyyyMMdd" />
<param name="Append" value="true"/>
<param name="Threshold" value="DEBUG"/>
<param name="Encoding" value="UTF-8"/>
<param name="file" value="${profile.log.root.path}/${profile.log.name.web}/${profile.log.name.web}-debug.log"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} [%7r] %-5p %c %M:%L - %m%n"/>
</layout>
</appender>
<!-- 日志过滤,只打印 com.portal.controller路径下日志 -->
<category name="com.portal.controller">
<priority value="INFO"/>
<appender-ref ref="CONSOLE"/>
</category>
<root>
<priority value="INFO"/>
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE-DEBUG"/>
</root>
</log4j:configuration>
以上是关于log4j的主要内容,如果未能解决你的问题,请参考以下文章
log4j怎样控制只输出自己写的代码的日志,不输出框架中的日志
Log4j反序列化远程代码执行漏洞(CVE-2019-17571)
log4jspringboot项目启动 ,使用的druid数据源,log4j报错 log4j:WARN Please initialize the log4j system properly.(代码片