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

Last change on this file since 1268 was 1227, checked in by pharms, 11 years ago
  • changed log file directory structure for better distinguishing the monitored applications
  • extended session timeout to potentially reduce log file sizes
  • increased log file maximum sizes to reduce storage consumption due do GUI model duplication
File size: 6.5 KB
Line 
1//   Copyright 2012 Georg-August-Universität Göttingen, Germany
2//
3//   Licensed under the Apache License, Version 2.0 (the "License");
4//   you may not use this file except in compliance with the License.
5//   You may obtain a copy of the License at
6//
7//       http://www.apache.org/licenses/LICENSE-2.0
8//
9//   Unless required by applicable law or agreed to in writing, software
10//   distributed under the License is distributed on an "AS IS" BASIS,
11//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12//   See the License for the specific language governing permissions and
13//   limitations under the License.
14
15package de.ugoe.cs.autoquest.htmlmonitor;
16
17import java.util.ArrayList;
18import java.util.HashMap;
19import java.util.List;
20import java.util.Map;
21import java.util.Timer;
22import java.util.TimerTask;
23
24import de.ugoe.cs.util.console.Console;
25
26/**
27 * <p>
28 * The log manager handles different {@link HtmlMonitorOutputWriter}s to perform the logging
29 * of recorded messages. It initializes a new writer if the first message for a specific
30 * client is received and it closes a writer if for a specific period of time no further message
31 * of the same client was received. The writers themselves consider log rotation. For handling
32 * messages, the {@link HtmlMonitorMessageListener} mechanism provided by the
33 * {@link HtmlMonitorServer} is used.
34 * </p>
35 *
36 * @author Patrick Harms
37 */
38class HtmlMonitorLogManager implements HtmlMonitorComponent, HtmlMonitorMessageListener {
39   
40    /**
41     * the timeout after which a writer of an inactive client is closed
42     */
43    private static final int SESSION_TIMEOUT = 10 * 60 * 1000;
44   
45    /**
46     * the directory into which the log files shall be written
47     */
48    private String logFileBaseDir;
49
50    /**
51     * the mapping of client ids to the respective writers.
52     */
53    private Map<String, HtmlMonitorOutputWriter> writers;
54
55    /**
56     * a timer used to detect client timouts
57     */
58    private Timer logFileMonitorTimer;
59
60    /**
61     * <p>
62     * initializes the log manager with the directory into which the log files shall be stored
63     * </p>
64     *
65     * @param logFileBaseDir the directory into which the log files shall be stored
66     */
67    HtmlMonitorLogManager(String logFileBaseDir) {
68        this.logFileBaseDir = logFileBaseDir;
69    }
70
71    /* (non-Javadoc)
72     * @see de.ugoe.cs.autoquest.htmlmonitor.HtmlMonitorComponent#init()
73     */
74    @Override
75    public synchronized void init() throws IllegalStateException, HtmlMonitorException {
76        if (writers != null) {
77            throw new IllegalStateException("already initialized");
78        }
79       
80        writers = new HashMap<String, HtmlMonitorOutputWriter>();
81        logFileMonitorTimer = new Timer();
82    }
83
84    /* (non-Javadoc)
85     * @see de.ugoe.cs.autoquest.htmlmonitor.HtmlMonitorComponent#start()
86     */
87    @Override
88    public synchronized void start() throws IllegalStateException, HtmlMonitorException {
89        if (writers == null) {
90            throw new IllegalStateException("not initialized");
91        }
92       
93        logFileMonitorTimer.schedule
94            (new LogFileMonitorTimerTask(), SESSION_TIMEOUT / 2, SESSION_TIMEOUT / 2);
95    }
96
97    /* (non-Javadoc)
98     * @see de.ugoe.cs.autoquest.htmlmonitor.HtmlMonitorComponent#stop()
99     */
100    @Override
101    public synchronized void stop() {
102        if (writers != null) {
103            logFileMonitorTimer.cancel();
104           
105            for (HtmlMonitorOutputWriter writer : writers.values()) {
106                writer.stop();
107            }
108        }
109       
110        writers = null;
111    }
112
113    /* (non-Javadoc)
114     * @see HtmlMonitoringListener#handleEvents(HtmlClientInfos, HtmlEvent[])
115     */
116    @Override
117    public void handleMessage(HtmlClientInfos clientInfos,
118                              HtmlGUIElement  guiStructure,
119                              HtmlEvent[]     events)
120    {
121        HtmlMonitorOutputWriter writer = writers.get(clientInfos.getClientId());
122       
123        try {
124            if (writer == null) {
125                synchronized (this) {
126                    writer = writers.get(clientInfos.getClientId());
127                    if (writer == null) {
128                        writer = new HtmlMonitorOutputWriter
129                            (logFileBaseDir, clientInfos.getWebAppId(), clientInfos.getClientId());
130
131                        writer.init();
132                        writer.start();
133                        writers.put(clientInfos.getClientId(), writer);
134                    }
135                }
136            }
137
138            writer.handleMessage(clientInfos, guiStructure, events);
139        }
140        catch (Exception e) {
141            Console.printerrln("could not handle message of client " + clientInfos.getClientId() +
142                               ": " + e);
143            e.printStackTrace();
144            Console.logException(e);
145           
146            // determine, if the writer exists but is not able to log something. In this case,
147            // destroy the writer (part of the message may be logged twice through this).
148            writer = writers.get(clientInfos.getClientId());
149            if (writer != null) {
150                try {
151                    writer.handleMessage(clientInfos, guiStructure, events);
152                }
153                catch (Exception e1) {
154                    synchronized (this) {
155                        writers.remove(clientInfos.getClientId());
156                        writer.stop();
157                    }
158                }
159            }
160        }
161    }
162
163    /**
164     * <p>
165     * internal timer task used for detecting session timeouts of clients
166     * </p>
167     *
168     * @author Patrick Harms
169     */
170    public class LogFileMonitorTimerTask extends TimerTask {
171
172        /* (non-Javadoc)
173         * @see java.lang.Runnable#run()
174         */
175        @Override
176        public void run() {
177            synchronized (HtmlMonitorLogManager.this) {
178                List<String> timeoutSessions = new ArrayList<String>();
179                for (Map.Entry<String, HtmlMonitorOutputWriter> entry : writers.entrySet()) {
180                    HtmlMonitorOutputWriter writer = entry.getValue();
181                   
182                    if (System.currentTimeMillis() - writer.getLastUpdate() > SESSION_TIMEOUT) {
183                        timeoutSessions.add(entry.getKey());
184                    }
185                }
186               
187                for (String clientId : timeoutSessions) {
188                    HtmlMonitorOutputWriter writer = writers.remove(clientId);
189                    writer.stop();
190                }
191            }
192        }
193
194    }
195
196}
Note: See TracBrowser for help on using the repository browser.