怎么在SpringBoot中使用Logback将日志记录到数据库

这篇文章给大家介绍怎么在SpringBoot中使用Logback将日志记录到数据库,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

创新互联是一家专注于网站设计制作、成都网站建设与策划设计,乐山网站建设哪家好?创新互联做网站,专注于网站建设10余年,网设计领域的专业建站公司;建站业务涵盖:乐山等地区。乐山做网站价格咨询:18982081108

一、添加pom依赖


      org.springframework.boot
      spring-boot-starter-web
    
    
    
      commons-dbcp
      commons-dbcp
      1.4
    
    
      MySQL
      mysql-connector-java
      runtime
    

二、创建logback配置文件



  
  

  
  
    
      
      %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
    
  

  
  
    
      
      ${LOG_HOME}/info/info.log.%d{yyyy-MM-dd}.log
      
      30
    
    
      
      %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
    
    
    
      500MB
    
  

  
  
    
      
      ${LOG_HOME}/error/error.log.%d{yyyy-MM-dd}.log
      
      30
    
    
      
      %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
    
    
    
      500MB
    
    
    
      error
      ACCEPT
      DENY
    
  

  
  
    
      
        com.mysql.cj.jdbc.Driver
        jdbc:mysql://127.0.0.1:3306/logdb?serverTimezone=Asia/Shanghai
        root
        123456
      
    
  

  
  
  
  
  

  
  
    
    
    
    
  

三、创建数据库表

在ch.qos.logback.classic.db包下可以找到对应数据库的表创建语句

怎么在SpringBoot中使用Logback将日志记录到数据库

我用的mysql数据库,前提是要首先自己创建库

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;

怎么在SpringBoot中使用Logback将日志记录到数据库

创建好的表

四、测试

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、运行结果

怎么在SpringBoot中使用Logback将日志记录到数据库

默认存储所有符合当前级别的日志记录

五、自定义数据库表字段和存储内容

当然,默认的表字段那么多,存储了很多内容,但是我们很多时候只是自己打印的日志内容,为了节省磁盘空间,这个时候可以自定义存储字段和存储内容

步骤:

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 {

  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类

  
  
    
      
        com.mysql.cj.jdbc.Driver
        jdbc:mysql://127.0.0.1:3306/logdb?serverTimezone=Asia/Shanghai
        root
        admin
      
    
  

4、测试运行

1)编写测试代码

  @Test
  public void contextLoads() {
    logger.info("- 数据库日志info");
    logger.error("- 数据库日志error");
    logger.info("一条不带‘-'的日志,看会不会记录如数据库");
  }

2)运行结果

怎么在SpringBoot中使用Logback将日志记录到数据库

关于怎么在SpringBoot中使用Logback将日志记录到数据库就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。


当前名称:怎么在SpringBoot中使用Logback将日志记录到数据库
当前地址:http://scyanting.com/article/iedssd.html