SpringBoot Logback 로그 가 데이터베이스 에 기록 되 는 실현 방법
13654 단어 SpringBootLogback로그
pom 의존 추가
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- , java.lang.ClassNotFoundException: org.apache.commons.dbcp.BasicDataSource-->
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
2.logback 프로필 만 들 기
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
<!-- LogBack -->
<property name="LOG_HOME" value="/home/admin" />
<!-- -->
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!-- :%d ,%thread ,%-5level: 5 %msg: ,%n -->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
</appender>
<!-- -->
<appender name="application_file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- -->
<FileNamePattern>${LOG_HOME}/info/info.log.%d{yyyy-MM-dd}.log</FileNamePattern>
<!-- -->
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!-- :%d ,%thread ,%-5level: 5 %msg: ,%n -->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
<!-- -->
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>500MB</MaxFileSize>
</triggeringPolicy>
</appender>
<!-- -->
<appender name="error_file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- -->
<FileNamePattern>${LOG_HOME}/error/error.log.%d{yyyy-MM-dd}.log</FileNamePattern>
<!-- -->
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!-- :%d ,%thread ,%-5level: 5 %msg: ,%n -->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
<!-- -->
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>500MB</MaxFileSize>
</triggeringPolicy>
<!-- -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>error</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- -->
<appender name="db_classic_mysql_pool" class="ch.qos.logback.classic.db.DBAppender">
<connectionSource class="ch.qos.logback.core.db.DataSourceConnectionSource">
<dataSource class="org.apache.commons.dbcp.BasicDataSource">
<driverClassName>com.mysql.cj.jdbc.Driver</driverClassName>
<url>jdbc:mysql://127.0.0.1:3306/logdb?serverTimezone=Asia/Shanghai</url>
<username>root</username>
<password>123456</password>
</dataSource>
</connectionSource>
</appender>
<!--myibatis log configure-->
<logger name="com.apache.ibatis" level="TRACE"/>
<logger name="java.sql.Connection" level="DEBUG" />
<logger name="java.sql.Statement" level="DEBUG"/>
<logger name="java.sql.PreparedStatement" level="DEBUG"/>
<!-- -->
<root level="INFO">
<appender-ref ref="stdout" />
<appender-ref ref="application_file" />
<appender-ref ref="error_file"/>
<appender-ref ref="db_classic_mysql_pool" />
</root>
</configuration>
3.데이터베이스 시트 만 들 기ch.qos.logback.classic.db 패키지 에서 데이터베이스 에 대응 하 는 표 생 성 문 구 를 찾 을 수 있 습 니 다.
내 가 사용 하 는 my sql 데이터 베 이 스 는 먼저 스스로 라 이브 러 리 를 만 드 는 것 이 전제 이다.
mysql 데이터베이스 sql 문장:
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;
생 성 된 시계
테스트
1.테스트 코드 작성
@RunWith(SpringRunner.class)
@SpringBootTest
public class Springboot02MybatisApplicationTests {
private final Logger logger = LoggerFactory.getLogger(Springboot02MybatisApplicationTests.class);
@Test
public void contextLoads() {
logger.info(" info");
logger.error(" error");
}
}
2.실행 결과현재 단계 에 맞 는 모든 로그 기록 을 기본 으로 저장 합 니 다.
5.사용자 정의 데이터베이스 테이블 필드 와 저장 내용
물론 기본 표 필드 가 그렇게 많 고 많은 내용 을 저장 하지만 우 리 는 자신 이 인쇄 한 로그 내용 만 있 을 때 가 많 습 니 다.디스크 공간 을 절약 하기 위해 이 럴 때 저장 필드 와 저장 내용 을 사용자 정의 할 수 있 습 니 다.
단계:
1.데이터베이스 시트 만 들 기
DROP TABLE IF EXISTS `logging`;
CREATE TABLE `logging` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`message` VARCHAR(300) NOT NULL COMMENT ' ',
`level_string` VARCHAR(254) NOT NULL COMMENT ' ',
`created_time` DATETIME NOT NULL COMMENT ' ',
`logger_name` VARCHAR(300) NOT NULL COMMENT ' ',
PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8 COMMENT=' '
2.재 작성 DBAppender 클래스 는 LogDBAppender 클래스 입 니 다.
package com.me.study.springboot02mybatis.config;
import ch.qos.logback.classic.spi.CallerData;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.db.DBAppenderBase;
import org.springframework.context.annotation.Configuration;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Timestamp;
@Configuration
public class LogDBAppender extends DBAppenderBase<ILoggingEvent> {
protected static final Method GET_GENERATED_KEYS_METHOD;
// sql
protected String insertSQL;
// message
static final int MESSAGE = 1;
// level_string
static final int LEVEL_STRING = 2;
// created_time
static final int CREATE_TIME = 3;
// logger_name
static final int LOGGER_NAME = 4;
static final StackTraceElement EMPTY_CALLER_DATA = CallerData.naInstance();
static {
// PreparedStatement.getGeneratedKeys() method was added in JDK 1.4
Method getGeneratedKeysMethod;
try {
// the
getGeneratedKeysMethod = PreparedStatement.class.getMethod("getGeneratedKeys", (Class[]) null);
} catch (Exception ex) {
getGeneratedKeysMethod = null;
}
GET_GENERATED_KEYS_METHOD = getGeneratedKeysMethod;
}
@Override
public void start() {
// sql insertSQL
insertSQL = buildInsertSQL();
super.start();
}
// sql
private static String buildInsertSQL() {
return "INSERT INTO `logging`(`message`,`level_string`,`created_time`,`logger_name`)" +
"VALUES (?,?,?,?)";
}
@Override
protected Method getGeneratedKeysMethod() {
return GET_GENERATED_KEYS_METHOD;
}
@Override
protected String getInsertSQL() {
return insertSQL;
}
/**
*
*
* @param stmt
* @param event
* @throws SQLException
*/
private void bindLoggingEventWithInsertStatement(PreparedStatement stmt, ILoggingEvent event) throws SQLException {
// event.getFormattedMessage()
String message = event.getFormattedMessage();
// , :logger.info("- XXXX")
if(message.startsWith("-")){ // - ,
stmt.setString(MESSAGE, message);
// event.getLevel().toString()
stmt.setString(LEVEL_STRING, event.getLevel().toString());
// new Timestamp(event.getTimeStamp())
stmt.setTimestamp(CREATE_TIME, new Timestamp(event.getTimeStamp()));
// event.getLoggerName()
stmt.setString(LOGGER_NAME, event.getLoggerName());
}
}
@Override
protected void subAppend(ILoggingEvent eventObject, Connection connection, PreparedStatement statement) throws Throwable {
bindLoggingEventWithInsertStatement(statement, eventObject);
// This is expensive... should we do it every time?
int updateCount = statement.executeUpdate();
if (updateCount != 1) {
addWarn("Failed to insert loggingEvent");
}
}
@Override
protected void secondarySubAppend(ILoggingEvent eventObject, Connection connection, long eventId) throws Throwable {
}
}
3.logback 로그 파일 을 수정 하고 사용자 정의 LogDBAppender 클래스 를 참조 합 니 다.
<!-- -->
<appender name="db_classic_mysql_pool" class="com.me.study.springboot02mybatis.config.LogDBAppender">
<connectionSource class="ch.qos.logback.core.db.DataSourceConnectionSource">
<dataSource class="org.apache.commons.dbcp.BasicDataSource">
<driverClassName>com.mysql.cj.jdbc.Driver</driverClassName>
<url>jdbc:mysql://127.0.0.1:3306/logdb?serverTimezone=Asia/Shanghai</url>
<username>root</username>
<password>admin</password>
</dataSource>
</connectionSource>
</appender>
4.테스트 실행1)테스트 코드 작성
@Test
public void contextLoads() {
logger.info("- info");
logger.error("- error");
logger.info(" ‘-' , ");
}
2)실행 결과데이터베이스 저장 결 과 는 사용자 정의 로그 기록 만 저장 되 어 있 습 니 다.
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
【Java・SpringBoot・Thymeleaf】 에러 메세지를 구현(SpringBoot 어플리케이션 실천편 3)로그인하여 사용자 목록을 표시하는 응용 프로그램을 만들고, Spring에서의 개발에 대해 공부하겠습니다 🌟 마지막 데이터 바인딩에 계속 바인딩 실패 시 오류 메시지를 구현합니다. 마지막 기사🌟 src/main/res...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.