前言:前面使用Maven搭建SSM框架的时候我们曾经配置过log4j.properties文件,那么这个文件主要是干什么的呢?配置的格式有哪些?日志是大型Web应用中不可缺少的部分,Apache的开源项目Log4J是一个功能强大的日志组件,提供方便的日志记录。
一、Log4j简介
1、Log4j的概念
Log4J 是 Apache 的一个开源项目,通过在项目中使用 Log4J,我们可以控制日志信息输出到控制台、文件、GUI 组件、甚至是数据库中。我们可以控制每一条日志的输出格式,通过定义日志的输出级别,可以更灵活的控制日志的生成过程。
最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要过多修改应用的代码,非常方便项目的调试。
简而言之,Log4J是一个功能强大的日志工具,通过简单的配置文件就可以提供方便的日志记录。
2、Log4j组成
Log4J 主要由 Loggers (日志记录器)、Appenders(输出端)和 Layout(日志格式化器)组成。
Loggers 指定日志的输出级别与日志是否输出;
Appenders 指定日志信息的输出目的地(输出到控制台、文件等);
Layout 指定日志信息的输出格式。
3、Lo4j日志信息级别
Log4j 在 org.apache.log4j.Level 类中定义了OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL七种日志级别:
注:一般只使用4个级别,优先级从高到低为 ERROR > WARN > INFO > DEBUG,分别用来指定这条日志信息的重要程度。
4、定义Log4j.properties配置文件
其实可以完全不使用配置文件,而是在代码中配置Log4j环境。但是使用配置文件将使您的应用程序更加灵活,满足自定义需求。
Log4j支持两种配置文件格式,一种是XML格式的文件,一种是Java中的properties属性文件(键=值)。
下面以properties属性文件为例介绍log4j.properties的配置:
(1)配置根Logger
log4j.rootLogger = level, appenderName, appenderName, …
其中,level 是日志记录的优先级,分为OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL或者您定义的级别。Log4j建议只使用四个级别,优先级从高到低分别是ERROR、WARN、INFO、DEBUG。通过在这里定义的级别,您可以控制到应用程序中相应级别的日志信息的开关。比如在这里定 义了INFO级别,则应用程序中所有DEBUG级别的日志信息将不被打印出来。
appenderName就是指level级别的日志信息输出到哪个地方,可以同时指定多个输出目的地,用逗号隔开。
(2)配置日志信息输出目的地Appender
org.apache.log4j.PatternLayout(可以灵活地指定布局模式
org.apache.log4j.ConsoleAppender(控制台)
org.apache.log4j.FileAppender(文件)
org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件)
org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件)
org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)
(3)配置日志信息的格式(布局)
org.apache.log4j.HTMLLayout(以HTML表格形式布局)
org.apache.log4j.PatternLayout(可以灵活地指定布局模式)
org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串)
org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息)
一般我们可以根据自己的喜好自定义输出日志信息的格式,使用org.apache.log4j.PatternLayout即可。
格式化符号说明:
log4J采用类似C语言中的printf函数的打印格式格式化日志信息,打印参数如下: %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)
实例:
5、在代码中使用Log4j(这里是没有配置log4j.properties的默认情况)
导入log4j-1.2.17.jar包到项目的lib目录,然后就可以敲代码了:
public class Log4JTest {
public static void main(String[] args)
{
//获取Logger对象的实例
Logger logger = Logger.getLogger(Log4JTest.class);
//使用默认的配置信息,不需要写log4j.properties
BasicConfigurator.configure();
//设置日志输出级别为WARN,这将覆盖配置文件中设置的级别,只有日志级别高于WARN的日志才输出
logger.setLevel(Level.WARN);
logger.debug("这是debug");
logger.info("这是info");
logger.warn("这是warn");
logger.error("这是error");//记录error级别的信息
logger.fatal("这是fatal");
}
}
二、
slf4j-api、slf4j-log4j12、log4j之间关系
/*一般创建工程,建议通过slf4j设计日志系统,方便扩展。slf4j-log4j12这个包依赖了slf4j和log4j,
所以使用slf4j+log4j的组合只要配置上面这一个依赖就够了*/
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.22</version>
</dependency>
// 可以用于学习log4j,正式项目中不推荐使用,这样是依赖具体的log4j日志系统。
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
1、slf4j的概念
slf4j:Simple Logging Facade for Java,为Java提供的简单日志Facade。Facade门面,更底层一点说就是接口。它允许用户以自己的喜好,在工程中通过slf4j接入不同的日志系统。
因此,slf4j接口就是抽象层,它不负责具体的日志实现,只在编译时负责寻找合适的日志系统进行绑定。比如:log4j,logback
common logging,jdk log日志实现包等,但是这些日志实现又不能通过接口直接调用,实现上他们根本就和slf4j-api不一致,因此slf4j又增加了一层来转换各日志实现包的使用,比如slf4j-log4j12等。
slf4j-api作为日志接入的接口:编译时slf4j-api中
public final class LoggerFactory
类中private final static void bind()
方法会寻找具体的日志实现类绑定
,主要通过StaticLoggerBinder.getSingleton()
的语句调用。slf4j-log4j12是链接slf4j-api和log4j中间的适配器:它实现了slf4j-api中StaticLoggerBinder接口,从而使得在编译时绑定的是slf4j-log4j12的getSingleton()方法。
log4j是具体的日志系统:通过slf4j-log4j12初始化Log4j,达到最终日志的输出。
2、为什么要使用SLF4J而不是直接使用Log4J
如果是在编写供内外部都可以使用的API或者通用类库,那么你真不会希望使用你类库的客户端必须使用你选择的日志类库。
比如一个项目已经使用了log4j,而你加载了一个类库,比方说 Apache Active MQ——它依赖于于另外一个日志类库logback,那么你就需要把它也加载进去。但如果Apache Active MQ使用了SLF4J,你可以继续使用你的日志类库而无语忍受加载和维护一个新的日志框架的痛苦。
三、Manen下的Web项目中使用Log4j实例
1>Maven工程的pom.xml添加依赖导入jar包
<!--通过slf4j设计日志系统,方便扩展-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j-log4j12.version}</version>
</dependency>
slf4j-log4j12这个包依赖了slf4j和log4j,所以使用slf4j+log4j的组合只要配置上面这一个依赖就够了。之后就会添加三个包,slf4j-api-1.7.28.jar, log4j-1.2.17.jar, slf4j-log4j12-1.7.28.jar
2>新建log4j.properties配置文件
#Log4j日志系统框架在运行的时候会加载项目路径下的 log4j.properties 配置文件,可以提供方便的日志记录,我们通过查看日志文件可以方便项目的Bug调试。
#log4j.rootLogger = [level] , appenderName1 , appenderName2 , … 这里表示默认输出Info级别以上的日志到控制台和文件中
log4j.rootLogger=INFO,Console,File,D
#控制台日志:输出Info级别以上的日志信息到控制台
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.Target=System.out
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=[%p][%t][%d{yyyy-MM-dd HH\:mm\:ss}][%C] - %m%n
#普通文件日志:输出Info级别以上的日志到src同级目录logs中的ssm.log文件中
log4j.appender.File=org.apache.log4j.RollingFileAppender
log4j.appender.File.File=logs/ssm.log
log4j.appender.File.MaxFileSize=10MB
#Threshold是个全局的过滤器,它将把低于当前所设置的level的信息过滤不显示出来,但是要注意Threshold指定的日志级别必须得比最上面rootLogger设置的level更高才有效
log4j.appender.File.Threshold=ALL
log4j.appender.File.layout=org.apache.log4j.PatternLayout
log4j.appender.File.layout.ConversionPattern=[%p][%t][%d{yyyy-MM-dd HH\:mm\:ss}][%C] - %m%n
### 输出error级别以上的日志到硬盘中 = D://Maven/error.log ###
log4j.appender.D= org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File =D://Maven/error.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = ERROR
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
上面的配置文件让Log4j分别输出INFO级别上的日志信息到控制台、SSM项目文件目录下的文件和本地的D盘目下的文件中
3>配置web.xml文件,让SSM框架项目知道这个log4j.properties配置文件的位置并起作用
在我们搭建的Web工程中的web.xml文件下添加如下代码描述:
<!--指定Log4j配置文件的位置 -->
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:log4j.properties</param-value>
</context-param>
这里就告诉了SSM框架我们采用了Log4j配置,配置文件位置是classpath路径下的log4j.properties文件。
4>SpringMVC的Controller层代码中使用Log4j
package com.hs.controller;
import com.alibaba.fastjson.JSON;
import com.hs.dao.entity.UserEntity;
import com.hs.service.UserService;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import javax.annotation.Resource;
@Controller
public class UserController
{
private static Logger logger = Logger.getLogger(UserController.class);
@Resource
private UserService userService;
@RequestMapping(value = "/user")
public ModelAndView user ()
{
logger.info("user()方法被调用");
logger.error("666666666666只是测试用");//记录error级别的信息
ModelAndView mv = new ModelAndView();//Spring MVC 通过 ModelAndView 对象把模型和视图结合在一起,即它里面包含了Model和View的对象
//通过SpringMVC和Mybatis
UserEntity userEntity = userService.getUserById(1);
mv.addObject("user",userEntity);
String str = JSON.toJSONString(userEntity);
logger.info(str);
mv.addObject("message", "测试能不能通过Controller层返回jsp!");
mv.setViewName("user");//也可以在new ModelAndView("user")构造函数中的参数指出试图逻辑名
return mv;
}
}
运行结果,控制台输出:
输出到项目下的文件中:
输出到D盘目录下的文件中:
5、Grep-Console插件实现控制台显示多颜色日志信息
配置IDEA控制台的多颜色log日志输出功能:由于idea不支持显示ascii颜色,grep-console插件能很好的解决这个问题。打开Setting,选中Plugins,输入框里搜索Grep-Console插件安装使用
效果如下: