一、什么是日志?
- 日志:用于记录系统中发生的各种事件。记录的位置常见的有:控制台、磁盘文件
- 日志级别从高到底:
TRACE <DEBUG<INFO<WARN<ERROR<FATAL
- TRACE用到比较少
- 当日志级别为DEBUG时,可以从日志中看到程序运行中的很多细节,比如运行到了哪个方法,方法里面的各种数据的值是什么样
- WARN日志会打印提示有报错隐患
- ERROR日志会打印报错信息
- FATAL提示有严重错误
日志作用:通过日志观察,分析项目的运行情况
通过日志分析用户的使用情况(大数据分析)
…
二、日志管理方案1
2.1 Log4j+Commons-Logging
2.1.1 导入依赖
- junit是测试用的
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>compile</scope>
</dependency>
2.1.2 基本使用
- 新建Maven
- 导入上面的依赖
- 新建一个测试类HelloLog.java
package com.lyx.log.test;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.Test;
public class LogTest {
//日志对象
private Log log = LogFactory.getLog(LogTest.class);
@Test
public void test1(){
log.trace("hello trace!");
log.debug("hello debug");
log.info("hello info");
log.warn("hello warn");
log.error("hello error");
log.fatal("hello fatal");
}
}
- 写好了测试类运行发现没有打印
- 因为配置追加器,追加器:<appender>的意思是我们的日志要输出到哪里
- 写一个log4j的配置文件
- 新建log4j.xml,配置信息如下
2.1.3 配置信息
<?xml version="1.0" encoding="UTF8" ?>
<!DOCTYPE log4j:configuration PUBLIC "-//LOGGER"
"http://org/apache/log4j/xml/log4j.dtd">
<log4j:configuration>
<!--org.apache.log4j.ConsoleAppender 输出到控制台-->
<appender name="myConsole" class="org.apache.log4j.ConsoleAppender">
<!--输出格式-->
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="%-d{yyyy-MM-dd HH:mm:ss,SSS} [%c]-[%p] %m%n"/>
<!--%-d{yyyy-MM-dd HH:mm:ss,SSS}是当前时间
[%c]是日志出现的包和类 %p是日志的级别 %m是message也就是日志的消息,%n是换行符 -->
</layout>
</appender>
<!-- 输出到文件H:/log/hello.log中-->
<appender name="myFile1" class="org.apache.log4j.RollingFileAppender">
<param name="File" value="H:/log/hello.log"/><!--文件位置-->
<param name="Append" value="true"/><!--是否选中追加-->
<param name="MaxFileSize" value="1kb"/><!--文件最大字节数-->
<param name="MaxBackupIndex" value="2"/>
<!--第一个文件超出上面设置的文件最大字节数后,
可以新增的新文件数量,这里只能新增2个,
当日志文件要输出的内容超出3个1kb(第一个加上新增的两个),则覆盖新增的第一个文件,再覆盖第二个文件-->
<!--日志的输出格式-->
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="%-d{yyyy-MM-dd HH:mm:ss,SSS} [%c]-[%p] %m%n"/>
<!--%-d{yyyy-MM-dd HH:mm:ss,SSS}是输出当前时间
[%c]是输出日志出现的包和类 %p是日志的级别 %m是message也就是日志的消息,%n是换行符 -->
</layout>
</appender>
<!-- 输出到文件,每天输出一个文件-->
<appender name="myFile2" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="h:/log/world.log"/>
<param name="Append" value="true"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-d{yyyy-MM-dd HH:mm:ss,SSS} [%c]-[%p] %m%n"/>
</layout>
</appender>
<root>
<!--优先级设置,all < trace < debug < info < warn < error < fatal < off-->
<priority value="all"/>
<appender-ref ref="myConsole"/>
<appender-ref ref="myFile1"/>
<appender-ref ref="myFile2"/>
</root>
</log4j:configuration>
2.1.4 日志输出格式
占位符 | 作用 |
%t | 输出产生改日志事件的线程名 |
%p | 输出优先级,即上面提到的DEBUG、INFO、WARN、ERROR、FATAL |
%c | 输出所在类的全名 |
%r | 输出自应用启动到输出该log信息耗费的毫秒数 |
%m | message也就是日志的消息 |
%n | 换行符 |
%d | 输出日志时间点的日期或手机,默认格式为ISO8601,也可以在其后指定格式,比如%-d{yyyy-MM-dd HH:mm:ss,SSS},输出类似:2022-5-11 14:19:33,921 |
三、日志管理方案2
3.1 Logback+SLF4J
3.1.1 导入依赖
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>compile</scope>
</dependency>
3.1.2 基本使用
public class LogTest {
private Logger logger = LoggerFactory.getLogger(LogTest.class);
@Test
public void test1() throws InterruptedException {
while (true){
logger.trace("hello trace");
logger.debug("hello debug");
logger.info("hello info");
logger.warn("hello warn");
logger.error("hello error");
}
}
}
3.1.3 配置信息
- 看注释
<?xml version="1.0" encoding="UTF8" ?>
<!--scan:当此属性设置为true时,配置文件如果发生改变,将会被出现加载,默认值为true-->
<!--scanPeriod:设置监测配置文件是否修改的时间间隔,如果没有给出时间单位,默认单位是毫秒
当scan为true时,默认的时间间隔为1分钟-->
<!--debug:当此属性设置为true时,将打印出logback内部日志消息,实时查看log back运行状态,默认值为false-->
<configuration scan="true" scanPeriod="50 seconds" debug="true">
<!--如下代码定义2个变量,可通过${log.path}和${CONSOLE_LOG_PATTERN}得到变量值-->
<property name="CONSOLE_LOG_PATTERN"
value="%d{yyyy-MM-dd HH:mm:ss,SSS} |-[%-5p] in %logger.%M[line-%L] -%m%n"></property>
<property name="log.path" value="H:/log2"></property>
<!--输出到控制台-->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<!--Threshold=即最低日志级别,此appender输出大于等于对应级别的日志-->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>debug</level>
</filter>
<encoder>
<!--日志格式-->
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
<!--设置字符集-->
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- 追加到文件中-->
<appender name="file" class="ch.qos.logback.core.FileAppender">
<file>${log.path}/world.log</file>
<encoder>
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
</encoder>
</appender>
<!--滚动追加到文件中-->
<appender name="file2" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--日志文件会写到${log.path}这里路径下的world3.log这个文件中-->
<file>${log.path}/world3.log</file>
<!--日志文件输出格式-->
<encoder>
<!--日志格式-->
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
<!--设置字符集-->
<charset>UTF-8</charset>
</encoder>
<!--日志记录器的滚动策略,按日期,按大小记录
文件超过最大容量后,会新建文件,然后新的日志文件中继续写入
如果日期变更,也会新建文件,然后在新的日志文件中写入当天日志-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--超过最大限制后创建新文件后,原来的旧日志会改名为如下, %i是文件序号从0开始-->
<fileNamePattern>${log.path}/world-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!--每个日志文件的最大体量-->
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>1kb</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天数,值为1:则只保留昨天的归档日志文件,例如今天是10号,保留了9号和10号,到了明天11号则保留10号和11号,,不设置则保留所有日志-->
<maxHistory>1</maxHistory>
</rollingPolicy>
</appender>
<root level="trace">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="file"/>
<appender-ref ref="file2"/>
</root>
</configuration>