[英]Log4j2 programmatic JdbcAppender ColumnConfig lookup not working
我的应用程序在 Spring-Boot (Vaadin) 之上运行,并使用配置 class(见下文)以编程方式配置 Log4j 的 JdbcAppender。
除了 JdbcAppender 之外,还通过 XML 文件(见下文)配置了 ConsoleAppender。
两个附加程序都使用一个查找插件(见下文),它应该触发用户名。 ConsoleAppender 工作正常,登录后用户名会打印在日志中。
问题:不幸的是,JdbcAppender 没有解决查找问题。 在数据库列中只有“$${app:username}”。
@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);
}
}
<?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>
@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 引导配置加载值。
<?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>
<?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>
@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.