我有一个Sprint Boot应用程序。我想实现Log4j来登录到Sql Server。我已经尝试了互联网上的每个示例,但似乎无法破解。
我已经按照以下方式实施了。我的问题是我从Log4j收到错误:
“错误无法写入数据库”
在我的连接工厂中,我可以看到正在调用getDatabaseConnection()方法。我已通过在其中运行选择来验证该连接是否有效。但是,当Log4j开始使用它时,Log4j代码中的连接对象为null,因此会引发此错误。
-用法-
public class MyLogger {
public MyLogger() {}
public static Logger logger = LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);
public static void info(String message){
logger.info(message);
}
}
-连接工厂-
public class ConnectionFactory {
private static interface Singleton {
final ConnectionFactory INSTANCE = new ConnectionFactory();
}
private final DataSource dataSource;
private static Properties properties;
static {
properties = new Properties();
ClassLoader cl = ConnectionFactory.class.getClassLoader();
URL url = cl.getResource("config/application.properties");
try {
properties.load(new FileInputStream(url.getPath()));
} catch (IOException e) {
e.printStackTrace();
}
}
private ConnectionFactory() {
dataSource=getDataSource();
}
public DataSource getDataSource()
{
String logDbServer = properties.getProperty("logDb.server");
String logDbInstance = properties.getProperty("logDb.instance");
String logDbDatabase = properties.getProperty("logDb.database");
String logDbUsername = properties.getProperty("logDb.username");
String logDbPassword = properties.getProperty("logDb.password");
Properties properties = new Properties();
properties.setProperty("user", logDbUsername);
properties.setProperty("password", logDbPassword);
GenericObjectPool<PoolableConnection> pool = new GenericObjectPool<>();
String conn = String.format("jdbc:sqlserver://%s;instanceName=%s;database=%s;encrypt=false;trustServerCertificate=true;loginTimeout=30;user=%s;password=%s"
, logDbServer, logDbInstance, logDbDatabase, logDbUsername, logDbPassword);
DriverManagerConnectionFactory connectionFactory = new DriverManagerConnectionFactory(conn, properties);
new PoolableConnectionFactory(connectionFactory, pool, null, "SELECT 1",
false, false, Connection.TRANSACTION_READ_COMMITTED);
PoolingDataSource p= new PoolingDataSource(pool);
return p;
}
public static Connection getDatabaseConnection() throws SQLException {
Connection conn = Singleton.INSTANCE.dataSource.getConnection();
return conn;
}
}
-Log4j.xml-
<?xml version="1.0" encoding="UTF-8" ?>
<Configuration name="com.online.sync" status="WARN">
<Properties>
<Property name="LOG_PATTERN">
%d{yyyy-MM-dd HH:mm:ss.SSS} %5p ${hostName} --- [%15.15t] %-40.40c{1.} : %m%n%ex
</Property>
</Properties>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="${LOG_PATTERN}"/>
</Console>
<!-- Database Appender -->
<JDBC name="DatabaseAppender" tableName="Log">
<ConnectionFactory class="au.com.online.sync.service.ConnectionFactory" method="getDatabaseConnection" />
<Column name="eventDate" isEventTimestamp="true" />
<Column name="level" pattern="%level" />
<Column name="logger" pattern="%logger" />
<Column name="message" pattern="%message" />
<Column name="exception" pattern="%ex{full}" />
</JDBC>
<!-- Async Logger for Info -->
<Async name="InfoAsync">
<AppenderRef ref="Console"/>
<AppenderRef ref="DatabaseAppender" />
</Async>
<!-- Async Logger for Error -->
<Async name="ErrorAsync">
<AppenderRef ref="Console"/>
<AppenderRef ref="DatabaseAppender" />
</Async>
</Appenders>
<Loggers>
<Logger name="error" level ="error">
<AppenderRef ref="ErrorAsync"/>
</Logger>
<Logger name="debug" level="debug">
<AppenderRef ref="Console" />
</Logger>
<Root level="info">
<AppenderRef ref="InfoAsync"/>
</Root>
</Loggers>
</Configuration>
发生了一件有趣的事情。花了2周的时间后,我几乎放弃了-但我只是破解了它。
我决定将Spring Boot升级到最新版本-现在一切正常。我以前一直在使用2.0.3,而我刚刚更新到2.2.5。我认为使用Log4J的那个Spring Boot版本存在问题,或者通过升级一些本身已修复的依赖关系。