- Notifications
You must be signed in to change notification settings - Fork 628
日志的使用
sqmax edited this page Aug 7, 2018 · 7 revisions
- 一套能够实现日志输出的工具包。
- 能够描述系统运行状态的所有时间都可以算作日志,包括用户下线,接口超时,数据库崩溃。
- 定制输出目标。
- 定制输出格式。
- 日志携带的上下文信息,如时间戳、类路径、线程、调用对象等等。
- 运行时的选择性输出,比如现在的系统正常,我就只关心正常的日志,假如现在系统运行特别慢,那我可能就比较关心数据库访问层的问题,也就是DAO层的细节,这时候如果能够把这部分相关的日志打印出来,就很重要了。
- 灵活的配置。
- 优异的性能。
日志门面 日志实现 JCL Log4j SLF4J Log4j2 jboss Logback JUL
进过比较,我们选用SLF4j和Logback。Spring Boot里面用的就是SLF4j和Logback,在使用Spring Boot构建web项目是,我们引入了,下面的起步依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
这个起步依赖已经引入了SLF4j和Logback,所以我们不必再显示引入。
- 使用方法: 如果在A类中使用日志,先以该类为参数构造一个对象,如下:
private final Logger logger=LoggerFactory.getLogger(A.class);
然后就可以使用:
log.debug("debug......"); log.info("name: {} , password: {}",name,password); log.error("error......"); log.warn("warning.....");
上面每次使用都要构造一个Logger对象,有没有很麻烦。 其实在IEDA里,我们可以有一点小技巧。可以不用构造Logger对象。
首先,添加以下依赖。
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.16</version> </dependency>
然后,在IDEA中安装lombok插件(IDEA中安装插件方式可在仓库首页有提到),然后在需要打印日志的类上用@Slfj
注解。 这样在该类中就可以直接使用log
对象了。如下:
@RunWith(SpringRunner.class) @SpringBootTest @Slf4j public class LoggerTest { // private final Logger logger= LoggerFactory.getLogger(LoggerTest.class); @Test public void test1(){ String name="imooc"; String password="123456"; //要安裝Lombok插件,才能直接用log log.debug("debug......"); log.info("name: {} , password: {}",name,password); log.error("error......"); log.warn("warning....."); } }
- 在日志里输出变量,用占位符。
String name="Mary"; log.info("name: {}",name);
- 方法一:在application.yml中配置,这里能配置的东西比较简单,只能配置日志文件的路径,日志输出格式等一些简单的配置。
logging: pattern: console: "%d - %msg%n" #配置日志的打印格式 file: F:/日志/sell.log level: com.imooc.LoggerTest: debug #将日志级别指定到一个类
- 方法二:在logback-spring.xml配置,可以进行一些复杂的配置。比如有下面的需求:
- 区分info和error日志
- 每天产生一个日志文件
在resource
目录下建立logback-spring.xml文件。
<?xml version="1.0" encoding="UTF-8" ?> <configuration> <!--1. 控制台日志输出的配置--> <appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender"> <layout class="ch.qos.logback.classic.PatternLayout"> <pattern> %d - %msg%n </pattern> </layout> </appender> <!--2. 日志输出文件,infor级别--> <appender name="fileInfoLog" class="ch.qos.logback.core.rolling.RollingFileAppender"> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>ERROR</level> <onMatch>DENY</onMatch> <onMismatch>ACCEPT</onMismatch> </filter> <encoder> <pattern> %msg%n </pattern> </encoder> <!-- 滚动策略,按时间滚动,每天一个日志--> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>F:/日志/info.%d.log</fileNamePattern> </rollingPolicy> </appender> <!--3. 日志输出文件,error级别--> <appender name="fileErrorLog" class="ch.qos.logback.core.rolling.RollingFileAppender"> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>ERROR</level> </filter> <encoder> <pattern> %msg%n </pattern> </encoder> <!-- 滚动策略,按时间滚动,每天一个日志--> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>F:/日志/error.%d.log</fileNamePattern> </rollingPolicy> </appender> <!--下面声明把以上的配置用在哪里,root即对整个项目都适用--> <root level="info"> <appender-ref ref="consoleLog"/> <appender-ref ref="fileInfoLog"/> <appender-ref ref="fileErrorLog"/> </root> </configuration>
对于每个配置项的含义,已用注解作简要说明。不过我们还是有必要了解一下日志级别,在package org.slf4j.event;
有一个Level的枚举类,它定义了日志级别,如下:
public enum Level { ERROR(ERROR_INT, "ERROR"), WARN(WARN_INT, "WARN"), INFO(INFO_INT, "INFO"), DEBUG(DEBUG_INT, "DEBUG"), TRACE(TRACE_INT, "TRACE"); private int levelInt; private String levelStr; Level(int i, String s) { levelInt = i; levelStr = s; } public int toInt() { return levelInt; } /** * Returns the string representation of this Level. */ public String toString() { return levelStr; } }
里面定义的TRACE、DEBUG、INFO、WARN、ERROR,表明严重性逐渐增加。
上面引入的lombok依赖还有其他的作用,我们在项目中与许多Entity和DTO,它们有许多字段,而且需要get、set方法。我们可以在该实体类上使用@Data注解,那么实体类就不需要显示写get、set方法了。
import lombok.Data; /** * Created by SqMax on 2018/3/31. */ @Data public class CategoryForm { private Integer categoryId; /**类目名字**/ private String categoryName; /** 类目编号**/ private Integer categoryType; }
如果该实体类只需get或set方法,那么就可以使用@Getter或@Setter注解。
目录