繁体   English   中英

Log4j2 编程 JdbcAppender ColumnConfig 查找不起作用

[英]Log4j2 programmatic JdbcAppender ColumnConfig lookup not working

我的应用程序在 Spring-Boot (Vaadin) 之上运行,并使用配置 class(见下文)以编程方式配置 Log4j 的 JdbcAppender。

除了 JdbcAppender 之外,还通过 XML 文件(见下文)配置了 ConsoleAppender。

两个附加程序都使用一个查找插件(见下文),它应该触发用户名。 ConsoleAppender 工作正常,登录后用户名会打印在日志中。

问题:不幸的是,JdbcAppender 没有解决查找问题。 在数据库列中只有“$${app:username}”。

  1. 配置 class:
@Configuration
public class LogConfiguration {

    private final Environment environment;

    public LogConfiguration(Environment environment) {
        this.environment = environment;
    }

    @PostConstruct
    public void onStartUp() {
        String url = Objects.requireNonNull(environment.getProperty("database.url"));
        String username = Objects.requireNonNull(environment.getProperty("database.username"));
        String password = Objects.requireNonNull(environment.getProperty("database.password"));

        ColumnConfig[] columnConfigs = new ColumnConfig[5];
        columnConfigs[0] = ColumnConfig.newBuilder()
                .setName("logger")
                .setPattern("%logger")
                .setUnicode(false)
                .build();
        columnConfigs[1] = ColumnConfig.newBuilder()
                .setName("level")
                .setPattern("%level")
                .setUnicode(false)
                .build();
        columnConfigs[2] = ColumnConfig.newBuilder()
                .setName("message")
                .setPattern("%message")
                .setUnicode(false)
                .build();
        columnConfigs[3] = ColumnConfig.newBuilder()
                .setName("exception")
                .setPattern("%ex{full}")
                .setUnicode(false)
                .build();
        columnConfigs[4] = ColumnConfig.newBuilder()
                .setName("revision_id")
                .setPattern("%X{rev.id}")
                .setUnicode(false)
                .build();
        columnConfigs[8] = ColumnConfig.newBuilder()
                .setName("username")
                .setPattern("$${app:username}")
                .setUnicode(false)
                .build();

        ConnectionSource connectionSource = DriverManagerConnectionSource.newBuilder()
                .setDriverClassName("org.postgresql.Driver")
                .setConnectionString(url)
                .setUserName(username.toCharArray())
                .setPassword(password.toCharArray())
                .build();

        ColumnMapping[] columnMappings = new ColumnMapping[1];
        columnMappings[0] = ColumnMapping.newBuilder()
                .setName("created_at")
                .setLiteral("now()")
                .setType(OffsetDateTime.class)
                .build();

        JdbcAppender appender = JdbcAppender.newBuilder()
                .setTableName("logs")
                .setConnectionSource(connectionSource)
                .setName("Database")
                .setIgnoreExceptions(true)
                .setBufferSize(1)
                .setColumnConfigs(columnConfigs)
                .setColumnMappings(columnMappings)
                .setFilter(ThresholdFilter.createFilter(Level.INFO, Filter.Result.ACCEPT, Filter.Result.DENY))
                .build();

        appender.start();
        Logger logger = (Logger) LogManager.getRootLogger();
        logger.addAppender(appender);
    }

}

  1. xml配置
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss} %-5level - %msg$${app:username}%n"/><!-- %logger{36} -->
        </Console>
    </Appenders>
    <Loggers>
        <Logger name="com.stackoverflow" level="info" additivity="true"/>
        <Root level="warn">
            <AppenderRef ref="Console"/>
        </Root>
    </Loggers>
</Configuration>
  1. 查找插件
@Plugin(name = "app", category = StrLookup.CATEGORY)
public class UsernameLookup implements StrLookup {

    @Override
    public String lookup(String key) {
        return username();
    }

    @Override
    public String lookup(LogEvent event, String key) {
        return username();
    }

    private String username() {
        User user = SecurityUtils.getUser();
        if(user == null) {
            return "";
        }

        return " (" + user.getUsername() + ")";
    }

}

编程配置的原因是某些数据仅在运行时可用。 我现在用两个配置文件绕过了这个问题。 默认情况下会自动加载一个配置文件,然后在 Spring 配置中加载另一个配置文件。 此外,新的 Maven 依赖项用于从 Spring 引导配置加载值。

  1. log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss} %-5level - %msg$${app:username}%n"/>
        </Console>
    </Appenders>
    <Loggers>
        <Logger name="com.stackoverflow" level="info" additivity="true"/>
        <Root level="warn">
            <AppenderRef ref="Console"/>
        </Root>
    </Loggers>
</Configuration>
  1. log4j2-full.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss} %-5level - %msg$${app:username}%n"/><!-- %logger{36} -->
        </Console>
        <JDBC name="Database" tableName="logs" bufferSize="1">
            <DriverManager connectionString="${spring:database.url}"
                           driverClassName="org.postgresql.Driver"
                           username="${spring:database.username}"
                           password="${spring:database.password}" />
            <Column name="created_at" isEventTimestamp="true" isUnicode="false" />
            <Column name="logger" pattern="%logger" isUnicode="false" />
            <Column name="level" pattern="%level" isUnicode="false" />
            <Column name="message" pattern="%message" isUnicode="false" />
            <Column name="exception" pattern="%ex{full}" isUnicode="false" />
            <Column name="username" pattern="$${app:username}" isUnicode="false" />
        </JDBC>
    </Appenders>
    <Loggers>
        <Logger name="com.stackoverflow" level="info" additivity="true"/>
        <Root level="warn">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="Database"/>
        </Root>
    </Loggers>
</Configuration>
  1. 配置 class
@Configuration
public class LogConfiguration {

    public LogConfiguration() throws URISyntaxException {
        ClassLoader classLoader = LogConfiguration.class.getClassLoader();
        URL resource = classLoader.getResource("log4j2-full.xml");

        if (resource != null) {
            Configurator.reconfigure(resource.toURI());
            log.info("Verbindung zur Datenbank hergestellt. Starte parallele Protokollierung in die Datenbank...");
        }
    }

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM