前言
本文主要介绍 SpringBoot 项目如何将 Logback 日志写入 MySQL 数据库,使用各组件的版本如下:
组件 | 版本 |
---|
SpringBoot | 2.2.6 |
Logback | 1.2.3 |
Druid | 1.1.9 |
创建数据库表
首先手动创建 Logback 所需的三张数据库表,分别是 logging_event
、logging_event_property
、logging_event_exception
,可以通过下述的方式找到创建数据库表的 SQL 脚本文件。
数据源配置
1 2 3 4 5 6 7 8
| spring: datasource: type: com.alibaba.druid.pool.DruidDataSource druid: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://127.0.0.1:3306/demo?characterEncoding=utf8&autoReconnect=true&useSSL=false&useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC&zeroDateTimeBehavior=CONVERT_TO_NULL username: root password: 123456
|
Logback 配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
| <?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<jmxConfigurator/>
<contextName>logback</contextName>
<property name="log.path" value="/tmp/log/demo" />
<springProperty scope="context" name="DATA_SOURCE" source="spring.datasource.type" /> <springProperty scope="context" name="JDBC_URL" source="spring.datasource.druid.url" /> <springProperty scope="context" name="USER_NAME" source="spring.datasource.druid.username" /> <springProperty scope="context" name="PASSWORD" source="spring.datasource.druid.password" /> <springProperty scope="context" name="DRIVER_CLASS_NAME" source="spring.datasource.druid.driver-class-name" />
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" /> <conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" /> <conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" /> <property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>INFO</level> </filter> <encoder> <Pattern>${CONSOLE_LOG_PATTERN}</Pattern> <charset>UTF-8</charset> </encoder> </appender>
<appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${log.path}/log_debug.log</file> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> <charset>UTF-8</charset> </encoder> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${log.path}/debug/log-debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>500MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> <maxHistory>30</maxHistory> </rollingPolicy> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>DEBUG</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> </appender>
<appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${log.path}/log_info.log</file> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> <charset>UTF-8</charset> </encoder> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>500MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> <maxHistory>30</maxHistory> </rollingPolicy> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>INFO</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> </appender>
<appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${log.path}/log_warn.log</file> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> <charset>UTF-8</charset> </encoder> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${log.path}/warn/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>500MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> <maxHistory>30</maxHistory> </rollingPolicy> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>WARN</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> </appender>
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${log.path}/log_error.log</file> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> <charset>UTF-8</charset> </encoder> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${log.path}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>500MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> <maxHistory>30</maxHistory> </rollingPolicy> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>ERROR</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> </appender>
<appender name="DB" class="ch.qos.logback.classic.db.DBAppender"> <connectionSource class="ch.qos.logback.core.db.DataSourceConnectionSource"> <dataSource class="${DATA_SOURCE}"> <url>${JDBC_URL}</url> <username>${USER_NAME}</username> <password>${PASSWORD}</password> <driverClassName>${DRIVER_CLASS_NAME}</driverClassName> </dataSource> </connectionSource> </appender> <root level="info"> <appender-ref ref="DB"/> <appender-ref ref="CONSOLE" /> <appender-ref ref="DEBUG_FILE" /> <appender-ref ref="INFO_FILE" /> <appender-ref ref="WARN_FILE" /> <appender-ref ref="ERROR_FILE" /> </root>
</configuration>
|
- 在上面的配置内容中,最重点的是配置 MySQL 数据库的连接信息和
DBAppender
,并引用 DBAppender
,如下所示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| <springProperty scope="context" name="DATA_SOURCE" source="spring.datasource.type" /> <springProperty scope="context" name="JDBC_URL" source="spring.datasource.druid.url" /> <springProperty scope="context" name="USER_NAME" source="spring.datasource.druid.username" /> <springProperty scope="context" name="PASSWORD" source="spring.datasource.druid.password" /> <springProperty scope="context" name="DRIVER_CLASS_NAME" source="spring.datasource.druid.driver-class-name" />
<appender name="DB" class="ch.qos.logback.classic.db.DBAppender"> <connectionSource class="ch.qos.logback.core.db.DataSourceConnectionSource"> <dataSource class="${DATA_SOURCE}"> <url>${JDBC_URL}</url> <username>${USER_NAME}</username> <password>${PASSWORD}</password> <driverClassName>${DRIVER_CLASS_NAME}</driverClassName> </dataSource> </connectionSource> </appender>
<root level="info"> <appender-ref ref="DB"/> <appender-ref ref="CONSOLE" /> <appender-ref ref="DEBUG_FILE" /> <appender-ref ref="INFO_FILE" /> <appender-ref ref="WARN_FILE" /> <appender-ref ref="ERROR_FILE" /> </root>
|
- 如果只希望记录某个包(如
com.clay.demo
)的错误日志信息到 MySQL 数据库,可以参考以下配置内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| <appender name="DB" class="ch.qos.logback.classic.db.DBAppender"> <connectionSource class="ch.qos.logback.core.db.DataSourceConnectionSource"> <dataSource class="${DATA_SOURCE}"> <url>${JDBC_URL}</url> <username>${USER_NAME}</username> <password>${PASSWORD}</password> <driverClassName>${DRIVER_CLASS_NAME}</driverClassName> </dataSource> </connectionSource> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>ERROR</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> </appender>
<logger name="com.clay.demo" value="ERROR" additivity="false" > <appender-ref ref="DB"/> <appender-ref ref="CONSOLE" /> <appender-ref ref="ERROR_FILE" /> </logger>
<root level="info"> <appender-ref ref="CONSOLE" /> <appender-ref ref="DEBUG_FILE" /> <appender-ref ref="INFO_FILE" /> <appender-ref ref="WARN_FILE" /> <appender-ref ref="ERROR_FILE" /> </root>
|
测试代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| @RunWith(SpringRunner.class) @SpringBootTest public class LogbackTest {
private final Logger logger= LoggerFactory.getLogger(LogbackTest.class);
@Test public void LogToSql(){ logger.debug("数据库日志 Debug"); logger.info("数据库日志 Info"); logger.warn("数据库日志 Warn"); logger.error("数据库日志 Error"); } }
|
Logback 成功将日志信息写入 MySQL 数据库后,logging_event
表的数据如下:
参考资料