栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SpringBoot Logback日志记录到数据库的实现方法

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringBoot Logback日志记录到数据库的实现方法

对于日志的处理,有时候需要把符合条件的日志计入数据库中

一、添加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包下可以找到对应数据库的表创建语句

我用的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,
  arg0VARCHAr(254),
  arg1VARCHAr(254),
  arg2VARCHAr(254),
  arg3VARCHAr(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、运行结果

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

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

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

步骤:

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;
  }

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

数据库存储结果只存储了自定义的日志记录

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持考高分网。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/136326.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号