Java 自定义将管理记录器消息的appender
我想创建三个appender:文件、控制台和数据库。此外,我在数据库中存储了三个变量:info、error和warn,它们的值是多少对应于上述附录之一 因此,当我运行以下语句时:Java 自定义将管理记录器消息的appender,java,logback,log4j2,Java,Logback,Log4j2,我想创建三个appender:文件、控制台和数据库。此外,我在数据库中存储了三个变量:info、error和warn,它们的值是多少对应于上述附录之一 因此,当我运行以下语句时: Logger.info ("bla bla bla") 我需要动态获取数据库中信息的当前值,并在右侧的附加器(文件、控制台或数据库)上显示消息 使用回显: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration> <
Logger.info ("bla bla bla")
我需要动态获取数据库中信息的当前值,并在右侧的附加器(文件、控制台或数据库)上显示消息
使用回显:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration>
<configuration>
<!-- Loads the datasource properties file -->
<property resource="datasource.properties" />
<!-- Directory where log files will be stored -->
<property name="LOG_DIRECTORY" value="/tmp" />
<!-- Appenders -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<filter class="com.myproject.logback.ConsoleFilter" />
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%-5level.%msg - %class.%method : %line]%n</pattern>
</encoder>
</appender>
<appender name="database" class="com.myproject.logback.CustomDBAppender">
<filter class="com.myproject.logback.DBFilter" />
<connectionSource class="ch.qos.logback.core.db.DataSourceConnectionSource">
<dataSource class="com.mchange.v2.c3p0.ComboPooledDataSource">
<driverClass>${jdbc.driverClass}</driverClass>
<jdbcUrl>${jdbc.jdbcUrl}</jdbcUrl>
<databaseName>${jdbc.databaseName}</databaseName>
<user>${jdbc.user}</user>
<password>${jdbc.password}</password>
</dataSource>
</connectionSource>
</appender>
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="com.myproject.logback.FileFilter" />
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- Rollover daily -->
<fileNamePattern>${LOG_DIRECTORY}/mylog-%d{yyyy-MM-dd}.txt</fileNamePattern>
<!-- Keep 10 days of history -->
<maxHistory>10</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%-5level.%msg - %class.%method : %line]%n</pattern>
</encoder>
</appender>
<!-- Logger for my project -->
<logger name="com.myproject" additivity="false" level="all">
<appender-ref ref="console" />
<appender-ref ref="database" />
<appender-ref ref="file" />
</logger>
<root level="info">
<appender-ref ref="console" />
</root>
</configuration>
public class CustomDBAppender extends DBAppenderBase<ILoggingEvent> {
protected String insertSQL;
// Indices of the fields of the table in which the logging information is stored
private static final int EVENTTIME_INDEX = 1;
private static final int MESSAGE_INDEX = 2;
private static final int LOGGER_INDEX = 3;
private static final int LEVEL_INDEX = 4;
private static final int CALLER_CLASS_INDEX = 5;
private static final int CALLER_METHOD_INDEX = 6;
private static final int CALLER_LINE_INDEX = 7;
private static final int TRACE_INDEX = 8;
static final StackTraceElement EMPTY_CALLER_DATA = CallerData.naInstance();
@Override
public void append (ILoggingEvent eventObject) {
Connection connection = null;
PreparedStatement insertStatement = null;
try {
connection = connectionSource.getConnection();
connection.setAutoCommit (false);
insertStatement = connection.prepareStatement (getInsertSQL());
// Inserting the event in database
synchronized (this) {
subAppend (eventObject, connection, insertStatement);
}
secondarySubAppend (eventObject, connection, 1);
connection.commit();
} catch (Throwable sqle) {
addError("problem appending event", sqle);
} finally {
DBHelper.closeStatement (insertStatement);
DBHelper.closeConnection (connection);
}
}
@Override
protected Method getGeneratedKeysMethod() {
return null;
}
@Override
protected String getInsertSQL() {
return insertSQL;
}
@Override
protected void secondarySubAppend (ILoggingEvent eventObject,
Connection connection, long eventId) throws Throwable {}
@Override
public void start() {
insertSQL = CustomDBAppender.buildInsertSQL();
super.start();
}
@Override
protected void subAppend (ILoggingEvent event, Connection connection,
PreparedStatement insertStatement) throws Throwable {
bindLoggingEventWithInsertStatement (insertStatement, event);
bindCallerDataWithPreparedStatement (insertStatement, event.getCallerData());
int updateCount = insertStatement.executeUpdate();
if (updateCount != 1) {
addWarn("Failed to insert loggingEvent");
}
}
void bindCallerDataWithPreparedStatement (PreparedStatement stmt,
StackTraceElement[] callerDataArray) throws SQLException {
StackTraceElement caller = extractFirstCaller (callerDataArray);
stmt.setString (CALLER_CLASS_INDEX, caller.getClassName());
stmt.setString (CALLER_METHOD_INDEX, caller.getMethodName());
stmt.setString (CALLER_LINE_INDEX, Integer.toString (caller.getLineNumber()));
}
void bindLoggingEventWithInsertStatement (PreparedStatement stmt,
ILoggingEvent event) throws SQLException {
stmt.setTimestamp (EVENTTIME_INDEX, new Timestamp (event.getTimeStamp()));
stmt.setString (MESSAGE_INDEX, event.getFormattedMessage());
stmt.setString (LOGGER_INDEX, event.getLoggerName());
stmt.setString (LEVEL_INDEX, event.getLevel().toString());
if (event.getThrowableProxy() != null &&
event.getThrowableProxy().getStackTraceElementProxyArray() != null)
stmt.setString (TRACE_INDEX, ThrowableProxyUtil.asString (event.getThrowableProxy()));
else
stmt.setString (TRACE_INDEX, null);
}
private static String buildInsertSQL () {
return "INSERT INTO mylogtable "
+ " (eventtime, message, logger, level, callerclass, callermethod, callerline, trace) "
+ "VALUES "
+ "(?, ?, ?, ?, ?, ?, ?, ?)";
}
private StackTraceElement extractFirstCaller (StackTraceElement[] callerDataArray) {
StackTraceElement caller = EMPTY_CALLER_DATA;
if (hasAtLeastOneNonNullElement (callerDataArray))
caller = callerDataArray[0];
return caller;
}
private boolean hasAtLeastOneNonNullElement (StackTraceElement[] callerDataArray) {
return callerDataArray != null && callerDataArray.length > 0 && callerDataArray[0] != null;
}
}
public class FileFilter extends Filter<ILoggingEvent> {
@Override
public FilterReply decide (ILoggingEvent event) {
try {
// I have in a database table something like this:
// Level - Appender
// ERROR FILE
// DEBUG CONSOLE
// ...
// Here I check with a service if "the actual logger level"
// [event.getLevel()] in the previous database table, is set
// to record their messages with the "current appender"
if (thePreviousCondition == true)
return FilterReply.ACCEPT;
return FilterReply.DENY;
} catch (Exception e) {
return FilterReply.DENY;
}
}
}
1。我需要创建一个完整的类(比如),因为我不想将信息存储在三个不同的表中(只存储在一个表中)
2.多亏了这一点,为信息捕获数据库的价值似乎很简单。因此,我可以在每个appender中包含过滤器,并根据info的值决定是否使用“当前appender”
使用Log4j 2:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration>
<configuration>
<!-- Loads the datasource properties file -->
<property resource="datasource.properties" />
<!-- Directory where log files will be stored -->
<property name="LOG_DIRECTORY" value="/tmp" />
<!-- Appenders -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<filter class="com.myproject.logback.ConsoleFilter" />
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%-5level.%msg - %class.%method : %line]%n</pattern>
</encoder>
</appender>
<appender name="database" class="com.myproject.logback.CustomDBAppender">
<filter class="com.myproject.logback.DBFilter" />
<connectionSource class="ch.qos.logback.core.db.DataSourceConnectionSource">
<dataSource class="com.mchange.v2.c3p0.ComboPooledDataSource">
<driverClass>${jdbc.driverClass}</driverClass>
<jdbcUrl>${jdbc.jdbcUrl}</jdbcUrl>
<databaseName>${jdbc.databaseName}</databaseName>
<user>${jdbc.user}</user>
<password>${jdbc.password}</password>
</dataSource>
</connectionSource>
</appender>
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="com.myproject.logback.FileFilter" />
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- Rollover daily -->
<fileNamePattern>${LOG_DIRECTORY}/mylog-%d{yyyy-MM-dd}.txt</fileNamePattern>
<!-- Keep 10 days of history -->
<maxHistory>10</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%-5level.%msg - %class.%method : %line]%n</pattern>
</encoder>
</appender>
<!-- Logger for my project -->
<logger name="com.myproject" additivity="false" level="all">
<appender-ref ref="console" />
<appender-ref ref="database" />
<appender-ref ref="file" />
</logger>
<root level="info">
<appender-ref ref="console" />
</root>
</configuration>
public class CustomDBAppender extends DBAppenderBase<ILoggingEvent> {
protected String insertSQL;
// Indices of the fields of the table in which the logging information is stored
private static final int EVENTTIME_INDEX = 1;
private static final int MESSAGE_INDEX = 2;
private static final int LOGGER_INDEX = 3;
private static final int LEVEL_INDEX = 4;
private static final int CALLER_CLASS_INDEX = 5;
private static final int CALLER_METHOD_INDEX = 6;
private static final int CALLER_LINE_INDEX = 7;
private static final int TRACE_INDEX = 8;
static final StackTraceElement EMPTY_CALLER_DATA = CallerData.naInstance();
@Override
public void append (ILoggingEvent eventObject) {
Connection connection = null;
PreparedStatement insertStatement = null;
try {
connection = connectionSource.getConnection();
connection.setAutoCommit (false);
insertStatement = connection.prepareStatement (getInsertSQL());
// Inserting the event in database
synchronized (this) {
subAppend (eventObject, connection, insertStatement);
}
secondarySubAppend (eventObject, connection, 1);
connection.commit();
} catch (Throwable sqle) {
addError("problem appending event", sqle);
} finally {
DBHelper.closeStatement (insertStatement);
DBHelper.closeConnection (connection);
}
}
@Override
protected Method getGeneratedKeysMethod() {
return null;
}
@Override
protected String getInsertSQL() {
return insertSQL;
}
@Override
protected void secondarySubAppend (ILoggingEvent eventObject,
Connection connection, long eventId) throws Throwable {}
@Override
public void start() {
insertSQL = CustomDBAppender.buildInsertSQL();
super.start();
}
@Override
protected void subAppend (ILoggingEvent event, Connection connection,
PreparedStatement insertStatement) throws Throwable {
bindLoggingEventWithInsertStatement (insertStatement, event);
bindCallerDataWithPreparedStatement (insertStatement, event.getCallerData());
int updateCount = insertStatement.executeUpdate();
if (updateCount != 1) {
addWarn("Failed to insert loggingEvent");
}
}
void bindCallerDataWithPreparedStatement (PreparedStatement stmt,
StackTraceElement[] callerDataArray) throws SQLException {
StackTraceElement caller = extractFirstCaller (callerDataArray);
stmt.setString (CALLER_CLASS_INDEX, caller.getClassName());
stmt.setString (CALLER_METHOD_INDEX, caller.getMethodName());
stmt.setString (CALLER_LINE_INDEX, Integer.toString (caller.getLineNumber()));
}
void bindLoggingEventWithInsertStatement (PreparedStatement stmt,
ILoggingEvent event) throws SQLException {
stmt.setTimestamp (EVENTTIME_INDEX, new Timestamp (event.getTimeStamp()));
stmt.setString (MESSAGE_INDEX, event.getFormattedMessage());
stmt.setString (LOGGER_INDEX, event.getLoggerName());
stmt.setString (LEVEL_INDEX, event.getLevel().toString());
if (event.getThrowableProxy() != null &&
event.getThrowableProxy().getStackTraceElementProxyArray() != null)
stmt.setString (TRACE_INDEX, ThrowableProxyUtil.asString (event.getThrowableProxy()));
else
stmt.setString (TRACE_INDEX, null);
}
private static String buildInsertSQL () {
return "INSERT INTO mylogtable "
+ " (eventtime, message, logger, level, callerclass, callermethod, callerline, trace) "
+ "VALUES "
+ "(?, ?, ?, ?, ?, ?, ?, ?)";
}
private StackTraceElement extractFirstCaller (StackTraceElement[] callerDataArray) {
StackTraceElement caller = EMPTY_CALLER_DATA;
if (hasAtLeastOneNonNullElement (callerDataArray))
caller = callerDataArray[0];
return caller;
}
private boolean hasAtLeastOneNonNullElement (StackTraceElement[] callerDataArray) {
return callerDataArray != null && callerDataArray.length > 0 && callerDataArray[0] != null;
}
}
public class FileFilter extends Filter<ILoggingEvent> {
@Override
public FilterReply decide (ILoggingEvent event) {
try {
// I have in a database table something like this:
// Level - Appender
// ERROR FILE
// DEBUG CONSOLE
// ...
// Here I check with a service if "the actual logger level"
// [event.getLevel()] in the previous database table, is set
// to record their messages with the "current appender"
if (thePreviousCondition == true)
return FilterReply.ACCEPT;
return FilterReply.DENY;
} catch (Exception e) {
return FilterReply.DENY;
}
}
}
1。我可以使用(而不必创建新类)
2.如何创建一个定制的数据库,用于获取数据库中信息的价值,并帮助我决定是否应该使用其中一个附件(文件、控制台或数据库)
问题是:
是否有任何方法可以简化“第一点回显”或执行“第二点回显”
提前感谢。Log4j2支持过滤器,我相信与Logback非常类似。听起来您正在寻找基于级别的过滤,您可以使用
或者您正在寻找类似的内容(请参阅常见问题解答以获取详细信息)?这允许您配置多个appender,并根据ThreadContext映射将日志事件动态路由到不同的appender。最后,我找到了问题的解决方案。在logback.xml文件中:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration>
<configuration>
<!-- Loads the datasource properties file -->
<property resource="datasource.properties" />
<!-- Directory where log files will be stored -->
<property name="LOG_DIRECTORY" value="/tmp" />
<!-- Appenders -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<filter class="com.myproject.logback.ConsoleFilter" />
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%-5level.%msg - %class.%method : %line]%n</pattern>
</encoder>
</appender>
<appender name="database" class="com.myproject.logback.CustomDBAppender">
<filter class="com.myproject.logback.DBFilter" />
<connectionSource class="ch.qos.logback.core.db.DataSourceConnectionSource">
<dataSource class="com.mchange.v2.c3p0.ComboPooledDataSource">
<driverClass>${jdbc.driverClass}</driverClass>
<jdbcUrl>${jdbc.jdbcUrl}</jdbcUrl>
<databaseName>${jdbc.databaseName}</databaseName>
<user>${jdbc.user}</user>
<password>${jdbc.password}</password>
</dataSource>
</connectionSource>
</appender>
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="com.myproject.logback.FileFilter" />
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- Rollover daily -->
<fileNamePattern>${LOG_DIRECTORY}/mylog-%d{yyyy-MM-dd}.txt</fileNamePattern>
<!-- Keep 10 days of history -->
<maxHistory>10</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%-5level.%msg - %class.%method : %line]%n</pattern>
</encoder>
</appender>
<!-- Logger for my project -->
<logger name="com.myproject" additivity="false" level="all">
<appender-ref ref="console" />
<appender-ref ref="database" />
<appender-ref ref="file" />
</logger>
<root level="info">
<appender-ref ref="console" />
</root>
</configuration>
public class CustomDBAppender extends DBAppenderBase<ILoggingEvent> {
protected String insertSQL;
// Indices of the fields of the table in which the logging information is stored
private static final int EVENTTIME_INDEX = 1;
private static final int MESSAGE_INDEX = 2;
private static final int LOGGER_INDEX = 3;
private static final int LEVEL_INDEX = 4;
private static final int CALLER_CLASS_INDEX = 5;
private static final int CALLER_METHOD_INDEX = 6;
private static final int CALLER_LINE_INDEX = 7;
private static final int TRACE_INDEX = 8;
static final StackTraceElement EMPTY_CALLER_DATA = CallerData.naInstance();
@Override
public void append (ILoggingEvent eventObject) {
Connection connection = null;
PreparedStatement insertStatement = null;
try {
connection = connectionSource.getConnection();
connection.setAutoCommit (false);
insertStatement = connection.prepareStatement (getInsertSQL());
// Inserting the event in database
synchronized (this) {
subAppend (eventObject, connection, insertStatement);
}
secondarySubAppend (eventObject, connection, 1);
connection.commit();
} catch (Throwable sqle) {
addError("problem appending event", sqle);
} finally {
DBHelper.closeStatement (insertStatement);
DBHelper.closeConnection (connection);
}
}
@Override
protected Method getGeneratedKeysMethod() {
return null;
}
@Override
protected String getInsertSQL() {
return insertSQL;
}
@Override
protected void secondarySubAppend (ILoggingEvent eventObject,
Connection connection, long eventId) throws Throwable {}
@Override
public void start() {
insertSQL = CustomDBAppender.buildInsertSQL();
super.start();
}
@Override
protected void subAppend (ILoggingEvent event, Connection connection,
PreparedStatement insertStatement) throws Throwable {
bindLoggingEventWithInsertStatement (insertStatement, event);
bindCallerDataWithPreparedStatement (insertStatement, event.getCallerData());
int updateCount = insertStatement.executeUpdate();
if (updateCount != 1) {
addWarn("Failed to insert loggingEvent");
}
}
void bindCallerDataWithPreparedStatement (PreparedStatement stmt,
StackTraceElement[] callerDataArray) throws SQLException {
StackTraceElement caller = extractFirstCaller (callerDataArray);
stmt.setString (CALLER_CLASS_INDEX, caller.getClassName());
stmt.setString (CALLER_METHOD_INDEX, caller.getMethodName());
stmt.setString (CALLER_LINE_INDEX, Integer.toString (caller.getLineNumber()));
}
void bindLoggingEventWithInsertStatement (PreparedStatement stmt,
ILoggingEvent event) throws SQLException {
stmt.setTimestamp (EVENTTIME_INDEX, new Timestamp (event.getTimeStamp()));
stmt.setString (MESSAGE_INDEX, event.getFormattedMessage());
stmt.setString (LOGGER_INDEX, event.getLoggerName());
stmt.setString (LEVEL_INDEX, event.getLevel().toString());
if (event.getThrowableProxy() != null &&
event.getThrowableProxy().getStackTraceElementProxyArray() != null)
stmt.setString (TRACE_INDEX, ThrowableProxyUtil.asString (event.getThrowableProxy()));
else
stmt.setString (TRACE_INDEX, null);
}
private static String buildInsertSQL () {
return "INSERT INTO mylogtable "
+ " (eventtime, message, logger, level, callerclass, callermethod, callerline, trace) "
+ "VALUES "
+ "(?, ?, ?, ?, ?, ?, ?, ?)";
}
private StackTraceElement extractFirstCaller (StackTraceElement[] callerDataArray) {
StackTraceElement caller = EMPTY_CALLER_DATA;
if (hasAtLeastOneNonNullElement (callerDataArray))
caller = callerDataArray[0];
return caller;
}
private boolean hasAtLeastOneNonNullElement (StackTraceElement[] callerDataArray) {
return callerDataArray != null && callerDataArray.length > 0 && callerDataArray[0] != null;
}
}
public class FileFilter extends Filter<ILoggingEvent> {
@Override
public FilterReply decide (ILoggingEvent event) {
try {
// I have in a database table something like this:
// Level - Appender
// ERROR FILE
// DEBUG CONSOLE
// ...
// Here I check with a service if "the actual logger level"
// [event.getLevel()] in the previous database table, is set
// to record their messages with the "current appender"
if (thePreviousCondition == true)
return FilterReply.ACCEPT;
return FilterReply.DENY;
} catch (Exception e) {
return FilterReply.DENY;
}
}
}
%d{yyyy-MM-dd HH:MM:ss}[%-5level.%msg-%class.%方法:%line]%n
${jdbc.driverClass}
${jdbc.jdbcUrl}
${jdbc.databaseName}
${jdbc.user}
${jdbc.password}
${LOG\u DIRECTORY}/mylog-%d{yyyy-MM-dd}.txt
10
%d{yyyy-MM-dd HH:MM:ss}[%-5level.%msg-%class.%方法:%line]%n
现在CustomDBAppender.java:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration>
<configuration>
<!-- Loads the datasource properties file -->
<property resource="datasource.properties" />
<!-- Directory where log files will be stored -->
<property name="LOG_DIRECTORY" value="/tmp" />
<!-- Appenders -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<filter class="com.myproject.logback.ConsoleFilter" />
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%-5level.%msg - %class.%method : %line]%n</pattern>
</encoder>
</appender>
<appender name="database" class="com.myproject.logback.CustomDBAppender">
<filter class="com.myproject.logback.DBFilter" />
<connectionSource class="ch.qos.logback.core.db.DataSourceConnectionSource">
<dataSource class="com.mchange.v2.c3p0.ComboPooledDataSource">
<driverClass>${jdbc.driverClass}</driverClass>
<jdbcUrl>${jdbc.jdbcUrl}</jdbcUrl>
<databaseName>${jdbc.databaseName}</databaseName>
<user>${jdbc.user}</user>
<password>${jdbc.password}</password>
</dataSource>
</connectionSource>
</appender>
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="com.myproject.logback.FileFilter" />
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- Rollover daily -->
<fileNamePattern>${LOG_DIRECTORY}/mylog-%d{yyyy-MM-dd}.txt</fileNamePattern>
<!-- Keep 10 days of history -->
<maxHistory>10</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%-5level.%msg - %class.%method : %line]%n</pattern>
</encoder>
</appender>
<!-- Logger for my project -->
<logger name="com.myproject" additivity="false" level="all">
<appender-ref ref="console" />
<appender-ref ref="database" />
<appender-ref ref="file" />
</logger>
<root level="info">
<appender-ref ref="console" />
</root>
</configuration>
public class CustomDBAppender extends DBAppenderBase<ILoggingEvent> {
protected String insertSQL;
// Indices of the fields of the table in which the logging information is stored
private static final int EVENTTIME_INDEX = 1;
private static final int MESSAGE_INDEX = 2;
private static final int LOGGER_INDEX = 3;
private static final int LEVEL_INDEX = 4;
private static final int CALLER_CLASS_INDEX = 5;
private static final int CALLER_METHOD_INDEX = 6;
private static final int CALLER_LINE_INDEX = 7;
private static final int TRACE_INDEX = 8;
static final StackTraceElement EMPTY_CALLER_DATA = CallerData.naInstance();
@Override
public void append (ILoggingEvent eventObject) {
Connection connection = null;
PreparedStatement insertStatement = null;
try {
connection = connectionSource.getConnection();
connection.setAutoCommit (false);
insertStatement = connection.prepareStatement (getInsertSQL());
// Inserting the event in database
synchronized (this) {
subAppend (eventObject, connection, insertStatement);
}
secondarySubAppend (eventObject, connection, 1);
connection.commit();
} catch (Throwable sqle) {
addError("problem appending event", sqle);
} finally {
DBHelper.closeStatement (insertStatement);
DBHelper.closeConnection (connection);
}
}
@Override
protected Method getGeneratedKeysMethod() {
return null;
}
@Override
protected String getInsertSQL() {
return insertSQL;
}
@Override
protected void secondarySubAppend (ILoggingEvent eventObject,
Connection connection, long eventId) throws Throwable {}
@Override
public void start() {
insertSQL = CustomDBAppender.buildInsertSQL();
super.start();
}
@Override
protected void subAppend (ILoggingEvent event, Connection connection,
PreparedStatement insertStatement) throws Throwable {
bindLoggingEventWithInsertStatement (insertStatement, event);
bindCallerDataWithPreparedStatement (insertStatement, event.getCallerData());
int updateCount = insertStatement.executeUpdate();
if (updateCount != 1) {
addWarn("Failed to insert loggingEvent");
}
}
void bindCallerDataWithPreparedStatement (PreparedStatement stmt,
StackTraceElement[] callerDataArray) throws SQLException {
StackTraceElement caller = extractFirstCaller (callerDataArray);
stmt.setString (CALLER_CLASS_INDEX, caller.getClassName());
stmt.setString (CALLER_METHOD_INDEX, caller.getMethodName());
stmt.setString (CALLER_LINE_INDEX, Integer.toString (caller.getLineNumber()));
}
void bindLoggingEventWithInsertStatement (PreparedStatement stmt,
ILoggingEvent event) throws SQLException {
stmt.setTimestamp (EVENTTIME_INDEX, new Timestamp (event.getTimeStamp()));
stmt.setString (MESSAGE_INDEX, event.getFormattedMessage());
stmt.setString (LOGGER_INDEX, event.getLoggerName());
stmt.setString (LEVEL_INDEX, event.getLevel().toString());
if (event.getThrowableProxy() != null &&
event.getThrowableProxy().getStackTraceElementProxyArray() != null)
stmt.setString (TRACE_INDEX, ThrowableProxyUtil.asString (event.getThrowableProxy()));
else
stmt.setString (TRACE_INDEX, null);
}
private static String buildInsertSQL () {
return "INSERT INTO mylogtable "
+ " (eventtime, message, logger, level, callerclass, callermethod, callerline, trace) "
+ "VALUES "
+ "(?, ?, ?, ?, ?, ?, ?, ?)";
}
private StackTraceElement extractFirstCaller (StackTraceElement[] callerDataArray) {
StackTraceElement caller = EMPTY_CALLER_DATA;
if (hasAtLeastOneNonNullElement (callerDataArray))
caller = callerDataArray[0];
return caller;
}
private boolean hasAtLeastOneNonNullElement (StackTraceElement[] callerDataArray) {
return callerDataArray != null && callerDataArray.length > 0 && callerDataArray[0] != null;
}
}
public class FileFilter extends Filter<ILoggingEvent> {
@Override
public FilterReply decide (ILoggingEvent event) {
try {
// I have in a database table something like this:
// Level - Appender
// ERROR FILE
// DEBUG CONSOLE
// ...
// Here I check with a service if "the actual logger level"
// [event.getLevel()] in the previous database table, is set
// to record their messages with the "current appender"
if (thePreviousCondition == true)
return FilterReply.ACCEPT;
return FilterReply.DENY;
} catch (Exception e) {
return FilterReply.DENY;
}
}
}
public类CustomDBAppender扩展了DBAppenderBase{
受保护的字符串insertSQL;
//存储日志信息的表的字段索引
私有静态final int EVENTTIME_INDEX=1;
私有静态最终int消息_索引=2;
私有静态最终int LOGGER_索引=3;
私有静态最终整数级_索引=4;
私有静态final int CALLER_CLASS_INDEX=5;
私有静态final int CALLER_METHOD_INDEX=6;
私有静态最终整数调用方线索引=7;
私有静态final int TRACE_INDEX=8;
静态最终StackTraceeElement EMPTY_CALLER_DATA=CallerData.naInstance();
@凌驾
public void append(ilogingevent事件对象){
连接=空;
PreparedStatement insertStatement=null;
试一试{
connection=connectionSource.getConnection();
connection.setAutoCommit(false);
insertStatement=connection.prepareStatement(getInsertSQL());
//在数据库中插入事件
已同步(此){
子外观(eventObject、connection、insertStatement);
}
次要子外观(eventObject,connection,1);
commit();
}捕获(可丢弃的sqle){
加法器(“问题追加事件”,sqle);
}最后{
DBHelper.closeStatement(insertStatement);
DBHelper.closeConnection(连接);
}
}
@凌驾
受保护的方法getGeneratedKeysMethod(){
返回null;
}
@凌驾
受保护的字符串getInsertSQL(){
返回insertSQL;
}
@凌驾
受保护的void secondarySubAppend(ILOGingEvent事件对象,
连接,长事件ID)抛出可丢弃的{}
@凌驾
公开作废开始(){
insertSQL=CustomDBAppender.buildInsertSQL();
super.start();
}
@凌驾
受保护的无效子外观(ILoggingEvent事件、连接、,
PreparedStatement插入语句)抛出可丢弃的{
bindLoggingEventWithInsertStatement(insertStatement,事件);
bindCallerDataWithPreparedStatement(insertStatement,event.getCallerData());
int updateCount=insertStatement.executeUpdate();
如果(updateCount!=1){
addWarn(“未能插入loggingEvent”);
}
}
作废bindCallerDataWithPreparedStatement(PreparedStatement stmt,
StackTraceeElement[]callerDataArray)引发SQLException{
StackTraceElement调用者=extractFirstCaller(callerDataArray);
stmt.setString(CALLER_CLASS_索引,CALLER.getClassName());
stmt.setString(调用者\方法\索引,调用者.getMethodName());
stmt.setString(CALLER\u LINE\u索引,Integer.toString(CALLER.getLineNumber());
}
作废bindLoggingEventWithInsertStatement(PreparedStatement stmt,
ILOGingEvent事件)引发SQLException{
stmt.setTimestamp(EVENTTIME_索引,新的时间戳(event.getTimeStamp());
stmt.setString(消息索引,event.getFormattedMessage());
stmt.setString(LOGGER_索引,event.getLoggerName());
stmt.setString(LEVEL_索引,event.getLevel().toString());
if(event.getThrowableProxy()!=null&&
event.getThrowableProxy().getStackTraceElementProxyArray()!=null)
stmt.setString(TRACE_INDEX,ThrowableProxyUtil.asString(event.getThrowableProxy());
其他的
stmt.setString(跟踪输入)