/*******************************************************************************
* Copyright (c) quickfixengine.org All rights reserved.
*
* This file is part of the QuickFIX FIX Engine
*
* This file may be distributed under the terms of the quickfixengine.org
* license as defined by quickfixengine.org and appearing in the file
* LICENSE included in the packaging of this file.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE.
*
* See http://www.quickfixengine.org/LICENSE for licensing information.
*
* Contact ask@quickfixengine.org if any conditions of this licensing
* are not clear to you.
******************************************************************************/
package quickfix;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.spi.LocationAwareLogger;
/**
* A Log using the SLFJ wrapper that supports JDK 1.4 logging, Log4J and others. This log should be created using the
* associated factory.
*
* @see SLF4JLogFactory
*/
public class SLF4JLog extends AbstractLog {
public static final String DEFAULT_EVENT_CATEGORY = "quickfixj.event";
public static final String DEFAULT_ERROR_EVENT_CATEGORY = "quickfixj.errorEvent";
public static final String DEFAULT_INCOMING_MSG_CATEGORY = "quickfixj.msg.incoming";
public static final String DEFAULT_OUTGOING_MSG_CATEGORY = "quickfixj.msg.outgoing";
private final Logger eventLog;
private final Logger errorEventLog;
private final Logger incomingMsgLog;
private final Logger outgoingMsgLog;
private final String logPrefix;
private final String callerFQCN;
public SLF4JLog(SessionID sessionID, String eventCategory, String errorEventCategory,
String incomingMsgCategory, String outgoingMsgCategory, boolean prependSessionID,
boolean logHeartbeats, String inCallerFQCN) {
setLogHeartbeats(logHeartbeats);
logPrefix = prependSessionID ? (sessionID + ": ") : null;
eventLog = getLogger(sessionID, eventCategory, DEFAULT_EVENT_CATEGORY);
errorEventLog = getLogger(sessionID, errorEventCategory, DEFAULT_ERROR_EVENT_CATEGORY);
incomingMsgLog = getLogger(sessionID, incomingMsgCategory, DEFAULT_INCOMING_MSG_CATEGORY);
outgoingMsgLog = getLogger(sessionID, outgoingMsgCategory, DEFAULT_OUTGOING_MSG_CATEGORY);
callerFQCN = inCallerFQCN;
}
private Logger getLogger(SessionID sessionID, String category, String defaultCategory) {
return LoggerFactory.getLogger(category != null
? substituteVariables(sessionID, category)
: defaultCategory);
}
private static final String FIX_MAJOR_VERSION_VAR = "\\$\\{fixMajorVersion}";
private static final String FIX_MINOR_VERSION_VAR = "\\$\\{fixMinorVersion}";
private static final String SENDER_COMP_ID_VAR = "\\$\\{senderCompID}";
private static final String SENDER_SUB_ID_VAR = "\\$\\{senderSubID}";
private static final String SENDER_LOC_ID_VAR = "\\$\\{senderLocationID}";
private static final String TARGET_COMP_ID_VAR = "\\$\\{targetCompID}";
private static final String TARGET_SUB_ID_VAR = "\\$\\{targetSubID}";
private static final String TARGET_LOC_ID_VAR = "\\$\\{targetLocationID}";
private static final String QUALIFIER_VAR = "\\$\\{qualifier}";
private String substituteVariables(SessionID sessionID, String category) {
final String[] beginStringFields = sessionID.getBeginString().split("\\.");
String processedCategory = category;
processedCategory = processedCategory.replaceAll(FIX_MAJOR_VERSION_VAR,
beginStringFields[1]);
processedCategory = processedCategory.replaceAll(FIX_MINOR_VERSION_VAR,
beginStringFields[2]);
processedCategory = processedCategory.replaceAll(SENDER_COMP_ID_VAR,
sessionID.getSenderCompID());
processedCategory = processedCategory.replaceAll(SENDER_SUB_ID_VAR,
sessionID.getSenderSubID());
processedCategory = processedCategory.replaceAll(SENDER_LOC_ID_VAR,
sessionID.getSenderLocationID());
processedCategory = processedCategory.replaceAll(TARGET_COMP_ID_VAR,
sessionID.getTargetCompID());
processedCategory = processedCategory.replaceAll(TARGET_SUB_ID_VAR,
sessionID.getTargetSubID());
processedCategory = processedCategory.replaceAll(TARGET_LOC_ID_VAR,
sessionID.getTargetLocationID());
processedCategory = processedCategory.replaceAll(QUALIFIER_VAR,
sessionID.getSessionQualifier());
return processedCategory;
}
public void onEvent(String text) {
log(eventLog, text);
}
public void onErrorEvent(String text) {
logError(errorEventLog, text);
}
@Override
protected void logIncoming(String message) {
log(incomingMsgLog, message);
}
@Override
protected void logOutgoing(String message) {
log(outgoingMsgLog, message);
}
/** Made protected to enable unit testing of callerFQCN coming through correctly */
protected void log(org.slf4j.Logger log, String text) {
if (log.isInfoEnabled()) {
final String message = logPrefix != null ? (logPrefix + text) : text;
if (log instanceof LocationAwareLogger) {
final LocationAwareLogger la = (LocationAwareLogger) log;
la.log(null, callerFQCN, LocationAwareLogger.INFO_INT, message, null, null);
} else {
log.info(message);
}
}
}
protected void logError(org.slf4j.Logger log, String text) {
final String message = logPrefix != null ? (logPrefix + text) : text;
log.error(message);
}
public void clear() {
onEvent("Log clear operation is not supported: " + getClass().getName());
}
}