1
2
3
4
5 package org.astrogrid.dataservice.queriers.status;
6
7 import java.io.*;
8
9 import java.net.URL;
10 import java.util.Date;
11 import java.util.StringTokenizer;
12 import java.util.Vector;
13 import org.apache.commons.logging.Log;
14 import org.apache.commons.logging.LogFactory;
15 import org.astrogrid.account.LoginAccount;
16 import org.astrogrid.cfg.PropertyNotFoundException;
17 import org.astrogrid.cfg.ConfigFactory;
18 import org.astrogrid.dataservice.service.ServletHelper;
19 import org.astrogrid.io.Piper;
20 import org.astrogrid.status.DefaultTaskStatus;
21 import org.astrogrid.status.TaskStatus;
22
23 /***
24 * Used to log status information to disk so we can look at it later. It basically
25 * records the output from the server
26 */
27
28
29 public class StatusLogger {
30
31 public final static String STATUS_PAGE_DIRECTORY_KEY = "datacenter.status.page.directory";
32
33 File statusPageDirectory = null;
34 File statusLog = null;
35
36 TaskStatus[] persistedCache = null;
37
38 Log log = LogFactory.getLog(StatusLogger.class);
39
40 public StatusLogger() {
41 statusPageDirectory = new File(ConfigFactory.getCommonConfig().getString(STATUS_PAGE_DIRECTORY_KEY, "/tmp/"));
42 statusLog = new File(statusPageDirectory, "palstatus.log");
43 }
44
45 /*** Stores copy of status page on disk, and adds to summary list file */
46 public void log(TaskStatus status) {
47
48 /*** Store summary details in log */
49 try {
50 Writer w = new FileWriter(statusLog, true);
51
52
53
54
55 w.write(status.getId()+", "+status.getStage().toString()+", "+status.getFirst().getTimestamp().getTime()+", "+status.getTimestamp().getTime()+", "+status.getOwner()+", "+status.getSource()+", "+status.getProgressMax());
56 w.write("\n");
57 w.close();
58 }
59 catch (IOException e) {
60 log.error("Writing query '"+status.getId()+"' status to "+statusPageDirectory,e);
61 }
62
63 /*** Store status page if it can be reached */
64 String statusUrl = null;
65 try {
66 statusUrl = ServletHelper.getUrlStem()+"queryStatus.jsp?ID="+status.getId();
67
68 log.debug("Storing status page "+statusUrl);
69
70 InputStream in = new URL(statusUrl).openStream();
71 OutputStream out = new FileOutputStream(new File(statusPageDirectory, "QueryStatus_"+status.getId()+".html"));
72 Piper.bufferedPipe(in, out);
73 in.close();
74 out.close();
75 }
76 catch (IOException ioe) {
77
78 log.warn(ioe+", copying query "+status.getId()+" status from '"+statusUrl+"' to "+statusPageDirectory+" -> could not persist status page");
79 }
80 catch (PropertyNotFoundException pnfe) {
81
82 log.warn(pnfe+", copying query "+status.getId()+" status from '"+statusUrl+"' to "+statusPageDirectory+" -> could not persist status page");
83 }
84
85 }
86
87 /*** Returns TaskStatus representation of past queries from persisted list
88 * Only need to load once per application run, as any that get written
89 * after loading will be available in the 'live details' list */
90 public synchronized TaskStatus[] getPersistedLog() throws IOException {
91
92 if (persistedCache == null) {
93
94 Vector statuses = new Vector();
95
96 LineNumberReader r = new LineNumberReader(new FileReader(statusLog));
97
98 String line = r.readLine();
99 int lineNum = 1;
100 while (line != null) {
101 try {
102 StringTokenizer splitter = new StringTokenizer(line, ",");
103 DefaultTaskStatus status = new DefaultTaskStatus();
104 status.setId(splitter.nextToken().trim());
105 status.setStage(splitter.nextToken().trim());
106 String startTime = splitter.nextToken().trim();
107 status.setTimestamp(new Date(Long.parseLong(splitter.nextToken().trim())));
108 status.setOwner(new LoginAccount(splitter.nextToken().trim(), null));
109 status.setSource(splitter.nextToken().trim());
110 status.setProgressMax(Long.parseLong(splitter.nextToken().trim()));
111
112
113 DefaultTaskStatus prev = new DefaultTaskStatus(status, status.INITIALISED);
114 prev.setTimestamp(new Date(Long.parseLong(startTime)));
115 prev.setPrevious(null);
116 status.setPrevious(prev);
117
118 statuses.add(status);
119 }
120 catch (NumberFormatException nfe) {
121
122 log.debug(nfe+", in line "+lineNum+" of "+statusLog+"; ignoring line");
123 }
124 lineNum++;
125 line = r.readLine();
126 }
127 r.close();
128 persistedCache = (TaskStatus[]) statuses.toArray(new TaskStatus[] {} );
129 }
130 return persistedCache;
131 }
132
133 /*** Removes the status log file */
134 public void clearStatusLog() {
135 statusLog.delete();
136 }
137
138 /*** Returns the status (if it exists) as loaded from the log file */
139 public TaskStatus getPersistedStatus(String id) throws IOException {
140 TaskStatus[] persisted = getPersistedLog();
141 for (int i = 0; i < persisted.length; i++)
142 {
143 if (persisted[i].getId().equals(id)) {
144 return persisted[i];
145 }
146 }
147 return null;
148 }
149
150 /*** Returns the page (if it exists) */
151 public String getPersistedStatusPage(String id) throws IOException {
152 try {
153 Reader in = new FileReader(new File(statusPageDirectory, "QueryStatus_"+id+".html"));
154 StringWriter out = new StringWriter();
155 Piper.bufferedPipe(in, out);
156 return out.toString();
157 }
158 catch (FileNotFoundException fnfe) {
159 log.warn(fnfe+" getting persisted status page for id "+id);
160
161 return null;
162 }
163 }
164
165 /*** For quick debug/tests */
166 public static void main(String[] args) throws IOException
167 {
168 TaskStatus[] persisted = new StatusLogger().getPersistedLog();
169 for (int i = 0; i < persisted.length; i++)
170 {
171 System.out.println(persisted[i]);
172 }
173 System.out.println("---------HTML:");
174
175
176 }
177 }
178