KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > versant > core > jdo > LogDownloader


1
2 /*
3  * Copyright (c) 1998 - 2005 Versant Corporation
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  * Versant Corporation - initial API and implementation
11  */

12 package com.versant.core.jdo;
13
14 import com.versant.core.util.BeanUtils;
15 import com.versant.core.logging.LogEvent;
16 import com.versant.core.metric.MetricSnapshotPacket;
17
18 import javax.jdo.JDOHelper;
19 import java.util.Properties JavaDoc;
20 import java.util.Date JavaDoc;
21 import java.io.*;
22 import java.text.SimpleDateFormat JavaDoc;
23
24 import com.versant.core.common.BindingSupportImpl;
25 import com.versant.core.common.config.ConfigParser;
26
27 /**
28  * Utility bean to download event logs and performance metric snapshots and
29  * store then in binary and/or text files. The binary files can be opened
30  * in the Workbench for later analysis. This can be run from the command
31  * line or embedded into an application. The JDO Genie server uses an
32  * instance of this class for its built in logging features. To use it in
33  * an application create an instance, set properties and invoke the run()
34  * method at regular intervals (e.g. create a Thread to do this).
35  */

36 public class LogDownloader implements VersantBackgroundTask {
37
38     private String JavaDoc project = "versant.properties";
39     private String JavaDoc host;
40     private int port;
41     private String JavaDoc server;
42     private String JavaDoc username;
43     private String JavaDoc password;
44     private VersantPersistenceManagerFactory pmf;
45     private int eventPollSecs = 1;
46     private int metricPollSecs = 60;
47     private boolean append;
48     private int maxFileSizeK = 1000;
49     private int backups = 3;
50     private String JavaDoc filename;
51     private boolean eventBinary = true;
52     private boolean eventText;
53     private String JavaDoc dateFormat = "HH:mm:ss.SSS";
54     private boolean metricBinary = true;
55     private boolean quiet;
56     private boolean single;
57
58     private boolean shutdown;
59
60     private int lastEventId;
61     private RollingFile eventBinaryFile;
62     private ObjectOutputStream eventOutput;
63     private RollingFile eventTextFile;
64     private OutputStreamWriter eventWriter;
65     private SimpleDateFormat JavaDoc eventDateFormat;
66
67     private int lastMetricId;
68     private RollingFile metricBinaryFile;
69     private ObjectOutputStream metricOutput;
70     private boolean metricsDone;
71
72     private boolean downloadedEvents;
73     private boolean downloadedMetrics;
74
75     private static final String JavaDoc LINE_SEPARATOR = System.getProperty(
76             "line.separator");
77
78     public static void main(String JavaDoc[] args) {
79         try {
80             LogDownloader l = new LogDownloader();
81             BeanUtils.setCommandLineArgs(l, args, new String JavaDoc[]{
82                 "host", "port", "server", "username", "password", "eventPollSecs",
83                 "metricPollSecs", "append", "maxFileSizeK", "backups", "filename",
84                 "eventBinary", "eventText", "metricBinary", "quiet", "project"
85             });
86             run(l);
87             System.exit(0);
88         } catch (Exception JavaDoc x) {
89             x.printStackTrace(System.out);
90             System.exit(1);
91         }
92     }
93
94     public static void run(LogDownloader l) throws Exception JavaDoc {
95         if (l.getProject() != null) {
96             Properties JavaDoc p = loadProperties(l.getProject());
97             if (l.getHost() == null) {
98                 l.setHost(p.getProperty("versant.host"));
99             }
100             if (l.getServer() == null) {
101                 l.setServer(p.getProperty(ConfigParser.SERVER));
102             }
103             if (l.getPort() == 0) {
104                 String JavaDoc s = p.getProperty(ConfigParser.SERVER_PORT);
105                 if (s != null) {
106                     try {
107                         l.setPort(Integer.parseInt(s));
108                     } catch (NumberFormatException JavaDoc e) {
109                         throw BindingSupportImpl.getInstance().illegalArgument(
110                                 "Invalid port: " + e);
111                     }
112                 }
113             }
114         }
115         if (l.getHost() == null) {
116             throw BindingSupportImpl.getInstance().illegalArgument(
117                     "-host is required");
118         }
119         if (l.getServer() == null) {
120             throw BindingSupportImpl.getInstance().illegalArgument(
121                     "-server is required");
122         }
123         Properties JavaDoc p = new Properties JavaDoc();
124         String JavaDoc host = l.getHost();
125         int port = l.getPort();
126         String JavaDoc server = l.getServer();
127         p.setProperty(ConfigParser.PMF_CLASS,
128                 "com.versant.core.jdo.BootstrapPMF");
129         p.setProperty("versant.host", host);
130         p.setProperty(ConfigParser.SERVER, server);
131         if (port != 0) p.setProperty(ConfigParser.SERVER_PORT, Integer.toString(port));
132         if (!l.isQuiet()) {
133             System.out.println("Connecting to " + host +
134                     (port == 0 ? "" : ":" + port) + "/" + server);
135         }
136         if (l.getUsername() != null) {
137             p.setProperty("versant.remoteUsername", l.getUsername());
138         }
139         if (l.getPassword() != null) {
140             p.setProperty("versant.remotePassword", l.getPassword());
141         }
142         VersantPersistenceManagerFactory pmf =
143                 (VersantPersistenceManagerFactory)JDOHelper.getPersistenceManagerFactory(
144                         p);
145         l.setPmf(pmf);
146         l.run();
147     }
148
149     private static Properties JavaDoc loadProperties(String JavaDoc filename)
150             throws IOException {
151         ClassLoader JavaDoc cl = LogDownloader.class.getClassLoader();
152         InputStream in = null;
153         try {
154             if (filename.startsWith("/")) filename = filename.substring(1);
155             in = cl.getResourceAsStream(filename);
156             if (in == null) {
157                 throw BindingSupportImpl.getInstance().runtime(
158                         "Resource not found: " + filename);
159             }
160             Properties JavaDoc p = new Properties JavaDoc();
161             p.load(in);
162             return p;
163         } finally {
164             if (in != null) in.close();
165         }
166     }
167
168     public void setPmf(VersantPersistenceManagerFactory pmf) throws Exception JavaDoc {
169         this.pmf = pmf;
170
171         if (!eventBinary && !eventText && !metricBinary) {
172             return;
173         }
174
175         if (filename == null) {
176             filename = generateFilename();
177         }
178
179         int maxSize = maxFileSizeK * 1024;
180
181         if (eventBinary) {
182             eventBinaryFile = new RollingFile(filename + ".jdolog");
183             eventBinaryFile.setMaxBackupIndex(backups);
184             eventBinaryFile.setMaxSize(maxSize);
185             openEventBinaryFile();
186         }
187
188         if (eventText) {
189             eventDateFormat = new SimpleDateFormat JavaDoc(dateFormat);
190             eventTextFile = new RollingFile(filename + ".txt");
191             eventTextFile.setMaxBackupIndex(backups);
192             eventTextFile.setMaxSize(maxSize);
193             eventTextFile.setAppend(append);
194             openEventTextFile();
195         }
196
197         if (metricBinary) {
198             metricBinaryFile = new RollingFile(filename + ".jdoperf");
199             metricBinaryFile.setMaxBackupIndex(backups);
200             metricBinaryFile.setMaxSize(maxSize);
201             openMetricBinaryFile();
202         }
203     }
204
205     /**
206      * Generate a filename. This is invoked if no filename has been set when
207      * the pmf is set.
208      */

209     protected String JavaDoc generateFilename() {
210         if (server != null) {
211             return "openaccess_" + (host == null ? "" : host + "_") + server;
212         } else {
213             return "openaccess";
214         }
215     }
216
217     public void run() {
218         try {
219             runImp();
220         } catch (Exception JavaDoc e) {
221             if (!shutdown) {
222                 e.printStackTrace(System.out);
223             }
224         }
225     }
226
227     protected void log(String JavaDoc msg) {
228         if (quiet) return;
229         System.out.println(new Date JavaDoc() + " " + msg);
230     }
231
232     protected void runImp() throws Exception JavaDoc {
233         boolean eventsOn = eventBinary || eventText;
234         if (!eventsOn && !metricBinary) return;
235
236         try {
237             log("Log downloader running");
238
239             long lastEventTime = 0;
240             long lastMetricTime = 0;
241             int eventPoll = eventPollSecs * 1000;
242             if (eventPoll < 1000) eventPoll = 1000;
243             int metricPoll = metricPollSecs * 1000;
244             if (metricPoll < 1000) metricPoll = 1000;
245             long sleep = 0;
246             for (; !shutdown;) {
247                 try {
248                     if (sleep > 0) Thread.sleep(sleep);
249                 } catch (InterruptedException JavaDoc e) {
250                     // ignore
251
}
252
253                 long now = System.currentTimeMillis();
254
255                 if (eventsOn) {
256                     if (shutdown || now - lastEventTime >= eventPoll) {
257                         lastEventTime = now;
258                         downloadEvents();
259                         sleep = eventPoll;
260                     } else {
261                         sleep = now - lastEventTime;
262                     }
263                 } else {
264                     sleep = Long.MAX_VALUE;
265                 }
266
267                 if (metricBinary) {
268                     long nsleep;
269                     if (shutdown || now - lastMetricTime >= metricPoll) {
270                         lastMetricTime = now;
271                         downloadMetrics();
272                         nsleep = metricPoll;
273                     } else {
274                         nsleep = now - lastMetricTime;
275                     }
276                     if (nsleep < sleep) sleep = nsleep;
277                 }
278
279                 if (single && (downloadedEvents || downloadedMetrics)) {
280                     shutdown();
281                 }
282             }
283
284             if (eventOutput != null) eventOutput.close();
285             if (eventWriter != null) eventWriter.close();
286             if (metricOutput != null) metricOutput.close();
287         } finally {
288             log("Log downloader stopped");
289         }
290     }
291
292     private void downloadEvents() throws IOException {
293         LogEvent[] a = pmf.getNewPerfEvents(lastEventId);
294         if (a == null) return;
295         downloadedEvents = true;
296         int n = a.length;
297         log("Received " + n + " event(s)");
298         lastEventId = a[n - 1].getId();
299         if (eventText) {
300             StringBuffer JavaDoc s = new StringBuffer JavaDoc();
301             Date JavaDoc d = new Date JavaDoc();
302             for (int i = 0; i < n; i++) {
303                 LogEvent ev = a[i];
304                 d.setTime(ev.getStart());
305                 s.append(eventDateFormat.format(d));
306                 s.append(' ');
307                 s.append(ev);
308                 s.append(LINE_SEPARATOR);
309             }
310             eventWriter.write(s.toString());
311             if (eventTextFile.isRolloverRequired()) {
312                 eventWriter.close();
313                 eventTextFile.rollover();
314                 openEventTextFile();
315             } else {
316                 eventWriter.flush();
317             }
318         }
319         if (eventBinary) {
320             eventOutput.writeObject(a);
321             if (eventBinaryFile.isRolloverRequired()) {
322                 eventOutput.close();
323                 eventBinaryFile.rollover();
324                 openEventBinaryFile();
325             } else {
326                 eventOutput.flush();
327             }
328         }
329     }
330
331     private void downloadMetrics() throws IOException {
332         // make sure each file contains the Metric's themselves
333
if (!metricsDone) {
334             metricOutput.writeObject(pmf.getMetrics());
335             metricOutput.flush();
336             metricsDone = true;
337         }
338         MetricSnapshotPacket a = pmf.getNewMetricSnapshots(lastMetricId);
339         if (a == null) return;
340         downloadedMetrics = true;
341         log("Received " + a.getSize() + " snapshot(s)");
342         lastMetricId = a.getMostRecentID();
343         metricOutput.writeObject(a);
344         if (metricBinaryFile.isRolloverRequired()) {
345             metricOutput.close();
346             metricBinaryFile.rollover();
347             openMetricBinaryFile();
348             metricsDone = false;
349         } else {
350             metricOutput.flush();
351         }
352     }
353
354     private void openEventBinaryFile() throws IOException {
355         eventOutput = new ObjectOutputStream(eventBinaryFile.getOut());
356     }
357
358     private void openEventTextFile() throws IOException {
359         eventWriter = new OutputStreamWriter(eventTextFile.getOut());
360     }
361
362     private void openMetricBinaryFile() throws IOException {
363         metricOutput = new ObjectOutputStream(metricBinaryFile.getOut());
364     }
365
366     /**
367      * Stop downloading events. This will cause one more call to the server
368      * to get any remaining data and then the run method will return. You
369      * should also interrupt the Thread that called run to speed exit of
370      * the run method.
371      */

372     public void shutdown() {
373         shutdown = true;
374     }
375
376     public String JavaDoc getProject() {
377         return project;
378     }
379
380     public void setProject(String JavaDoc project) {
381         this.project = project;
382     }
383
384     public String JavaDoc getHost() {
385         return host;
386     }
387
388     public void setHost(String JavaDoc host) {
389         this.host = host;
390     }
391
392     public int getPort() {
393         return port;
394     }
395
396     public void setPort(int port) {
397         this.port = port;
398     }
399
400     public String JavaDoc getServer() {
401         return server;
402     }
403
404     public void setServer(String JavaDoc server) {
405         this.server = server;
406     }
407
408     public String JavaDoc getUsername() {
409         return username;
410     }
411
412     public void setUsername(String JavaDoc username) {
413         this.username = username;
414     }
415
416     public String JavaDoc getPassword() {
417         return password;
418     }
419
420     public void setPassword(String JavaDoc password) {
421         this.password = password;
422     }
423
424     public VersantPersistenceManagerFactory getPmf() {
425         return pmf;
426     }
427
428     public int getEventPollSecs() {
429         return eventPollSecs;
430     }
431
432     public void setEventPollSecs(int eventPollSecs) {
433         this.eventPollSecs = eventPollSecs;
434     }
435
436     public int getMetricPollSecs() {
437         return metricPollSecs;
438     }
439
440     public void setMetricPollSecs(int metricPollSecs) {
441         this.metricPollSecs = metricPollSecs;
442     }
443
444     public boolean isAppend() {
445         return append;
446     }
447
448     public void setAppend(boolean append) {
449         this.append = append;
450     }
451
452     public int getMaxFileSizeK() {
453         return maxFileSizeK;
454     }
455
456     public void setMaxFileSizeK(int maxFileSizeK) {
457         this.maxFileSizeK = maxFileSizeK;
458     }
459
460     public int getBackups() {
461         return backups;
462     }
463
464     public void setBackups(int backups) {
465         this.backups = backups;
466     }
467
468     public String JavaDoc getFilename() {
469         return filename;
470     }
471
472     public void setFilename(String JavaDoc filename) {
473         this.filename = filename;
474     }
475
476     public boolean isEventBinary() {
477         return eventBinary;
478     }
479
480     public void setEventBinary(boolean eventBinary) {
481         this.eventBinary = eventBinary;
482     }
483
484     public boolean isEventText() {
485         return eventText;
486     }
487
488     public void setEventText(boolean eventText) {
489         this.eventText = eventText;
490     }
491
492     public boolean isMetricBinary() {
493         return metricBinary;
494     }
495
496     public void setMetricBinary(boolean metricBinary) {
497         this.metricBinary = metricBinary;
498     }
499
500     public boolean isQuiet() {
501         return quiet;
502     }
503
504     public void setQuiet(boolean quiet) {
505         this.quiet = quiet;
506     }
507
508     public String JavaDoc getDateFormat() {
509         return dateFormat;
510     }
511
512     public void setDateFormat(String JavaDoc dateFormat) {
513         this.dateFormat = dateFormat;
514     }
515
516     public boolean isSingle() {
517         return single;
518     }
519
520     public void setSingle(boolean single) {
521         this.single = single;
522     }
523
524 }
525
Popular Tags