// Copyright 2012 Georg-August-Universität Göttingen, Germany // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package de.ugoe.cs.autoquest.httpmonitor; import java.util.Timer; import java.util.TimerTask; import de.ugoe.cs.autoquest.httpmonitor.exchange.HttpExchange; import de.ugoe.cs.util.console.Console; /** *

* The log manager handles an {@link HttpMonitorOutputWriter} to perform the logging * of recorded exchanges. It initializes the writer if the first exchange is received and it * closes the writer if for a specific period of time no further exchange was received. The writer * themselves considers log rotation. For handling exchanges, the {@link HttpMonitorExchangeHandler} * mechanism is used. *

* * @author Patrick Harms */ public class HttpMonitorLogManager implements HttpMonitorComponent, HttpMonitorExchangeHandler { /** * the timeout after which the writer is closed */ private static final int SESSION_TIMEOUT = 10 * 60 * 1000; /** * the directory into which the log files shall be written */ private String logFileBaseDir; /** * the writer for the log file */ private HttpMonitorOutputWriter writer; /** * a timer used to detect timeouts */ 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 */ public HttpMonitorLogManager(String logFileBaseDir) { this.logFileBaseDir = logFileBaseDir; } /* (non-Javadoc) * @see de.ugoe.cs.autoquest.htmlmonitor.HttpMonitorComponent#init() */ @Override public synchronized void init() throws IllegalStateException, HttpMonitorException { if (logFileMonitorTimer != null) { throw new IllegalStateException("already initialized"); } logFileMonitorTimer = new Timer(); } /* (non-Javadoc) * @see de.ugoe.cs.autoquest.htmlmonitor.HttpMonitorComponent#start() */ @Override public synchronized void start() throws IllegalStateException, HttpMonitorException { if (logFileMonitorTimer == null) { throw new IllegalStateException("not initialized"); } logFileMonitorTimer.schedule (new LogFileMonitorTimerTask(), SESSION_TIMEOUT / 2, SESSION_TIMEOUT / 2); } /* (non-Javadoc) * @see de.ugoe.cs.autoquest.htmlmonitor.HttpMonitorComponent#stop() */ @Override public synchronized void stop() { if (logFileMonitorTimer != null) { logFileMonitorTimer.cancel(); } if (writer != null) { writer.stop(); } writer = null; } /* (non-Javadoc) * @see HttpMonitoringListener#handleHttpMessage() */ @Override public synchronized void handleHttpExchange(HttpExchange httpExchange) { try { if (writer == null) { writer = new HttpMonitorOutputWriter(logFileBaseDir); writer.init(); } writer.handleHttpExchange(httpExchange); } catch (Exception e) { Console.printerrln("could not handle message: " + 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). if (writer != null) { try { writer.handleHttpExchange(httpExchange); } catch (Exception e1) { synchronized (this) { writer.stop(); writer = null; } } } } } /** *

* 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 (HttpMonitorLogManager.this) { if (System.currentTimeMillis() - writer.getLastUpdate() > SESSION_TIMEOUT) { writer.stop(); writer = null; } } } } }