package org.olat.core.util.threadlog;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;
import javax.servlet.http.HttpServletRequest;
import org.apache.log4j.Appender;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.Priority;
import org.olat.core.configuration.PersistedProperties;
import org.olat.core.gui.control.Event;
import org.olat.core.util.event.GenericEventListener;
/** work in progress class to allow overwriting log levels on a request base **/
public class RequestBasedLogLevelManager implements GenericEventListener {
private static final String PROP_NAME_REQUESTBASED_IPS = "RequestBasedIps";
private static final Map<String,LogConfig> remoteAddrs2LogConfigs = new HashMap<String,LogConfig>();
private static boolean initialized_ = false;
private static PersistedProperties persistentProperties;
@Override
public void event(@SuppressWarnings("unused") Event event) {
// ignoring
}
private static void init() {
if (initialized_) {
return;
}
persistentProperties = new PersistedProperties(new RequestBasedListener());
String ipsAndLevels = loadIpsAndLevels();
if (ipsAndLevels!=null) {
String[] ipsAndLevelArray = ipsAndLevels.split("\r\n");
for (int i = 0; i < ipsAndLevelArray.length; i++) {
String anIpAndLevel = ipsAndLevelArray[i];
if (anIpAndLevel!=null && anIpAndLevel.length()>0 && anIpAndLevel.contains("=")) {
setLogLevelAndAppender(anIpAndLevel);
}
}
}
initialized_ = true;
}
public static String loadIpsAndLevels() {
try{
return persistentProperties.getStringPropertyValue(PROP_NAME_REQUESTBASED_IPS, true);
} catch(Exception e) {
Logger.getLogger(RequestBasedLogLevelManager.class).warn("loadIpsAndLevels: Error loading property value "+PROP_NAME_REQUESTBASED_IPS, e);
return null;
}
}
public static void storeIpsAndLevels(String ipsAndLevels) {
try{
persistentProperties.setStringProperty(PROP_NAME_REQUESTBASED_IPS, ipsAndLevels, true);
} catch(Exception e) {
Logger.getLogger(RequestBasedLogLevelManager.class).warn("storeIpsAndLevels: Error storing property value "+PROP_NAME_REQUESTBASED_IPS, e);
}
}
public static void reset() {
remoteAddrs2LogConfigs.clear();
}
public static void setLogLevelAndAppender(String configStr) {
StringTokenizer st = new StringTokenizer(configStr, "=");
String anIpAddress = st.nextToken();
String logConfig = st.nextToken();
Level level;
Appender appender;
if (logConfig.contains(",")) {
st = new StringTokenizer(logConfig, ",");
level = Level.toLevel(st.nextToken());
String categoryAppenderStr = st.nextToken();
Logger l = Logger.getLogger(categoryAppenderStr);
if (l!=null) {
appender = l.getAppender(categoryAppenderStr);
if (appender==null) {
appender = Logger.getRootLogger().getAppender(categoryAppenderStr);
}
} else {
appender = null;
}
} else {
level = Level.toLevel(logConfig);
appender = null;
}
setLogLevelAndAppenderForRemoteAddr(anIpAddress, level, appender);
}
public static void setLogLevelAndAppenderForRemoteAddr(String remoteAddr, Priority level, Appender appender) {
if (level==null) {
remoteAddrs2LogConfigs.remove(remoteAddr);
} else {
remoteAddrs2LogConfigs.put(remoteAddr, new LogConfig(level, appender));
}
}
/** done static here - still work in progress - will be done as a normal spring manager eventually **/
public static void activateRequestBasedLogLevel(HttpServletRequest request) {
if (!initialized_) init();
LogConfig logConfig = remoteAddrs2LogConfigs.get(request.getRemoteAddr());
if (logConfig!=null) {
ThreadLocalLogLevelManager.forceThreadLocalLogLevel(logConfig);
} else {
ThreadLocalLogLevelManager.releaseForcedThreadLocalLogLevel();
}
}
public static void deactivateRequestBasedLogLevel() {
ThreadLocalLogLevelManager.releaseForcedThreadLocalLogLevel();
}
}