View Javadoc

1   /*
2    * $Id: StatusLogger.java,v 1.3 2005/05/27 16:21:18 clq2 Exp $
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.io.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); //append
51           
52           //get time taken
53  //         Date timeTaken = new Date(status.getTimestamp().getTime() - status.getFirst().getStartTime().getTime());
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           //if we can't reach the pages, assume a unit test or similar
78           log.warn(ioe+", copying query "+status.getId()+" status from '"+statusUrl+"' to "+statusPageDirectory+" -> could not persist status page");
79        }
80        catch (PropertyNotFoundException pnfe) {
81           //couldn't find stem, never mind
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                //set start time by using a previous
113                DefaultTaskStatus prev = new DefaultTaskStatus(status, status.INITIALISED);
114                prev.setTimestamp(new Date(Long.parseLong(startTime)));
115                prev.setPrevious(null); //constructor assumes status is previous
116                status.setPrevious(prev);
117                
118                statuses.add(status);
119             }
120             catch (NumberFormatException nfe) {
121                //format has changed perhaps.  Log & continue
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(); //make sure it's loaded
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; //not found
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          //never mind, it's just not been stored for some reason
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 //      new ServerStatusHtmlRenderer().writeHtmlStatus(new OutputStreamWriter(System.out), new DataServer().getStatus().getServiceStatus(), persisted);
176    }
177 }
178