source: trunk/autoquest-htmlmonitor/src/main/java/de/ugoe/cs/autoquest/htmlmonitor/HtmlMonitorLogManager.java @ 871

Last change on this file since 871 was 871, checked in by pharms, 12 years ago
  • added some comments
File size: 5.7 KB
Line 
1package de.ugoe.cs.autoquest.htmlmonitor;
2
3import java.util.ArrayList;
4import java.util.HashMap;
5import java.util.List;
6import java.util.Map;
7import java.util.Timer;
8import java.util.TimerTask;
9
10import de.ugoe.cs.util.console.Console;
11
12/**
13 * <p>
14 * The log manager handles different {@link HtmlMonitorOutputWriter}s to perform the logging
15 * of recorded messages. It initializes a new writer if the first message for a specific
16 * client is received and it closes a writer if for a specific period of time no further message
17 * of the same client was received. The writers themselves consider log rotation. For handling
18 * messages, the {@link HtmlMonitorMessageListener} mechanism provided by the
19 * {@link HtmlMonitorServer} is used.
20 * </p>
21 *
22 * @author Patrick Harms
23 */
24class HtmlMonitorLogManager implements HtmlMonitorComponent, HtmlMonitorMessageListener {
25   
26    /**
27     * the timeout after which a writer of an inactive client is closed
28     */
29    private static final int SESSION_TIMEOUT = 100000;
30   
31    /**
32     * the directory into which the log files shall be written
33     */
34    private String logFileBaseDir;
35
36    /**
37     * the mapping of client ids to the respective writers.
38     */
39    private Map<String, HtmlMonitorOutputWriter> writers;
40
41    /**
42     * a timer used to detect client timouts
43     */
44    private Timer logFileMonitorTimer;
45
46    /**
47     * <p>
48     * initializes the log manager with the directory into which the log files shall be stored
49     * </p>
50     *
51     * @param logFileBaseDir the directory into which the log files shall be stored
52     */
53    HtmlMonitorLogManager(String logFileBaseDir) {
54        this.logFileBaseDir = logFileBaseDir;
55    }
56
57    /* (non-Javadoc)
58     * @see de.ugoe.cs.autoquest.htmlmonitor.HtmlMonitorComponent#init()
59     */
60    @Override
61    public synchronized void init() throws IllegalStateException, HtmlMonitorException {
62        if (writers != null) {
63            throw new IllegalStateException("already initialized");
64        }
65       
66        writers = new HashMap<String, HtmlMonitorOutputWriter>();
67        logFileMonitorTimer = new Timer();
68    }
69
70    /* (non-Javadoc)
71     * @see de.ugoe.cs.autoquest.htmlmonitor.HtmlMonitorComponent#start()
72     */
73    @Override
74    public synchronized void start() throws IllegalStateException, HtmlMonitorException {
75        if (writers == null) {
76            throw new IllegalStateException("not initialized");
77        }
78       
79        logFileMonitorTimer.schedule
80            (new LogFileMonitorTimerTask(), SESSION_TIMEOUT / 2, SESSION_TIMEOUT / 2);
81    }
82
83    /* (non-Javadoc)
84     * @see de.ugoe.cs.autoquest.htmlmonitor.HtmlMonitorComponent#stop()
85     */
86    @Override
87    public synchronized void stop() {
88        if (writers != null) {
89            logFileMonitorTimer.cancel();
90           
91            for (HtmlMonitorOutputWriter writer : writers.values()) {
92                writer.stop();
93            }
94        }
95       
96        writers = null;
97    }
98
99    /* (non-Javadoc)
100     * @see HtmlMonitoringListener#handleEvents(HtmlClientInfos, HtmlEvent[])
101     */
102    @Override
103    public void handleMessage(HtmlClientInfos clientInfos, HtmlEvent[] events) {
104        HtmlMonitorOutputWriter writer = writers.get(clientInfos.getClientId());
105       
106        try {
107            if (writer == null) {
108                synchronized (this) {
109                    writer = writers.get(clientInfos.getClientId());
110                    if (writer == null) {
111                        writer =
112                            new HtmlMonitorOutputWriter(logFileBaseDir, clientInfos.getClientId());
113                        writer.init();
114                        writer.start();
115                        writers.put(clientInfos.getClientId(), writer);
116                    }
117                }
118            }
119
120            writer.handleMessage(clientInfos, events);
121        }
122        catch (Exception e) {
123            Console.printerrln("could not handle message of client " + clientInfos.getClientId() +
124                               ": " + e);
125            Console.logException(e);
126           
127            // determine, if the writer exists but is not able to log something. In this case,
128            // destroy the writer (part of the message may be logged twice through this).
129            writer = writers.get(clientInfos.getClientId());
130            if (writer != null) {
131                try {
132                    writer.handleMessage(clientInfos, events);
133                }
134                catch (Exception e1) {
135                    synchronized (this) {
136                        writers.remove(clientInfos.getClientId());
137                        writer.stop();
138                    }
139                }
140            }
141        }
142    }
143
144    /**
145     * <p>
146     * internal timer task used for detecting session timeouts of clients
147     * </p>
148     *
149     * @author Patrick Harms
150     */
151    public class LogFileMonitorTimerTask extends TimerTask {
152
153        /* (non-Javadoc)
154         * @see java.lang.Runnable#run()
155         */
156        @Override
157        public void run() {
158            synchronized (HtmlMonitorLogManager.this) {
159                List<String> timeoutSessions = new ArrayList<String>();
160                for (Map.Entry<String, HtmlMonitorOutputWriter> entry : writers.entrySet()) {
161                    HtmlMonitorOutputWriter writer = entry.getValue();
162                   
163                    if (System.currentTimeMillis() - writer.getLastUpdate() > SESSION_TIMEOUT) {
164                        timeoutSessions.add(entry.getKey());
165                    }
166                }
167               
168                for (String clientId : timeoutSessions) {
169                    HtmlMonitorOutputWriter writer = writers.remove(clientId);
170                    writer.stop();
171                }
172            }
173        }
174
175    }
176
177}
Note: See TracBrowser for help on using the repository browser.