通过定义几个自定义类,我设法很容易地自定义格式化消息,一个扩展DBAppender
和另一个实现ILoggingEvent
接口:
package com.mypackage;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.Map;
import org.slf4j.Marker;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.db.DBAppender;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.classic.spi.IThrowableProxy;
import ch.qos.logback.classic.spi.LoggerContextVO;
/**
*
* @author PJ_Finnegan
*
* To override the default DBAppender with a custom FORMATTED_MESSAGE
*
*/
public class MdcDbAppender extends DBAppender {
@Override
protected void subAppend(ILoggingEvent event, Connection connection, PreparedStatement insertStatement)
throws Throwable {
// use a special event with custom formatted message
MdcLoggingEvent customEvent = new MdcLoggingEvent(event);
super.subAppend(customEvent, connection, insertStatement);
}
}
/**
*
* @author PJ_Finnegan
*
* To override the getFormattedMessage() method prepending MDC info
*
*/
class MdcLoggingEvent implements ILoggingEvent {
private ILoggingEvent mOrigEvent;
public MdcLoggingEvent(ILoggingEvent origEvent) {
mOrigEvent = origEvent;
}
@Override
public String getThreadName() {
return mOrigEvent.getThreadName();
}
@Override
public Level getLevel() {
return mOrigEvent.getLevel();
}
@Override
public String getMessage() {
return mOrigEvent.getMessage();
}
@Override
public Object[] getArgumentArray() {
return mOrigEvent.getArgumentArray();
}
@Override
public String getFormattedMessage() {
// add my MDC info as a prefix
String mdcVals[] = new String[] { "NA", "NA", "NA" };
Map<String, String> mpm = mOrigEvent.getMDCPropertyMap();
if (mpm != null) {
int i = 0;
for (String key : new String[] { "jobName", "jobInstanceId", "jobExecutionId" }) {
if (mpm.containsKey(key)) {
mdcVals[i] = mpm.get(key);
}
i++;
}
}
return String.format("[%s-%s-%s] ", mdcVals[0], mdcVals[1], mdcVals[2]) + mOrigEvent.getFormattedMessage();
}
@Override
public String getLoggerName() {
return mOrigEvent.getLoggerName();
}
@Override
public LoggerContextVO getLoggerContextVO() {
return mOrigEvent.getLoggerContextVO();
}
@Override
public IThrowableProxy getThrowableProxy() {
return mOrigEvent.getThrowableProxy();
}
@Override
public StackTraceElement[] getCallerData() {
return mOrigEvent.getCallerData();
}
@Override
public boolean hasCallerData() {
return mOrigEvent.hasCallerData();
}
@Override
public Marker getMarker() {
return mOrigEvent.getMarker();
}
@Override
public Map<String, String> getMDCPropertyMap() {
return mOrigEvent.getMDCPropertyMap();
}
@Override
public Map<String, String> getMdc() {
return mOrigEvent.getMdc();
}
@Override
public long getTimeStamp() {
return mOrigEvent.getTimeStamp();
}
@Override
public void prepareForDeferredProcessing() {
mOrigEvent.prepareForDeferredProcessing();
}
}
这样LOGGING_EVENT.FORMATTED_MESSAGE
,数据库上的列值将在前面加上字符串[jobName-jobInstanceId-jobExecutionId]
(我之前将其值放入 MDC):
TIMESTMP |
FORMATTED_MESSAGE |
1635255763784 |
[test-2760-3980] HikariPool-1 - 关机完成。 |
当然你想在你的logback.xml
文件中使用你的自定义类而不是股票 DBAppender:
<!-- DB appender -->
<!-- use our custom class to override the FORMATTED_MESSAGE default pattern -->
<!-- <appender name="ORADB" class="ch.qos.logback.classic.db.DBAppender"> -->
<appender name="ORADB" class="com.mypackage.MdcDbAppender">
<connectionSource
...
没有什么能阻止ILoggingEvent.getFormattedMessage()
用更复杂的操作来覆盖该方法。