1. Java常用日志输出

java中进行日志打印的方法有很多种,主要分为以下几类:

1 最简单的system.print.out、err之类的打印

2 java.util.logging ; 在JDK 1.4 版本之后,提供了日志的API ,可以往文件中写日志了

3 log4j , 最强大的记录日志的方式。 可以通过配置 .properties 或是 .xml 的文件, 配置日志的目的地,格式等等

4 commons-logging, 最综合和常见的日志记录方式, 经常是和log4j 结合起来使用

当然这里并不打算介绍每一种日志输出,而是着重讲一下log4j日志打印。

2. log4j

log4j作为之前比较流行的日志打印插件,可以在控制台打印信息,并将信息记录到文件里面。但随着log4j2的出现,log4j逐渐被舍弃。

3. log4j2

log4j2和log4j同属一个作者开发,log4j2是后来重新架构的一款日志组件,抛弃了之前log4j的不足,以及吸取了优秀的logback的设计重新推出的一款新组件。

3.1. log4j2和slf4j

一般来说log4j2是和slf4j搭配使用,主要原因如下:

log4j2是一个日志框架,slf4j是日志框架接口,之所以使用log4j2和slf4j搭配使用是为了以后如果项目对日志有其它要求而需要更换日志框架时可以不改动代码,只需要把依赖的jar包换掉就可以了。

3.2. 依赖jar包

// log4j2依赖 

log4j-api-2.8.2.jar

log4j-core-2.8.2.jar

// log4j2和slf4j桥接依赖 

log4j-slf4j-impl-2.8.2.jar

// slf4j依赖 

slf4j-api-1.7.25.jar

3.3. 配置文件

新建一个log4j2.xml文件置于src文件夹下面。相关知识了解:

使用log4j2之前需要在classpath下新建一个配置文件。需要注意的是log4j 2.x版本不再支持像1.x中的.properties后缀的文件配置方式,2.x版本配置文件后缀名只能为”.xml”,”.json”或者”.jsn”。

系统选择配置文件的优先级(从先到后)如下:

classpath下的名为log4j2-test.json 或者log4j2-test.jsn的文件

classpath下的名为log4j2-test.xml的文件

classpath下名为log4j2.json 或者log4j2.jsn的文件

classpath下名为log4j2.xml的文件

示例:

1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出-->
 3 <!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数-->
 4 <configuration monitorInterval="5">
 5    <!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
 6 
 7    <!--变量配置-->
 8    <Properties>
 9       <!-- 格式化输出:%date表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度 %msg:日志消息,%n是换行符-->
10       <!-- %logger{36} 表示 Logger 名字最长36个字符 -->
11       <property name="LOG_PATTERN" value="%date{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n" />
12       <!-- 定义日志存储的路径,不要配置相对路径 -->
13       <property name="FILE_PATH" value="log/error_log" />
14       <property name="FILE_NAME" value="mycollection" />
15    </Properties>
16 
17    <appenders>
18 
19       <console name="Console" target="SYSTEM_OUT">
20          <!--输出日志的格式-->
21          <PatternLayout pattern="${LOG_PATTERN}"/>
22          <!--控制台只输出level及其以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
23          <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
24       </console>
25 
26       <!--文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,适合临时测试用-->
27       <File name="Filelog" fileName="${FILE_PATH}/test.log" append="false">
28          <PatternLayout pattern="${LOG_PATTERN}"/>
29       </File>
30 
31       <!-- 这个会打印出所有的info及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
32       <RollingFile name="RollingFileInfo" fileName="${FILE_PATH}/info.log" filePattern="${FILE_PATH}/${FILE_NAME}-INFO-%d{yyyy-MM-dd}_%i.log.gz">
33          <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
34          <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
35          <PatternLayout pattern="${LOG_PATTERN}"/>
36          <Policies>
37             <!--interval属性用来指定多久滚动一次,默认是1 hour-->
38             <TimeBasedTriggeringPolicy interval="1"/>
39             <SizeBasedTriggeringPolicy size="10MB"/>
40          </Policies>
41          <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件开始覆盖-->
42          <DefaultRolloverStrategy max="15"/>
43       </RollingFile>
44 
45       <!-- 这个会打印出所有的warn及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
46       <RollingFile name="RollingFileWarn" fileName="${FILE_PATH}/warn.log" filePattern="${FILE_PATH}/${FILE_NAME}-WARN-%d{yyyy-MM-dd}_%i.log.gz">
47          <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
48          <ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/>
49          <PatternLayout pattern="${LOG_PATTERN}"/>
50          <Policies>
51             <!--interval属性用来指定多久滚动一次,默认是1 hour-->
52             <TimeBasedTriggeringPolicy interval="1"/>
53             <SizeBasedTriggeringPolicy size="10MB"/>
54          </Policies>
55          <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件开始覆盖-->
56          <DefaultRolloverStrategy max="15"/>
57       </RollingFile>
58 
59       <!-- 这个会打印出所有的error及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
60       <RollingFile name="RollingFileError" fileName="${FILE_PATH}/error.log" filePattern="${FILE_PATH}/${FILE_NAME}-ERROR-%d{yyyy-MM-dd}_%i.log.gz">
61          <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
62          <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
63          <PatternLayout pattern="${LOG_PATTERN}"/>
64          <Policies>
65             <!--interval属性用来指定多久滚动一次,默认是1 hour-->
66             <TimeBasedTriggeringPolicy interval="1"/>
67             <SizeBasedTriggeringPolicy size="10MB"/>
68          </Policies>
69          <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件开始覆盖-->
70          <DefaultRolloverStrategy max="15"/>
71       </RollingFile>
72 
73    </appenders>
74 
75    <!--Logger节点用来单独指定日志的形式,比如要为指定包下的class指定不同的日志级别等。-->
76    <!--然后定义loggers,只有定义了logger并引入的appender,appender才会生效-->
77    <loggers>
78 
79       <!--过滤掉spring和mybatis的一些无用的DEBUG信息-->
80       <logger name="org.mybatis" level="info" additivity="false">
81          <AppenderRef ref="Console"/>
82       </logger>
83       <!--监控系统信息-->
84       <!--若是additivity设为false,则 子Logger 只会在自己的appender里输出,而不会在 父Logger 的appender里输出。-->
85       <Logger name="org.springframework" level="info" additivity="false">
86          <AppenderRef ref="Console"/>
87       </Logger>
88 
89       <root level="info">
90          <appender-ref ref="Console"/>
91          <appender-ref ref="Filelog"/>
92          <appender-ref ref="RollingFileInfo"/>
93          <appender-ref ref="RollingFileWarn"/>
94          <appender-ref ref="RollingFileError"/>
95       </root>
96    </loggers>
97 
98 </configuration>

3.4. 测试类

1 import org.junit.Test;
 2 import org.slf4j.Logger;
 3 import org.slf4j.LoggerFactory;
 4 
 5 /**
 6  * StackTest
 7  *
 8  * @author limingcheng
 9  * @Date 2019/12/9
10  */
11 public class StackTest {
12     private static final Logger logger = LoggerFactory.getLogger(StackTest.class);
13     /**
14      * 测试数组栈
15      */
16     @Test
17     public static void ArrayStackTest(){
18         ArrayStack arr = new ArrayStack(5);
19         arr.push("aa");
20         arr.push("bb");
21         arr.push("cc");
22         arr.push("dd");
23         arr.push("ee");
24         System.out.println("结果:"+arr.pop());
25 
26         logger.debug("结果:"+arr.pop());
27         logger.trace("结果:"+arr.pop());
28         logger.error("结果:"+arr.pop());
29         logger.warn("结果:"+arr.pop());
30 
31     }
32 
33 
34     public static void main(String[] args) {
35         ArrayStackTest();
36     }
37 }

3.5. ssm框架配置

在ssm框架项目里面需要在web.xml里面再配置一下:

1 <?xml version="1.0" encoding="UTF-8"?>
 2 <web-app xmlns="http://java.sun.com/xml/ns/javaee"
 3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
 5         http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
 6        version="3.0">
 7 <welcome-file-list>
 8    <welcome-file>/login.jsp</welcome-file>
 9 </welcome-file-list>
10 <context-param>
11    <param-name>contextConfigLocation</param-name>
12    <param-value>classpath:spring/spring.xml</param-value>
13 </context-param>
14 <listener>
15    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
16 </listener>
17 <listener>
18    <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
19 </listener>
20 <listener>
21    <listener-class>org.apache.logging.log4j.web.Log4jServletContextListener</listener-class>
22 </listener>
23 <servlet>
24    <servlet-name>spring-mvc</servlet-name>
25    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
26    <init-param>
27       <param-name>contextConfigLocation</param-name>
28       <param-value>classpath:spring/spring-mvc.xml</param-value>
29    </init-param>
30 </servlet>
31 <servlet-mapping>
32    <servlet-name>spring-mvc</servlet-name>
33    <url-pattern>/</url-pattern>
34 </servlet-mapping>
35 </web-app>