第16章—日志(slf4j&logback)
spring boot 系列学习记录:http://www.cnblogs.com/jinxiaohang/p/8111057.html
码云源码地址:https://gitee.com/jinxiaohang/springboot
因为spring-boot-starter启动器包含spring-boot-starter-logging启动器并集成了slf4j日志抽象及Logback日志框架,所以不用额外的引入依赖。本次练习在之前整合Spring Data JPA基础上进行。
一、slf4j的使用
-
方法一
@RunWith(SpringRunner.class) @SpringBootTest public class logTest { // 在Java类中创建 logger 实例 private final Logger logger = LoggerFactory.getLogger(this.getClass()); // 在方法中使用日志输出,如 @Test public void log() { logger.debug("日志输出测试 Debug"); logger.trace("日志输出测试 Trace"); logger.info("日志输出测试 Info"); logger.error("日志输出测试 Error"); } }
这种方式每次都要写logger实例,会不会很麻烦,有没有更简单的方法,答案是有的,方法二。
-
方法二
@RunWith(SpringRunner.class) @SpringBootTest @Slf4j public class logTest2 { @Test public void log(){ String name="xiaohang"; String password="123"; log.debug("日志输出测试 Debug"); log.trace("日志输出测试 Trace"); log.info("日志输出测试 Info"); log.error("日志输出测试 Error"); log.info("name:"+name+" , password:"+password);//string拼接 log.info("name:{} , password:{}",name,password);//使用占位符 } }
使用@Slf4j注解,这需要lombok插件的支持,然后直接使用实例好的log。
二、简单日志配置
默认的日志配置满足不了项目需求时,如何使用一些简单配置输出想要的日志。
在application.properties文件中添加如下配置:
#指定日志文件目录、名字(建议使用绝对路径) logging.file=D:/springboot/main.log #指定日志文件目录(默认日志名为spring.log) logging.path=D:/springboot #指定控制台输出日志的pattern logging.pattern.console=%-20(%d{yyyy-MM-dd HH:mm:ss.SSS} [Thread]) %-5level %logger{80} - %msg%n #指定日志文件输出日志的pattern logging.file.console=%-20(%d{yyyy-MM-dd HH:mm:ss.SSS} [Thread]) %-5level %logger{80} - %msg%n #指定整个项目(包含jdk源代码打印的日志)的日志级别 logging.level.root=degug #指定某个类的日志级别 logging.level.com.springboot.CodeController=debug
三、自定义配置文件(logback配置)
当基本配置也满足不了项目需求时,如:需要每日生成一个日志、info级别的和error级别的日志分开生成文件、持久化到数据库中....这就需要自定义的配置文件了,通常配置文件的命名方式:
下面主要实现logback配置,新建logback-spring.xml:
<?xml version="1.0" encoding="UTF-8"?> <configuration> <!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径--> <property name="LOG_HOME" value="D:/log" /> <!-- 控制台输出 --> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <layout class="ch.qos.logback.classic.PatternLayout"> <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符--> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n </pattern> </layout> </appender> <!-- 按照每天生成日志文件 --> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!--日志文件输出的文件名--> <FileNamePattern>${LOG_HOME}/myApp.log.%d{yyyy-MM-dd}.log</FileNamePattern> <MaxHistory>30</MaxHistory> </rollingPolicy> <layout class="ch.qos.logback.classic.PatternLayout"> <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符--> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> </layout> <!--日志文件最大的大小--> <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> <MaxFileSize>10MB</MaxFileSize> </triggeringPolicy> </appender> <!--show parameters for hibernate sql 专为 Hibernate 定制--> <logger name="org.hibernate.type.descriptor.sql.BasicBinder" level="TRACE" /> <logger name="org.hibernate.type.descriptor.sql.BasicExtractor" level="DEBUG" /> <logger name="org.hibernate.SQL" level="DEBUG" /> <logger name="org.hibernate.engine.QueryParameters" level="DEBUG" /> <logger name="org.hibernate.engine.query.HQLQueryPlan" level="DEBUG" /> <!-- 将日志写入数据库 无连接池--> <appender name="DB-CLASSIC-MYSQL" class="ch.qos.logback.classic.db.DBAppender"> <connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource"> <driverClass>com.mysql.jdbc.Driver</driverClass> <url>jdbc:mysql://localhost:3306/test</url> <user>root</user> <password>root</password> </connectionSource> </appender> <!-- 将日志写入数据库 c3p0连接池--> <appender name="DB-CLASSIC-MYSQL-POOL-C3P0" class="ch.qos.logback.classic.db.DBAppender"> <connectionSource class="ch.qos.logback.core.db.DataSourceConnectionSource"> <dataSource class="com.mchange.v2.c3p0.ComboPooledDataSource"> <driverClass>com.mysql.jdbc.Driver</driverClass> <jdbcUrl>jdbc:mysql://localhost:3306/test</jdbcUrl> <user>root</user> <password>root</password> </dataSource> </connectionSource> </appender> <!-- 将日志写入数据库 DBCP2连接池--> <appender name="DB-CLASSIC-MYSQL-POOL-DBCP" class="ch.qos.logback.classic.db.DBAppender"> <connectionSource class="ch.qos.logback.core.db.DataSourceConnectionSource"> <dataSource class="org.apache.commons.dbcp2.BasicDataSource"> <driverClassName>com.mysql.jdbc.Driver</driverClassName> <url>jdbc:mysql://localhost:3306/test</url> <username>root</username> <password>root</password> </dataSource> </connectionSource> </appender> <!-- 将日志写入数据库 DRUID连接池--> <appender name="DB-CLASSIC-MYSQL-POOL-DRUID" class="ch.qos.logback.classic.db.DBAppender"> <connectionSource class="ch.qos.logback.core.db.DataSourceConnectionSource"> <dataSource class="com.alibaba.druid.pool.DruidDataSource"> <driverClassName>com.mysql.jdbc.Driver</driverClassName> <url>jdbc:mysql://localhost:3306/test</url> <username>root</username> <password>root</password> </dataSource> </connectionSource> </appender> <!-- 日志输出级别 --> <root level="INFO"> <appender-ref ref="STDOUT" /> <appender-ref ref="FILE" /> <appender-ref ref="DB-CLASSIC-MYSQL-POOL-DRUID"/><!--更换不同的name--> </root> </configuration>
如要完整实现日志数据库持久化,还需要添加数据库表:
BEGIN; DROP TABLE IF EXISTS logging_event_property; DROP TABLE IF EXISTS logging_event_exception; DROP TABLE IF EXISTS logging_event; COMMIT; BEGIN; CREATE TABLE logging_event ( timestmp BIGINT NOT NULL, formatted_message TEXT NOT NULL, logger_name VARCHAR(254) NOT NULL, level_string VARCHAR(254) NOT NULL, thread_name VARCHAR(254), reference_flag SMALLINT, arg0 VARCHAR(254), arg1 VARCHAR(254), arg2 VARCHAR(254), arg3 VARCHAR(254), caller_filename VARCHAR(254) NOT NULL, caller_class VARCHAR(254) NOT NULL, caller_method VARCHAR(254) NOT NULL, caller_line CHAR(4) NOT NULL, event_id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY ); COMMIT; BEGIN; CREATE TABLE logging_event_property ( event_id BIGINT NOT NULL, mapped_key VARCHAR(254) NOT NULL, mapped_value TEXT, PRIMARY KEY(event_id, mapped_key), FOREIGN KEY (event_id) REFERENCES logging_event(event_id) ); COMMIT; BEGIN; CREATE TABLE logging_event_exception ( event_id BIGINT NOT NULL, i SMALLINT NOT NULL, trace_line VARCHAR(254) NOT NULL, PRIMARY KEY(event_id, i), FOREIGN KEY (event_id) REFERENCES logging_event(event_id) ); COMMIT;
以上实现了按一定格式控制台输出日志、每日生成日志文件,和日志数据库持久化。数据库持久化实现了无连接池方式、用c3p0方式、用dbcp2方式和druid方式,任意选择一种方式,其他可以删除,当然使用连接池时需要引入对应依赖:
<dependency> <groupId>c3p0</groupId> <artifactId>c3p0</artifactId> <version>0.9.1.2</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-dbcp2</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.0</version> </dependency>
效果展示: