首页 > 技术文章 > SpringBoot集成logback将日志输出到MySQL数据库

lihuidong 2020-07-24 14:53 原文

logback将日志输出到数据库时,数据库必须包含三张表;
建表语句如下:

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;

新建logback配置文件logback-spring.xml
在application.properties配置文件中设置logback配置文件路径:logging.config=classpath:logback-spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出 -->
<!-- scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true -->
<!-- scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。 -->
<!-- debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 -->
<configuration  scan="true" scanPeriod="10 seconds">
    <contextName>logback</contextName>
    <!-- name的值是变量的名称,value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量。 -->
    <property name="log.path" value="D:/log/" />
    <!-- 彩色日志 -->
    <!-- 彩色日志依赖的渲染类 -->
    <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">
        <!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息-->
        <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="DB-CLASSIC-MYSQL-POOL" class="ch.qos.logback.classic.db.DBAppender">
        <connectionSource class="ch.qos.logback.core.db.DataSourceConnectionSource">
            <dataSource class="com.mchange.v2.c3p0.ComboPooledDataSource">
                <driverClass>com.mysql.cj.jdbc.Driver</driverClass>
                <jdbcUrl>jdbc:mysql:数据库地址</jdbcUrl>
                <user>数据库账号</user>
                <password>数据库密码</password>
            </dataSource>
        </connectionSource>
        <!--
            自定义日志过滤实现类,继承Filter<ILoggingEvent>或者TurboFilter重写decide方法
            Filter实现的过滤器是与Appender绑定的,而TurboFIlter是与日志上下文绑定的,会过滤所有的日志请求,并且TurboFIlter的方法中提供了丰富的可访问信息用来进行控制和改写。
        常规过滤器Filter位置:位于appender内。常规过滤器用<filter>标签,是<appender>的子标签。
        TurboFilter过滤器位置:位于configuration内。TurboFilter过滤器用<turboFilter>标签,是<configuration>子标签。
          TurboFilter对于解决应用程序中因为框架的叠加,且对接了日志告警的情况下,若出现一个错误产生重复告警的现象有很好的效果,可以在全局进行动态的日志修改。
            返回值有三种类型
            FilterReply.ACCEPT   记录事件立即被处理,不经过下个记录器
            FilterReply.NEUTRAL      下一个记录器接着处理
            FilterReply.DENY      记录时事件被立即被抛弃
        -->
        <filter class="com.xxxxx.xxxxx.LogsFilter" />
    </appender>
   

    <!--开发环境:打印控制台-->
    <springProfile name="dev">
        <logger name="com.nmys.view" level="debug"/>
    </springProfile>

    <root level="info">
        <appender-ref ref="CONSOLE" />
        <appender-ref ref="DB-CLASSIC-MYSQL-POOL" />
    </root>
</configuration>

在使用过程中遇到一个坑,出现以下报错信息:
DBAppender cannot function if the JDBC driver does not support getGeneratedKeys method and without a specific SQL dialect
网上给了好多种情况和解决方法都没有效果,最后发现是数据库密码写错了,经过尝试,发现只要logback配置文件中有错误的地方都会报这个错,大多数情况下和
JDBC driver并没有关系。

推荐阅读