log4j 2 入门实例(1)
本文介绍log4j的基本概念和将日志输出到控制台的例子。
参考文章:
http://www.jianshu.com/p/464058bdbc76
http://www.hankcs.com/program/java/log4j-2-console-color-configuration-with-intellij-idea.html
Log4J是什么?
Log4J是Apache基金会下一个开源的日志管理项目,可以高度自定义日志的收集过程,和收集粒度,以及收集后日志的输出位置,可以输出到控制台,文件,数据库,甚至是远程服务器,这些操作仅仅只需要通过Log4J的配置文件进行定义后便可实现,是一个非常方便而且强大的日志收集库。除此之外,Log4J提供多语言兼容,可以在Java,Python,.Net等语言环境下的服务器中使用,可以对服务集群的日志进行统一管理。
Log4j 2升级了不少API,拓展性更好。
Log4J学习
Log4J三大组件:
1. Logger(记录器):只管记录日志(根据日志级别记录),不管日志存储在什么地方。
2. Appender(存放器):将Logger记录的日志,存放到配置文件中所指向的地方,只处理日志的存放过程。
3. Layout(布局):将日志进行格式化后再输出,也就是说他是用来让日志看这更顺眼的。当然如何算顺眼,由你在配置文件中设定。
一个Logger可以有多个Appender,可以同时输出到多个设备上,每一个Appender都有一个Layout来格式化输出内容。
Logger 组件
有一个默认的logger——root,如果我们不定义其它logger,就会默认使用这个名为root的logger。
Appender 组件
Appender用来决定日志要输出到什么地方,支持一下目的地:
- ConsoleAppender 将信息输出到控制台(*常用)
- FileAppender 输出信息到文件中(*常用)
- RollingFileAppender 输出信息到文件中,可以根据策略清空文件和备份文件(*常用)
- SocketAppender 套接口服务器(Remote Socket Server)
- AsyncAppender 将信息输出到其它appender中
- CassandraAppender 将信息输出到Apache Cassandra数据库中
- FailoverAppender 封装一组Appender,如果前面的Appender失败了,那么就用后面的Appender,直到输出信息成功
- FlumeAppender 将信息输出到一个Apache Flume中,用于收集、集成、移动大量的log数据
- JDBCAppender 通过JDBC方式,将数据输出到相关数据库中
- JMSAppender 将信息输出到一个JMS服务中
- JPAAppender 通过Java Persistence API,将数据输出到相关数据库中
- KafkaAppender 将信息输出到Apache Kafka中
- MemoryMappedAppender 将信息输出到内存中,主要用于减少磁盘IO操作,提升系统性能
- NoSQLAppender 将信息输出到一个非SQL数据库中
- RewriteAppender 将信息处理后(例如,掩盖账号密码),输出到其它Appender
- RoutingAppender 将信息分类,然后分别输出到其它Appender
- SMTPAppender 将信息通过邮件发送出来
- ScriptAppenderSelector 调用脚本得到一个Appender的名字,并创建这个Appender
- Syslogappender 通过BSD Syslog或者RFC5424格式,将信息发送远程服务器中
- ZeroMQAppender 将信息发送到ZeroMQ端节点
Layout 组件
Layout组件决定日志的输出格式,有如下几类:
- CSVLayout 以CSV格式输出日志
- GELF Layout 全称是Graylog Extended Log Format
- HTMLLayout 以HTML格式输出日志
- JSONLayout 输出信息到JSON字符串中
- PatternLayout 以自定义Pattern的模式输出日志(*常用)
- RFC5424Layout 加强版的syslog
- SerializedLayout 输出信息到字节流
- SyslogLayout BSD Syslog方式
日志级别
我们现在要调用logger的方法,不过在这个Logger对象中,有很多方法,所以要先了解log4j的日志级别,log4j规定了默认的几个级别:trace<debug<info<warn<error<fatal等。这里要说明一下:
1)级别之间是包含的关系,意思是如果你设置日志级别是trace,则大于等于这个级别的日志都会输出。
2)这不同的级别的含义大家都很容易理解,这里就简单介绍一下:
trace: 是追踪,就是程序推进以下,你就可以写个trace输出,所以trace应该会特别多,不过没关系,我们可以设置最低日志级别不让他输出。
debug: 调试么,我一般就只用这个作为最低级别,trace压根不用。是在没办法就用eclipse或者idea的debug功能就好了么。
info: 输出一下你感兴趣的或者重要的信息,这个用的最多了。
warn: 有些信息不是错误信息,但是也要给程序员的一些提示,类似于eclipse中代码的验证不是有error 和warn(不算错误但是也请注意,比如以下depressed的方法)。
error: 错误信息。用的也比较多。
fatal: 级别比较高了。重大错误,这种级别你可以直接停止程序了,是不应该出现的错误么!不用那么紧张,其实就是一个程度的问题。
入门实例
1、 新建一个Java工程,导入Log4j2包,pom文件中对应的配置代码如下:
注:log4j只用一个jar包,log4j2需要用两个jar包。
<dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.8</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.8</version> </dependency>
2、 resources目录下创建log4j2.xml文件
注:log4j使用property文件,log4j2使用xml文件。
<?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="trace"> <appender-ref ref="Console"/> </root> </loggers> </configuration>
解释一下:
- configuration后面的status:这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出。一般不用关注内部信息,设定为OFF即可。
- console是一个Appender,可以将信息输出到控制台。
- patternlayout是console对应的layout。1)参数%d指日期,H,m,s,S依次为时分秒毫秒;2)%t参数指产生该日志的线程名称。3)%level参数指日志级别,数字5指字符占位5个字符宽度;4)%logger参数指logger的名称,即语句private static final Logger logger = LogManager.getLogger(App.class.getName())中App.class.getName()的值,参数是整数n(只支持正整数),则先将logger名称依照小数点(.)分割成n段,然后取右侧的n段。5)%msg指要记录的信息;6)%n指换行。
- root是一个默认的logger,如果不定义特定的logger,则都会使用这个logger。level=“trace”表示trace及其以上级别的信息都将被输出。
- appender-ref指将要使用的Appender。
3、输出日志的例子如下
import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; public class Hello { public static org.apache.logging.log4j.Logger logger = LogManager.getLogger(Hello.class.getName); public static void main(String[] args) { add(1, 2); } public static int add(int a , int b) { logger.entry(a, b);//trace级别的信息,单独列出来是希望你在某个方法或者程序逻辑开始的时候调用,和logger.trace("entry")基本一个意思 logger.info("我是info信息"); logger.warn("我是warn信息"); logger.error("我是error信息"); logger.fatal("我是fatal信息"); logger.printf(Level.TRACE, "%d+%d=%d", a, b, a + b);//这个就是制定Level类型的调用:谁闲着没事调用这个,也不一定哦! logger.exit(a + b);//和entry()对应的结束方法,和logger.trace("exit");一个意思 return a + b; } }
即可在控制台看到
20:39:35.937 [main] TRACE com.hankcs.Hello - entry params(1, 2) 20:39:35.938 [main] INFO com.hankcs.Hello - 我是info信息 20:39:35.938 [main] WARN com.hankcs.Hello - 我是warn信息 20:39:35.938 [main] ERROR com.hankcs.Hello - 我是error信息 20:39:35.938 [main] FATAL com.hankcs.Hello - 我是fatal信息 20:39:35.939 [main] TRACE com.hankcs.Hello - 1+2=3 20:39:35.939 [main] TRACE com.hankcs.Hello - exit with(3)