package de.ugoe.cs.autoquest.htmlmonitor; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Timer; import java.util.TimerTask; import de.ugoe.cs.util.console.Console; /** *

* The log manager handles different {@link HtmlMonitorOutputWriter}s to perform the logging * of recorded messages. It initializes a new writer if the first message for a specific * client is received and it closes a writer if for a specific period of time no further message * of the same client was received. The writers themselves consider log rotation. For handling * messages, the {@link HtmlMonitorMessageListener} mechanism provided by the * {@link HtmlMonitorServer} is used. *

* * @author Patrick Harms */ class HtmlMonitorLogManager implements HtmlMonitorComponent, HtmlMonitorMessageListener { /** * the timeout after which a writer of an inactive client is closed */ private static final int SESSION_TIMEOUT = 100000; /** * the directory into which the log files shall be written */ private String logFileBaseDir; /** * the mapping of client ids to the respective writers. */ private Map writers; /** * a timer used to detect client timouts */ private Timer logFileMonitorTimer; /** *

* initializes the log manager with the directory into which the log files shall be stored *

* * @param logFileBaseDir the directory into which the log files shall be stored */ HtmlMonitorLogManager(String logFileBaseDir) { this.logFileBaseDir = logFileBaseDir; } /* (non-Javadoc) * @see de.ugoe.cs.autoquest.htmlmonitor.HtmlMonitorComponent#init() */ @Override public synchronized void init() throws IllegalStateException, HtmlMonitorException { if (writers != null) { throw new IllegalStateException("already initialized"); } writers = new HashMap(); logFileMonitorTimer = new Timer(); } /* (non-Javadoc) * @see de.ugoe.cs.autoquest.htmlmonitor.HtmlMonitorComponent#start() */ @Override public synchronized void start() throws IllegalStateException, HtmlMonitorException { if (writers == null) { throw new IllegalStateException("not initialized"); } logFileMonitorTimer.schedule (new LogFileMonitorTimerTask(), SESSION_TIMEOUT / 2, SESSION_TIMEOUT / 2); } /* (non-Javadoc) * @see de.ugoe.cs.autoquest.htmlmonitor.HtmlMonitorComponent#stop() */ @Override public synchronized void stop() { if (writers != null) { logFileMonitorTimer.cancel(); for (HtmlMonitorOutputWriter writer : writers.values()) { writer.stop(); } } writers = null; } /* (non-Javadoc) * @see HtmlMonitoringListener#handleEvents(HtmlClientInfos, HtmlEvent[]) */ @Override public void handleMessage(HtmlClientInfos clientInfos, HtmlEvent[] events) { HtmlMonitorOutputWriter writer = writers.get(clientInfos.getClientId()); try { if (writer == null) { synchronized (this) { writer = writers.get(clientInfos.getClientId()); if (writer == null) { writer = new HtmlMonitorOutputWriter(logFileBaseDir, clientInfos.getClientId()); writer.init(); writer.start(); writers.put(clientInfos.getClientId(), writer); } } } writer.handleMessage(clientInfos, events); } catch (Exception e) { Console.printerrln("could not handle message of client " + clientInfos.getClientId() + ": " + e); Console.logException(e); // determine, if the writer exists but is not able to log something. In this case, // destroy the writer (part of the message may be logged twice through this). writer = writers.get(clientInfos.getClientId()); if (writer != null) { try { writer.handleMessage(clientInfos, events); } catch (Exception e1) { synchronized (this) { writers.remove(clientInfos.getClientId()); writer.stop(); } } } } } /** *

* internal timer task used for detecting session timeouts of clients *

* * @author Patrick Harms */ public class LogFileMonitorTimerTask extends TimerTask { /* (non-Javadoc) * @see java.lang.Runnable#run() */ @Override public void run() { synchronized (HtmlMonitorLogManager.this) { List timeoutSessions = new ArrayList(); for (Map.Entry entry : writers.entrySet()) { HtmlMonitorOutputWriter writer = entry.getValue(); if (System.currentTimeMillis() - writer.getLastUpdate() > SESSION_TIMEOUT) { timeoutSessions.add(entry.getKey()); } } for (String clientId : timeoutSessions) { HtmlMonitorOutputWriter writer = writers.remove(clientId); writer.stop(); } } } } }