Spring 启动 Logback DB Appender 属性

Spring Boot Logback DB Appender Properties

您好,我想在我的 Spring 启动应用程序中使用 DBAppender。我想从 application.properties 文件中检索数据库连接属性。但是它似乎不认识他们。 请记住,我正在使用 Spring Boot 1.2.x,所以我还不能使用 logback-spring.xml

我使用的配置如下:

<appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
        <connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource">

            <driverClass>${spring.datasource.driver-class-name}</driverClass>
            <url>${spring.datasource.url}</url>
            <user>${spring.datasource.username}</user>
            <password>${spring.datasource.password}</password>
        </connectionSource>
    </appender>

在搜索类似的解决方案时偶然发现了这一点。由于这仍然没有答案,这里有一些我发现的方法:

1) 如果您正在使用 Spring Boot 1.3+(您已经指出您不是,但为了将来参考),我设法使用了 标签重用来自 application.properties.

的相同值

application.properties(对于嵌入式 H2 数据库):

spring.datasource.driverClassName=org.h2.Driver
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.username=sa
spring.datasource.password=

logback-spring.xml:

<springProperty name="spring.datasource.driverClassName" source="spring.datasource.driverClassName"/>
<springProperty name="spring.datasource.url" source="spring.datasource.url"/>
<springProperty name="spring.datasource.username" source="spring.datasource.username"/>
<springProperty name="spring.datasource.password" source="spring.datasource.password"/>

<appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
    <connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource">
        <driverClass>${spring.datasource.driverClassName}</driverClass>
        <url>${spring.datasource.url}</url>
        <user>${spring.datasource.username}</user>
        <password>${spring.datasource.password}</password>
    </connectionSource>
</appender>

2) 将应用程序属性导入为 属性 来源:

<property resource="application.properties" />

3) 也许您可以在容器 JNDI 中注册数据源并改用 logback 的 JNDIConnectionSource?查看其他 post:How to create JNDI context in Spring Boot with Embedded Tomcat Container

所以请为jpt的回答点赞。 因为没有提示“

<property resource="application.yml" />

”(或该答案中的 .properties),我不会得到任何工作。

但我的回答和贡献:我想添加这也适用于 application.yml。

我会尽量列出我在这里所做的一切:

设置3个环境变量。

SPRING_DATASOURCE_URL
SPRING_DATASOURCE_USER
SPRING_DATASOURCE_PASSWORD

application.yml的内容(下)

spring:
  datasource:
    #SPRING_DATASOURCE_URL environment variable will be something like -> jdbc:sqlserver://MySqlServer\MyInstance:1433;DatabaseName=MyDbName;
    url: ${SPRING_DATASOURCE_URL}
    username: ${SPRING_DATASOURCE_USERNAME}
    password: ${SPRING_DATASOURCE_PASSWORD}
    driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver
logging:
    config: classpath:logback-spring.xml

注意,我正在使用文件 "logback-spring.xml"。我不确定它是否有所作为(而不是仅仅使用 "logback.xml")

logback的内容-spring.xml(下)

<configuration debug="true" scan="true" scanPeriod="30 seconds">


    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>INFO</level>
        </filter>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} [%file:%line] %msg%n</pattern>
        </encoder>
    </appender>



    <!-- THIS IS THE MAGIC LINE that JPT figured out -->
    <property resource="application.yml" />

    <springProperty name="humptydumptyurl" source="spring.datasource.url"/>
    <springProperty name="humptydumptyusername" source="spring.datasource.username"/>
    <springProperty name="humptydumptypassword" source="spring.datasource.password"/>


    <appender name = "MyDbAppender" class="ch.qos.logback.classic.db.DBAppender">
        <connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource">
            <driverClass>com.microsoft.sqlserver.jdbc.SQLServerDriver</driverClass>
            <url>${humptydumptyurl}</url>
            <user>${humptydumptyusername}</user>
            <password>${humptydumptypassword}</password>
        </connectionSource>
    </appender>



    <root level="INFO">
        <appender-ref ref="STDOUT"/>
        <appender-ref ref="MyDbAppender"/>
    </root>

</configuration>

注意,我特意使用了 "humptydumpty" 以避免歧义。您可能会使用更好的前缀,但我想表明映射的左侧可以是您想要的任何名称。

请注意,我的 application.properties 文件是空的。我是 100% application.yml.

注意,你也可以set/use第四个环境变量(我觉得find会起作用,我还没测试过)

SPRING_DATASOURCE_DRIVER-CLASS-NAME

和它的两个小伙伴

datasource:
    driverClassName: ${SPRING_DATASOURCE_DRIVER-CLASS-NAME}

  <springProperty name="humptydumptydriverclassname" source="spring.datasource.driver-class-name"/>

......

下面的一些 mssql-server 注释(可能对大多数用户不重要)

我用过

        <dependency>
            <groupId>com.microsoft.sqlserver</groupId>
            <artifactId>mssql-jdbc</artifactId>
            <version>7.0.0.jre8</version>
        </dependency>

让它工作。

我不得不调整我的 DDL 一些,因为我在 INSERT 上遇到 "truncate" 错误。

-- This SQL script creates the required tables by ch.qos.logback.classic.db.DBAppender
-- 
-- The event_id column type was recently changed from INT to DECIMAL(40)
-- without testing.

DROP TABLE logging_event_property 
DROP TABLE logging_event_exception 
DROP TABLE logging_event 

CREATE TABLE logging_event 
  ( 
    timestmp         DECIMAL(20) NOT NULL,
    formatted_message  VARCHAR(max) NOT NULL,
    logger_name       VARCHAR(512) NOT NULL,
    level_string      VARCHAR(512) NOT NULL,
    thread_name       VARCHAR(512),
    reference_flag    SMALLINT,
    arg0              VARCHAR(512),
    arg1              VARCHAR(512),
    arg2              VARCHAR(512),
    arg3              VARCHAR(512),
    caller_filename   VARCHAR(512) NOT NULL,
    caller_class      VARCHAR(512) NOT NULL,
    caller_method     VARCHAR(512) NOT NULL,
    caller_line       CHAR(16) NOT NULL,
    event_id          DECIMAL(38) NOT NULL identity,
    PRIMARY KEY(event_id) 
  ) 

CREATE TABLE logging_event_property 
  ( 
    event_id          DECIMAL(38) NOT NULL, 
    mapped_key        VARCHAR(512) NOT NULL, 
    mapped_value      VARCHAR(1024), 
    PRIMARY KEY(event_id, mapped_key), 
    FOREIGN KEY (event_id) REFERENCES logging_event(event_id) 
  ) 

CREATE TABLE logging_event_exception 
  ( 
    event_id         DECIMAL(38) NOT NULL, 
    i                SMALLINT NOT NULL, 
    trace_line       VARCHAR(512) NOT NULL, 
    PRIMARY KEY(event_id, i), 
    FOREIGN KEY (event_id) REFERENCES logging_event(event_id) 
  ) 

最后,让我给出最重要的调试提示。

首先对您的连接字符串值进行硬编码,使其正常工作...然后开始插入环境变量替换。

ch.qos.logback.classic.db.DBAppender 必须有一个良好且有效的连接字符串才能执行 "check".....如果你输入一个错误的连接字符串,你会得到这种错误(下面).我花了 4 个小时来追查错误,这是因为我追查以下错误而发生的,仅仅是因为我的连接字符串无法正常工作。同样,首先将 correct/working 值硬编码到 logback-spring.xml 中,让它工作,然后返回并执行环境变量 spring-properties 替换 voodoo.

所以对于 db-appender,首先硬编码你的 url,用户名,密码,让它工作,然后开始慢慢地做替换......我很久以前就一直在追逐下面的错误意识到所有的替代品都不起作用....

06:19:09,721 |-WARN in ch.qos.logback.classic.db.DBAppender[MyDbAppender] - Attempted to append to non started appender [MyDbAppender].
    at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEvent(LoggingApplicationListener.java:202)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:127)
    at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:75)
    at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:54)
    at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:347)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:306)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248)
Caused by: java.lang.IllegalStateException: Logback configuration error detected: 
ERROR in ch.qos.logback.core.joran.spi.Interpreter@68:16 - RuntimeException in Action for tag [appender] java.lang.IllegalStateException: DBAppender cannot function if the JDBC driver does not support getGeneratedKeys method *and* without a specific SQL dialect
    at org.springframework.boot.logging.logback.LogbackLoggingSystem.loadConfiguration(LogbackLoggingSystem.java:169)
    at org.springframework.boot.logging.AbstractLoggingSystem.initializeWithSpecificConfig(AbstractLoggingSystem.java:67)
    at org.springframework.boot.logging.AbstractLoggingSystem.initialize(AbstractLoggingSystem.java:57)
    at org.springframework.boot.logging.logback.LogbackLoggingSystem.initialize(LogbackLoggingSystem.java:117)
    at org.springframework.boot.context.logging.LoggingApplicationListener.initializeSystem(LoggingApplicationListener.java:298)

并且只是为了完成所有内容的列表。

这些是我使用的 logback 版本:

        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>1.2.3</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>

我一直在寻找解决方案 jpt,特别是之前描述的 granadaCoder,但它对我不起作用,尽管它也与 logback-spring.xml 一起工作。相反,更简单的方法有所帮助:

魔法线

<property resource="application-local.yml" />

再简单

<appender name="DB_Logger" class="ch.qos.logback.classic.db.DBAppender">
            <connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource">
                <driverClass>com.mysql.cj.jdbc.Driver</driverClass>
                <url>${URL}</url>
                <user>${USERNAME}</user>
                <password>${PASSWORD}</password>
            </connectionSource>
        </appender>

显然在我的 application.yml 中我有 spring.datasource.URL/USERNAME/PASSWORD 个值