001: /*
002: * This file or a portion of this file is licensed under the terms of
003: * the Globus Toolkit Public License, found in file GTPL, or at
004: * http://www.globus.org/toolkit/download/license.html. This notice must
005: * appear in redistributions of this file, with or without modification.
006: *
007: * Redistributions of this Software, with or without modification, must
008: * reproduce the GTPL in: (1) the Software, or (2) the Documentation or
009: * some other similar material which is provided with the Software (if
010: * any).
011: *
012: * Copyright 1999-2004 University of Chicago and The University of
013: * Southern California. All rights reserved.
014: */
015: package org.griphyn.cPlanner.visualize.spaceusage;
016:
017: import org.griphyn.cPlanner.visualize.Callback;
018:
019: import org.griphyn.cPlanner.common.LogManager;
020:
021: import java.io.File;
022: import java.io.FileReader;
023: import java.io.BufferedReader;
024: import java.io.IOException;
025:
026: import java.util.StringTokenizer;
027: import java.util.List;
028: import java.util.Map;
029: import java.util.HashMap;
030: import java.util.Date;
031:
032: /**
033: * The callback parses the jobstate.log file to order the events of how
034: * the jobs executed.
035: *
036: * @author Karan Vahi vahi@isi.edu
037: *
038: * @version $Revision: 50 $
039: */
040:
041: public class TailStatd extends SpaceUsageCallback {
042:
043: /**
044: * The name of the tailstatd file.
045: */
046: public static final String JOBSTATE_LOG = "jobstate.log";
047:
048: /**
049: * The state in the jobstate that is taken to designate the GRIDSTART_PREJOB
050: * time.
051: */
052: public static final String GRIDSTART_PREJOB_STATE = "EXECUTE";
053:
054: /**
055: * The state in the jobstate that is taken to designate the GRIDSTART_MAINJOB
056: * time.
057: */
058: public static final String GRIDSTART_MAINJOB_STATE = "EXECUTE";
059:
060: /**
061: * The state in the jobstate that is taken to designate the GRIDSTART_POSTJOB
062: * time.
063: */
064: public static final String GRIDSTART_POSTJOB_STATE = "JOB_TERMINATED";
065:
066: /**
067: * The directory where all the files reside.
068: */
069: private String mDirectory;
070:
071: /**
072: * A Map store that stores JobSpace objects indexed by the name of the jobs.
073: */
074: private Map mJobSpaceStore;
075:
076: /**
077: * The handle to the logging object
078: */
079: private LogManager mLogger;
080:
081: /**
082: * The default constructor.
083: */
084: public TailStatd() {
085: super ();
086: mDirectory = ".";
087: mJobSpaceStore = new HashMap();
088: }
089:
090: /**
091: * Initializes the callback.
092: *
093: * @param directory the directory where all the files reside.
094: * @param useStatInfo boolean indicating whether to use stat info or not.
095: */
096: public void initialize(String directory, boolean useStatInfo) {
097: super .initialize(directory, useStatInfo);
098: mDirectory = directory;
099: File jobstate = new File(directory, this .JOBSTATE_LOG);
100:
101: //some sanity checks on file
102: if (jobstate.exists()) {
103: if (!jobstate.canRead()) {
104: throw new RuntimeException(
105: "The jobstate file does not exist " + jobstate);
106: }
107: } else {
108: throw new RuntimeException(
109: "Unable to read the jobstate file " + jobstate);
110: }
111:
112: BufferedReader reader;
113:
114: try {
115: reader = new BufferedReader(new FileReader(jobstate));
116:
117: String line, time = null, job = null, state = null, token;
118: int count = 0;
119: StringTokenizer st;
120: while ((line = reader.readLine()) != null) {
121:
122: //parse the line contents
123: st = new StringTokenizer(line);
124: count = 1;
125: while (st.hasMoreTokens()) {
126: token = (String) st.nextToken();
127: switch (count) {
128: case 1:
129: time = token;
130: break;
131:
132: case 2:
133: job = token;
134: break;
135:
136: case 3:
137: state = token;
138: break;
139:
140: default:
141: }
142: count++;
143: }
144:
145: if (!validState(state)) {
146: //ignore and move to next line
147: continue;
148: }
149:
150: JobSpace js = (mJobSpaceStore.containsKey(job)) ? (JobSpace) mJobSpaceStore
151: .get(job)
152: : new JobSpace(job);
153: Date d = new Date(Long.parseLong(time) * 1000);
154: Space s = new Space(d);
155: s.setAssociatedJob(job);
156: js.addSpaceReading(s, this .getEventType(state));
157:
158: //specific quirk because i am using same trigger for pre job and main job
159: if (state.equals(this .GRIDSTART_PREJOB_STATE)) {
160: //add the same event reading for the main job
161: js.addSpaceReading((Space) s.clone(),
162: JobSpace.GRIDSTART_MAINJOB_EVENT_TYPE);
163: }
164:
165: //add the js back
166: mJobSpaceStore.put(job, js);
167: }
168: } catch (IOException ioe) {
169: throw new RuntimeException("While reading jobstate file "
170: + jobstate, ioe);
171: }
172:
173: //System.out.println( "Job space store is " + mJobSpaceStore );
174: }
175:
176: /**
177: * Callback for the starting of an invocation record.
178: *
179: * @param job the job/file being parsed.
180: * @param resource the site id where the job was executed.
181: */
182: public void cbInvocationStart(String job, String resource) {
183: mMainJob = job;
184: mSite = resource;
185:
186: mJobOutSize = 0;
187: //get the one from store!
188: mJobSpace = (JobSpace) mJobSpaceStore.get(job);
189: }
190:
191: /**
192: * Parses the content and stores it in a SpaceUsage object.
193: * The date is taken from the jobstate.log instead of the date in the record.
194: *
195: * @param header the header from which the content was collected.
196: * @param content the Content.
197: *
198: * @return Space
199: */
200: protected Space parseContent(String header, String content) {
201: String date = null;
202: String size = null;
203:
204: for (StringTokenizer st = new StringTokenizer(content); st
205: .hasMoreTokens();) {
206: if (date == null) {
207: date = st.nextToken();
208: } else {
209: size = st.nextToken();
210: break;
211: }
212: }
213:
214: JobSpace js = (JobSpace) mJobSpaceStore.get(mMainJob);
215: Space s = js
216: .getSpaceReading(this .getEventTypeForHeader(header));
217:
218: if (s == null) {
219: throw new RuntimeException("JobState " + js
220: + " did not contain information about header "
221: + header);
222: }
223:
224: s.setSize(size);
225: return s;
226: }
227:
228: /**
229: * Returns a boolean indicating whether the state is valid or not.
230: *
231: * @param state the state
232: *
233: * @return boolean
234: */
235: protected boolean validState(String state) {
236: return (state.equals(this .GRIDSTART_MAINJOB_STATE)
237: || state.equals(this .GRIDSTART_POSTJOB_STATE) || state
238: .equals(this .GRIDSTART_PREJOB_STATE));
239: }
240:
241: /**
242: * Returns the event type matching a particular job type
243: *
244: * @param type the state of the job
245: *
246: * @return the corresponding event type
247: */
248: private int getEventType(String state) {
249: int event = -1;
250: if (state.equals(this.GRIDSTART_PREJOB_STATE)) {
251: event = JobSpace.GRIDSTART_PREJOB_EVENT_TYPE;
252: } else if (state.equals(this.GRIDSTART_MAINJOB_STATE)) {
253: event = JobSpace.GRIDSTART_MAINJOB_EVENT_TYPE;
254: } else if (state.equals(this.GRIDSTART_POSTJOB_STATE)) {
255: event = JobSpace.GRIDSTART_POSTJOB_EVENT_TYPE;
256: }
257: return event;
258: }
259: }
|