最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot Logback日志記錄到數(shù)據(jù)庫(kù)的實(shí)現(xiàn)方法

 更新時(shí)間:2019年11月12日 14:38:37   作者:拉提娜的爸爸  
這篇文章主要介紹了SpringBoot Logback日志記錄到數(shù)據(jù)庫(kù)的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

對(duì)于日志的處理,有時(shí)候需要把符合條件的日志計(jì)入數(shù)據(jù)庫(kù)中

一、添加pom依賴

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- 這個(gè)依賴必須存在,否則會(huì)報(bào)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>

二、創(chuàng)建logback配置文件

<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
  <!--定義日志文件的存儲(chǔ)地址 勿在 LogBack 的配置中使用相對(duì)路徑-->
  <property name="LOG_HOME" value="/home/admin" />

  <!-- 控制臺(tái)輸出 -->
  <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
    <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
      <!--格式化輸出:%d表示日期,%thread表示線程名,%-5level:級(jí)別從左顯示5個(gè)字符寬度%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>
      <!--日志文件保留天數(shù)-->
      <MaxHistory>30</MaxHistory>
    </rollingPolicy>
    <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
      <!--格式化輸出:%d表示日期,%thread表示線程名,%-5level:級(jí)別從左顯示5個(gè)字符寬度%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>
      <!--日志文件保留天數(shù)-->
      <MaxHistory>30</MaxHistory>
    </rollingPolicy>
    <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
      <!--格式化輸出:%d表示日期,%thread表示線程名,%-5level:級(jí)別從左顯示5個(gè)字符寬度%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>
    <!-- 只打印錯(cuò)誤日志 -->
    <filter class="ch.qos.logback.classic.filter.LevelFilter">
      <level>error</level>
      <onMatch>ACCEPT</onMatch>
      <onMismatch>DENY</onMismatch>
    </filter>
  </appender>

  <!--連接數(shù)據(jù)庫(kù)配置-->
  <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"/>

  <!-- 日志輸出級(jí)別 -->
  <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>

三、創(chuàng)建數(shù)據(jù)庫(kù)表

在ch.qos.logback.classic.db包下可以找到對(duì)應(yīng)數(shù)據(jù)庫(kù)的表創(chuàng)建語句

我用的mysql數(shù)據(jù)庫(kù),前提是要首先自己創(chuàng)建庫(kù)

mysql的數(shù)據(jù)庫(kù)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;

創(chuàng)建好的表

四、測(cè)試

1、編寫測(cè)試代碼

@RunWith(SpringRunner.class)
@SpringBootTest
public class Springboot02MybatisApplicationTests {

  private final Logger logger = LoggerFactory.getLogger(Springboot02MybatisApplicationTests.class);
  @Test
  public void contextLoads() {
    logger.info("數(shù)據(jù)庫(kù)日志info");
    logger.error("數(shù)據(jù)庫(kù)日志error");
  }
}

2、運(yùn)行結(jié)果

默認(rèn)存儲(chǔ)所有符合當(dāng)前級(jí)別的日志記錄

五、自定義數(shù)據(jù)庫(kù)表字段和存儲(chǔ)內(nèi)容

當(dāng)然,默認(rèn)的表字段那么多,存儲(chǔ)了很多內(nèi)容,但是我們很多時(shí)候只是自己打印的日志內(nèi)容,為了節(jié)省磁盤空間,這個(gè)時(shí)候可以自定義存儲(chǔ)字段和存儲(chǔ)內(nèi)容

步驟:

1、創(chuàng)建數(shù)據(jù)庫(kù)表

DROP TABLE IF EXISTS `logging`;
CREATE TABLE `logging` (
 `id` BIGINT(20) NOT NULL AUTO_INCREMENT,
 `message` VARCHAR(300) NOT NULL COMMENT '內(nèi)容',
 `level_string` VARCHAR(254) NOT NULL COMMENT '級(jí)別',
 `created_time` DATETIME NOT NULL COMMENT '時(shí)間',
 `logger_name` VARCHAR(300) NOT NULL COMMENT '全類名',
 PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8 COMMENT='自定義日志記錄表'

2、重寫DBAppender類為L(zhǎng)ogDBAppender類

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 日志內(nèi)容
  static final int MESSAGE = 1;
  // level_string
  static final int LEVEL_STRING = 2;
  // created_time 時(shí)間
  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() 日志打印內(nèi)容
    String message = event.getFormattedMessage();
    // 如果只想存儲(chǔ)自己打印的日志,可以這樣寫日志:logger.info("- XXXX")
    if(message.startsWith("-")){ // 判斷日志消息首字母為 - 的日志,記錄到數(shù)據(jù)庫(kù)表
      stmt.setString(MESSAGE, message);
      // event.getLevel().toString() 日志級(jí)別
      stmt.setString(LEVEL_STRING, event.getLevel().toString());
      // new Timestamp(event.getTimeStamp()) 時(shí)間
      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類

  <!--連接數(shù)據(jù)庫(kù)配置-->
  <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、測(cè)試運(yùn)行

1)編寫測(cè)試代碼

  @Test
  public void contextLoads() {
    logger.info("- 數(shù)據(jù)庫(kù)日志info");
    logger.error("- 數(shù)據(jù)庫(kù)日志error");
    logger.info("一條不帶‘-'的日志,看會(huì)不會(huì)記錄如數(shù)據(jù)庫(kù)");
  }

2)運(yùn)行結(jié)果

數(shù)據(jù)庫(kù)存儲(chǔ)結(jié)果只存儲(chǔ)了自定義的日志記錄

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Spring中Xml屬性配置的解析全過程記錄

    Spring中Xml屬性配置的解析全過程記錄

    這篇文章主要給大家介紹了關(guān)于Spring中Xml屬性配置的解析全過程,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • spring AOP的After增強(qiáng)實(shí)現(xiàn)方法實(shí)例分析

    spring AOP的After增強(qiáng)實(shí)現(xiàn)方法實(shí)例分析

    這篇文章主要介紹了spring AOP的After增強(qiáng)實(shí)現(xiàn)方法,結(jié)合實(shí)例形式分析了spring面向切面AOP的After增強(qiáng)實(shí)現(xiàn)步驟與相關(guān)操作技巧,需要的朋友可以參考下
    2020-01-01
  • spring boot idea maven依賴找不到問題處理方法

    spring boot idea maven依賴找不到問題處理方法

    這篇文章主要介紹了spring boot idea 偶爾maven依賴找不到問題,這里總結(jié)了幾種處理方法,方便嘗試排查,對(duì)spring boot idea  maven依賴找不到問題感興趣的朋友跟隨小編一起看看吧
    2023-08-08
  • Java中Comparable與Comparator的區(qū)別解析

    Java中Comparable與Comparator的區(qū)別解析

    這篇文章主要介紹了Java中Comparable與Comparator的區(qū)別解析,實(shí)現(xiàn)Comparable接口,重寫compareTo方法,一般在實(shí)體類定義的時(shí)候就可以選擇實(shí)現(xiàn)該接口,提供一個(gè)默認(rèn)的排序方式,供Arrays.sort和Collections.sort使用,需要的朋友可以參考下
    2024-01-01
  • Java神操作:圖片快速轉(zhuǎn)換PDF秘籍

    Java神操作:圖片快速轉(zhuǎn)換PDF秘籍

    想掌握J(rèn)ava神操作,將圖片快速轉(zhuǎn)換成PDF嗎?這份秘籍將一步步引導(dǎo)你,輕松實(shí)現(xiàn)這一目標(biāo),別等了,跟著我們一起,解鎖這項(xiàng)超實(shí)用技能吧!
    2024-02-02
  • JDK安裝與配置超級(jí)詳細(xì)教程(包含二個(gè)或多個(gè)JDK的同時(shí)安裝)

    JDK安裝與配置超級(jí)詳細(xì)教程(包含二個(gè)或多個(gè)JDK的同時(shí)安裝)

    這篇文章主要給大家介紹了關(guān)于JDK安裝與配置(包含二個(gè)或多個(gè)JDK的同時(shí)安裝)的相關(guān)資料,對(duì)于Java學(xué)習(xí)者來說,一臺(tái)電腦拿到手肯定要配置JDK,但是對(duì)于新手來說還是容易出錯(cuò),需要的朋友可以參考下
    2023-10-10
  • java實(shí)現(xiàn)大文件導(dǎo)出的實(shí)現(xiàn)與優(yōu)化

    java實(shí)現(xiàn)大文件導(dǎo)出的實(shí)現(xiàn)與優(yōu)化

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)大文件導(dǎo)出的實(shí)現(xiàn)與優(yōu)化的相關(guān)資料,文中的示例代碼講解詳細(xì),對(duì)我們深入了解java有一定的幫助,感興趣的小伙伴可以了解下
    2023-11-11
  • 詳解Spring Boot配置排序依賴技巧

    詳解Spring Boot配置排序依賴技巧

    本篇文章主要介紹了Spring Boot配置排序依賴技巧,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-11-11
  • Springboot集成mybatis與jsp過程詳解

    Springboot集成mybatis與jsp過程詳解

    這篇文章主要介紹了Springboot集成mybatis與jsp過程,Spring Boot是一種全新的框架(相對(duì)而言),是用來簡(jiǎn)化Spring應(yīng)用的初始搭建以及開發(fā)過程。該框架使用了特定的方式來進(jìn)行配置
    2021-09-09
  • SpringBoot整合Redis及Redis工具類撰寫實(shí)例

    SpringBoot整合Redis及Redis工具類撰寫實(shí)例

    這篇文章主要介紹了SpringBoot整合Redis及Redis工具類撰寫實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-01-01

最新評(píng)論

沛县| 宜春市| 拉孜县| 瑞丽市| 包头市| 兴国县| 五指山市| 南宫市| 台中县| 宁安市| 儋州市| 濮阳市| 浦县| 盐边县| 拉萨市| 普陀区| 陆良县| 攀枝花市| 曲麻莱县| 台南市| 文昌市| 东城区| 乌恰县| 垦利县| 大厂| 德格县| 句容市| 彩票| 沅陵县| 游戏| 大邑县| 达尔| 南皮县| 修武县| 南丹县| 屏山县| 江山市| 广西| 镇江市| 布尔津县| 辽宁省|