【问题标题】:Spring Boot Logback DB Appender PropertiesSpring Boot Logback DB Appender 属性
【发布时间】:2016-01-16 03:53:35
【问题描述】:

您好,我想在我的 Spring Boot 应用程序中使用 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>

【问题讨论】:

  • 那永远行不通。 Logback 对 spring 一无所知,反之亦然。属性的替换仅适用于 spring 管理的 bean,logback 配置不是 spring 管理的,所以你不能做这样的事情。

标签: java spring logback


【解决方案1】:

在寻找类似解决方案时偶然发现了这一点。由于这仍然没有答案,因此我找到了一些方法:

1) 如果您使用的是 Spring Boot 1.3+(您已经指出您不是但供将来参考),我设法使用 标记来重用相同的值来自 application.properties。

application.properties(用于嵌入式 H2 DB):

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) 导入应用属性作为属性源:Unable to use Spring Property Placeholders in logback.xml

<property resource="application.properties" />

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

【讨论】:

    【解决方案2】:

    所以请投票给 jpt 的答案。 因为没有“

    的提示

    &lt;property resource="application.yml" /&gt;

    ”(或该答案中的 .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。

    注意,您还可以设置/使用第四个环境变量(我认为它会起作用,我还没有测试过)

    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 上遇到了“截断”错误。

    -- 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 必须有一个良好且有效的连接字符串才能进行“检查”.....如果您输入错误的连接字符串,您将收到此类错误(以下)。我花了 4 个小时来追踪错误,这是因为我追踪了下面的错误,只是因为我的连接字符串工作不正常。同样,首先将正确/工作值硬编码到 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>
    

    【讨论】:

      【解决方案3】:

      我一直在寻找 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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-09-23
        • 2015-06-08
        • 1970-01-01
        • 2012-12-01
        • 2019-03-04
        • 2020-12-22
        • 2021-07-23
        相关资源
        最近更新 更多