如何从数据库中获取spring-logback的路径

时间:2019-07-19 07:47:55

标签: java spring spring-boot logging spring-logback

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

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

这很好,因为仍然可以从logging.properties文件中选择服务器日志的路径。记录是通过spring-logback xml配置完成的。

我相信日志记录是即使在数据库连接之前,Spring引导也要做的第一件事,因此很难从数据库中获取路径并将其提供给logback文件。

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

1 个答案:

答案 0 :(得分:0)

请确定您需要将application.properties文件数据存储到DB中。 您可以配置它,如果您选择将appication.properties完全存储到数据库中,则可以通过使用数据库附加程序来实现。

<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);
    }