source: trunk/autoquest-htmlmonitor/src/main/java/de/ugoe/cs/autoquest/htmlmonitor/HtmlMonitorOutputWriter.java @ 857

Last change on this file since 857 was 857, checked in by pharms, 12 years ago
  • initial version of the HTML monitor
File size: 7.6 KB
Line 
1
2package de.ugoe.cs.autoquest.htmlmonitor;
3
4import java.io.File;
5import java.io.FileOutputStream;
6import java.io.IOException;
7import java.io.OutputStreamWriter;
8import java.io.PrintWriter;
9import java.text.DecimalFormat;
10
11/**
12 * <p>
13 * comment
14 * </p>
15 *
16 * @author Patrick Harms
17 * @version 1.0
18 *
19 */
20public class HtmlMonitorOutputWriter implements HtmlMonitorComponent, HtmlMonitorMessageListener {
21   
22    /**
23     *
24     */
25    private static final int MAXIMUM_LOG_FILE_SIZE = 10000000;
26
27    /**
28     *
29     */
30    private static final String DEFAULT_LOG_FILE_BASE_DIR = "logs";
31
32    /**
33     *
34     */
35    private File logFileBaseDir;
36
37    /**
38     *
39     */
40    private String clientId;
41
42    /**
43     *
44     */
45    private File logFile;
46
47    /**
48     * <p>
49     * Writer for logging events.
50     * </p>
51     */
52    private PrintWriter outputWriter;
53
54    /**
55     *
56     */
57    private long lastUpdate;
58
59    /**
60     * <p>
61     *
62     * </p>
63     *
64     * @param outputWriter
65     *            writer for the logged information
66     */
67    public HtmlMonitorOutputWriter(String logFileBaseDir, String clientId) {
68        if (logFileBaseDir == null) {
69            this.logFileBaseDir = new File(DEFAULT_LOG_FILE_BASE_DIR);
70        }
71        else {
72            this.logFileBaseDir = new File(logFileBaseDir);
73        }
74       
75        this.clientId = clientId;
76       
77        lastUpdate = System.currentTimeMillis();
78    }
79
80    /* (non-Javadoc)
81     * @see de.ugoe.cs.autoquest.htmlmonitor.HtmlMonitorComponent#init()
82     */
83    @Override
84    public synchronized void init() throws HtmlMonitorException {
85        if (outputWriter != null) {
86            throw new IllegalStateException("already initialized. Call close() first");
87        }
88       
89        synchronized (HtmlMonitorOutputWriter.class) {
90            try {
91                File clientLogDir = new File(logFileBaseDir, clientId);
92           
93                if (!clientLogDir.exists()) {
94                    clientLogDir.mkdirs();
95                }
96                else if (!clientLogDir.isDirectory()) {
97                    throw new HtmlMonitorException("client log file directory " + clientLogDir +
98                                                   " already exists as a file");
99                }
100               
101                logFile = new File(clientLogDir, getLogFileName(-1));
102               
103                if (logFile.exists()) {
104                    rotateLogFile();
105                }
106           
107                createLogWriter();
108            }
109            catch (IOException e) {
110                throw new HtmlMonitorException("could not open logfile " + logFile, e);
111            }
112        }
113       
114        lastUpdate = System.currentTimeMillis();
115    }
116
117    /**
118     * <p>
119     * TODO: comment
120     * </p>
121     *
122     * @param logFileIndex2
123     * @return
124     */
125    private String getLogFileName(int index) {
126        String result = "htmlmonitor_" + clientId;
127       
128        if (index >= 0) {
129            result += "_" + new DecimalFormat("000" ).format(index);
130        }
131       
132        result += ".log";
133       
134        return result;
135    }
136
137    /* (non-Javadoc)
138     * @see de.ugoe.cs.autoquest.htmlmonitor.HtmlMonitorComponent#start()
139     */
140    @Override
141    public synchronized void start() throws IllegalStateException, HtmlMonitorException {
142        lastUpdate = System.currentTimeMillis();
143    }
144
145    /* (non-Javadoc)
146     * @see de.ugoe.cs.autoquest.htmlmonitor.HtmlMonitorMessageListener#handleMessage(de.ugoe.cs.quest.htmlmonitor.HtmlClientInfos, de.ugoe.cs.quest.htmlmonitor.HtmlEvent[])
147     */
148    @Override
149    public void handleMessage(HtmlClientInfos clientInfos, HtmlEvent[] events) {
150        if (outputWriter == null) {
151            throw new IllegalStateException("not initialized. Call init() first");
152        }
153       
154        for (HtmlEvent event : events) {
155            dumpEvent(event);
156        }
157       
158        outputWriter.flush();
159       
160        try {
161            considerLogRotate();
162        }
163        catch (IOException e) {
164            throw new IllegalStateException("could not perform log rotation: " + e, e);
165        }
166       
167        lastUpdate = System.currentTimeMillis();
168    }
169
170    /**
171     * <p>
172     * TODO: comment
173     * </p>
174     *
175     * @param event
176     */
177    private void dumpEvent(HtmlEvent event) {
178        dumpString(event.getClientInfos().getClientId());
179        outputWriter.print(' ');
180        dumpString(event.getTime().toString());
181        outputWriter.print(' ');
182        dumpString(event.getClientInfos().getTitle());
183        outputWriter.print(' ');
184        dumpString(event.getClientInfos().getUrl().toString());
185        outputWriter.print(' ');
186        dumpString(event.getClientInfos().getUserAgent());
187        outputWriter.print(' ');
188        dumpString(event.getEventType());
189        outputWriter.print(' ');
190        dumpString(event.getPath());
191
192        if (event.getCoordinates() != null) {
193            outputWriter.print(' ');
194           
195            StringBuffer value = new StringBuffer();
196            for (int i = 0; i < event.getCoordinates().length; i++) {
197                if (i > 0) {
198                    value.append(',');
199                }
200                value.append(event.getCoordinates()[i]);
201            }
202           
203            dumpString(value.toString());
204        }
205
206        if (event.getKey() != null) {
207            outputWriter.print(' ');
208            dumpString(event.getKey().toString());
209        }
210           
211        if (event.getScrollPosition() != null) {
212            outputWriter.print(' ');
213            dumpString(event.getScrollPosition().toString());
214        }
215           
216        outputWriter.println();
217    }
218
219    /**
220     * <p>
221     * TODO: comment
222     * </p>
223     *
224     * @param clientId2
225     */
226    private void dumpString(String str) {
227        outputWriter.print('"');
228        outputWriter.print(str.replaceAll("\\\\", "\\\\").replaceAll("\\\"", "\\\""));
229        outputWriter.print('"');
230    }
231
232    /**
233     * <p>
234     * TODO: comment
235     * </p>
236     *
237     */
238    private synchronized void considerLogRotate() throws IOException {
239        if (logFile.length() > MAXIMUM_LOG_FILE_SIZE) {
240            closeLogWriter();
241            rotateLogFile();
242            createLogWriter();
243        }
244    }
245
246    /**
247     * <p>
248     * TODO: comment
249     * </p>
250     *
251     */
252    private void rotateLogFile() {
253        File clientLogDir = logFile.getParentFile();
254        File checkFile;
255
256        int logFileIndex = -1;
257        do {
258            logFileIndex++;
259           
260            checkFile = new File(clientLogDir, getLogFileName(logFileIndex));
261        }
262        while (checkFile.exists());
263   
264        logFile.renameTo(checkFile);
265        logFileIndex++;
266        logFile = new File(clientLogDir, getLogFileName(-1));
267    }
268
269    /**
270     * <p>
271     * TODO: comment
272     * </p>
273     *
274     */
275    private void createLogWriter() throws IOException {
276        FileOutputStream fis = new FileOutputStream(logFile);
277        outputWriter = new PrintWriter(new OutputStreamWriter(fis, "UTF-8"));
278    }
279
280    /**
281     * <p>
282     * TODO: comment
283     * </p>
284     *
285     */
286    private void closeLogWriter() {
287        if (outputWriter != null) {
288            outputWriter.flush();
289            outputWriter.close();
290            outputWriter = null;
291        }
292    }
293
294    /* (non-Javadoc)
295     * @see de.ugoe.cs.autoquest.htmlmonitor.HtmlMonitorComponent#stop()
296     */
297    @Override
298    public synchronized void stop() {
299        closeLogWriter();
300        rotateLogFile();
301
302        lastUpdate = System.currentTimeMillis();
303    }
304
305    /**
306     * <p>
307     * TODO: comment
308     * </p>
309     *
310     * @return
311     */
312    public long getLastUpdate() {
313        return lastUpdate;
314    }
315}
Note: See TracBrowser for help on using the repository browser.