1

我最近开始在一个 Spring Boot 项目中工作。在这里,所有应用程序或环境级别的属性都存储在 DB (Oracle) 中。这包括应用程序中使用的所有 URL、路径等。

这些属性在启动时获取,存储在静态映射中,然后在整个应用程序中使用(也许想法是客户端可以更新 DB 中的任何属性并重新启动特定环境,一切都应该正常工作)。

这很好接受这样一个事实,即服务器日志的路径仍然是从logging.properties文件中选择的。日志记录是通过 spring-logback xml 配置完成的。

我相信日志记录是 Spring 引导甚至在 DB 连接之前完成的第一件事,因此很难从 DB 中获取路径,然后将其提供给 logback 文件。

是否有任何可能的方法来配置日志记录,以便也可以从数据库中获取日志的路径。

4

1 回答 1

0

我感谢您需要将 application.properties 文件数据存储到数据库中。您可以对此进行配置,如果您选择将 appication.properties 存储到 DB 中,您可以使用 DB appender 来做到这一点。

<configuration  debug="true">

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

       <dataSource class="${dataSourceClass}">
         <!-- Joran cannot substitute variables
         that are not attribute values. Therefore, we cannot
         declare the next parameter like the others. 
         -->
         <param name="${url-key:-url}" value="${url_value}"/>
         <serverName>${serverName}</serverName>
         <databaseName>${databaseName}</databaseName>
       </dataSource>

       <user>${user}</user>
       <password>${password}</password>
     </connectionSource>
  </appender>

  <root level="INFO">
    <appender-ref ref="DB" />
  </root>  
</configuration>

但是需要从数据库中获取数据,然后你可以使用下面的代码。

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.HashMap;
import java.util.Map;

import javax.sql.DataSource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;

public class ReadDBPropertiesInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {

    private static final Logger LOG = LoggerFactory.getLogger(ReadDBPropertiesInitializer.class);

    /**
     * Name of the custom property source added by this post processor class
     */
    private static final String PROPERTY_SOURCE_NAME = "databaseProperties";

    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {

        ConfigurableEnvironment configEnv = ((ConfigurableEnvironment) applicationContext.getEnvironment());

        LOG.info("Load properties from database");

        Map<String, Object> propertySource = new HashMap<>();

        try {

            final String url = getEnv(configEnv, "spring.datasource.url");

            String driverClassName = getProperty(configEnv, "spring.datasource.driver-class-name");

            final String username = getEnv(configEnv, "spring.datasource.username");
            final String password = getEnv(configEnv, "spring.datasource.password");

            DataSource ds = DataSourceBuilder.create().url(url).username(username).password(password)
                    .driverClassName(driverClassName).build();

            // Fetch all properties
            PreparedStatement preparedStatement = ds.getConnection()
                    .prepareStatement("SELECT config_key as name, config_value as value, config_label as label FROM TB_CONFIGURATION");

            ResultSet rs = preparedStatement.executeQuery();

            // Populate all properties into the property source
            while (rs.next()) {             
                final String propName = rs.getString("name");
                final String propValue = rs.getString("value");
                final String propLabel = rs.getString("label");
                LOG.info(String.format("Property: %s | Label: %s", propName, propLabel));
                LOG.info(String.format("Value: %s", propValue));
                propertySource.put(propName, propValue);
            }

            // Create a custom property source with the highest precedence and add it to
            // Spring Environment
            applicationContext.getEnvironment().getPropertySources()
                    .addFirst(new MapPropertySource(PROPERTY_SOURCE_NAME, propertySource));

        } catch (Exception e) {
            throw new RuntimeException("Error fetching properties from db");
        }

    }

    private String getEnv(ConfigurableEnvironment configEnv, final String property) {
        MutablePropertySources propertySources = configEnv.getPropertySources();
        PropertySource<?> appConfigProp = propertySources.get("applicationConfigurationProperties");
        return System.getenv().get(((String) appConfigProp.getProperty(property)).replace("${", "").replace("}", ""));
    }

    private String getProperty(ConfigurableEnvironment configEnv, final String property) {
        MutablePropertySources propertySources = configEnv.getPropertySources();
        PropertySource<?> appConfigProp = propertySources.get("applicationConfigurationProperties");
        return (String) appConfigProp.getProperty(property);
    }
于 2019-07-19T09:12:37.623 回答