001 /*
002 * Benchmark.java
003 *
004 * Copyright (c) 1995-2010, The University of Sheffield. See the file
005 * COPYRIGHT.txt in the software or at http://gate.ac.uk/gate/COPYRIGHT.txt
006 *
007 * This file is part of GATE (see http://gate.ac.uk/), and is free
008 * software, licenced under the GNU Library General Public License,
009 * Version 2, June 1991 (in the distribution as file licence.html,
010 * and also available at http://gate.ac.uk/gate/licence.html).
011 */
012
013 package gate.util;
014
015 import gate.Executable;
016 import gate.creole.ExecutionException;
017
018 import java.util.Date;
019 import java.util.HashMap;
020 import java.util.Map;
021 import org.apache.log4j.Logger;
022
023 /**
024 * This class provides methods for making entries in the shared log
025 * maintained by the GATE system. User should use various methods
026 * provided by this class and as described in the following example.
027 *
028 * <p>
029 *
030 * TODO: Provide example here.
031 *
032 * </p>
033 *
034 * @author niraj
035 */
036 public class Benchmark {
037
038 /**
039 * variable that keeps track of if logging is ON or OFF.
040 */
041 protected static boolean benchmarkingEnabled = false;
042
043 /**
044 * corpus name feature
045 */
046 public final static String CORPUS_NAME_FEATURE = "corpusName";
047
048 /**
049 * application name feature
050 */
051 public final static String APPLICATION_NAME_FEATURE = "applicationName";
052
053 /**
054 * document name feature
055 */
056 public final static String DOCUMENT_NAME_FEATURE = "documentName";
057
058 /**
059 * processing resource name feature
060 */
061 public final static String PR_NAME_FEATURE = "prName";
062
063 /**
064 * message feature
065 */
066 public final static String MESSAGE_FEATURE = "message";
067
068 // various check point ids
069
070 public final static String PR_PREFIX = "pr_";
071
072 public final static String DOCUMENT_LOADED = "documentLoaded";
073
074 public final static String DOCUMENT_SAVED = "documentSaved";
075
076 public final static String WRITING_FVS_TO_DISK = "writingFVsToDisk";
077
078 public final static String ANNOTS_TO_NLP_FEATURES = "annotsToNlpFeatures";
079
080 public final static String NLP_FEATURES_TO_FVS = "nlpFeaturesToFVs";
081
082 public final static String READING_LEARNING_INFO = "readingLearningInfo";
083
084 public final static String MODEL_APPLICATION = "modelApplication";
085
086 public final static String WRITING_NGRAM_MODEL = "writingNgramModel";
087
088 public final static String TERM_DOC_STATS = "termDocStats";
089
090 public final static String FILTERING = "filtering";
091
092 public final static String MODEL_TRAINING = "modelTraining";
093
094 public final static String EVALUATION = "evaluation";
095
096 public final static String NLP_LABELS_TO_DATA_LABELS = "nlpLabelsToDataLabels";
097
098 public final static String READING_NLP_FEATURES = "readingNlpFeatures";
099
100 public final static String READING_FVS = "readingFVs";
101
102 public final static String WEKA_MODEL_TRAINING = "wekaModelTraining";
103
104 public final static String PAUM_MODEL_TRAINING = "paumModelTraining";
105
106 public final static String READING_CHUNK_LEARNING_DATA = "readingChunkLearningData";
107
108 public final static String WEKA_MODEL_APPLICATION = "wekaModelApplication";
109
110 public final static String PAUM_MODEL_APPLICATION = "paumModelApplication";
111
112 public final static String POST_PROCESSING = "postProcessing";
113
114 /**
115 * Static shared logger used for logging.
116 */
117 public static Logger logger = Logger.getLogger(Benchmark.class);
118
119 /**
120 * This returns the current system time.
121 *
122 * @return
123 */
124 public static long startPoint() {
125 return System.currentTimeMillis();
126 }
127
128 /**
129 * Like {@link #startPoint()} but also logs a message with the
130 * starting time if benchmarking is enabled. This is intended to be
131 * used in conjuntion with the three-argument version of checkPoint.
132 *
133 * @param benchmarkID the identifier of the process that is just
134 * starting.
135 * @return the current time, as logged.
136 */
137 public static long startPoint(String benchmarkID) {
138 long time = startPoint();
139 if(benchmarkingEnabled) {
140 logger.info(time + " START " + benchmarkID);
141 }
142 return time;
143 }
144
145 /**
146 * This method is responsible for making entries into the log.
147 *
148 * @param startTime - when did the actual process started. This value
149 * should be the value obtained by Benchmark.startPoint()
150 * method invoked at the begining of the process.
151 * @param benchmarkID - a unique ID of the resource that should be
152 * logged with this message.
153 * @param objectInvokingThisCheckPoint - The benchmarkable object that
154 * invokes this method.
155 * @param features - any features (key-value pairs) that should be
156 * reported in the log message. toString() method will be
157 * invoked on the objects.
158 */
159 public static void checkPoint(long startTime, String benchmarkID,
160 Object objectInvokingThisCheckPoint, Map benchmarkingFeatures) {
161
162 // check if logging is disabled
163 if(!benchmarkingEnabled) return;
164
165 // we calculate processEndTime here as we don't want to consider
166 // the time to convert featureMapToString
167 long processingTime = System.currentTimeMillis() - startTime;
168
169 logCheckPoint(String.valueOf(processingTime), benchmarkID,
170 objectInvokingThisCheckPoint, benchmarkingFeatures);
171 }
172
173 /**
174 * This method is responsible for making entries into the log.
175 *
176 * @param totalTime - Total time consumed by the process
177 * @param benchmarkID - a unique ID of the resource that should be
178 * logged with this message.
179 * @param objectInvokingThisCheckPoint - The benchmarkable object that
180 * invokes this method.
181 * @param features - any features (key-value pairs) that should be
182 * reported in the log message. toString() method will be
183 * invoked on the objects.
184 */
185 public static void checkPointWithDuration(long totalTime, String benchmarkID,
186 Object objectInvokingThisCheckPoint, Map benchmarkingFeatures) {
187
188 // check if logging is disabled
189 if(!benchmarkingEnabled) return;
190
191 logCheckPoint(String.valueOf(totalTime), benchmarkID,
192 objectInvokingThisCheckPoint, benchmarkingFeatures);
193 }
194
195 /**
196 * Logs the end of a process. There must previously have been a call
197 * to {@link #startPoint(String)} with the same benchmark ID.
198 *
199 * @see #checkPoint(long, String, Object, Map)
200 */
201 public static void checkPoint(String benchmarkID,
202 Object objectInvokingThisCheckPoint, Map benchmarkingFeatures) {
203 if(!benchmarkingEnabled) return;
204 logCheckPoint("END", benchmarkID, objectInvokingThisCheckPoint,
205 benchmarkingFeatures);
206 }
207
208 /**
209 * Private method to create a line in the benchmark log.
210 *
211 * @param processingTimeOrFlag either the duration of the task in ms
212 * or the string "END" if no start time was provided.
213 */
214 private static void logCheckPoint(String processingTimeOrFlag,
215 String benchmarkID, Object objectInvokingThisCheckPoint,
216 Map benchmarkingFeatures) {
217 // finally build the string to be logged
218 StringBuilder messageToLog = new StringBuilder();
219 messageToLog.append("" + System.currentTimeMillis() + " ");
220 messageToLog.append(processingTimeOrFlag + " " + benchmarkID + " "
221 + objectInvokingThisCheckPoint.getClass().getName() + " ");
222
223 if(benchmarkingFeatures == null) {
224 messageToLog.append("{}");
225 }
226 else {
227 messageToLog.append(benchmarkingFeatures.toString().replaceAll("\n", ""))
228 .append("\n");
229 }
230 logger.info(messageToLog.toString());
231 }
232
233 /**
234 * Helper method to generate the benchmark ID.
235 *
236 * @param resourceName
237 * @param parentBenchmarkID
238 * @return
239 */
240 public static String createBenchmarkId(String resourceName,
241 String parentBenchmarkID) {
242 if(parentBenchmarkID != null) {
243 if(resourceName != null) {
244 return (parentBenchmarkID + "." + resourceName.replaceAll("\\.","_")).replaceAll("[ ]+", "_");
245 }
246 else {
247 return (parentBenchmarkID + ".null").replaceAll("[ ]+", "_");
248 }
249 }
250 else {
251 if(resourceName != null) {
252 return resourceName.replaceAll("[ .]+", "_");
253 }
254 else {
255 return "null";
256 }
257 }
258
259 }
260
261 /**
262 * Returns if the logging is enabled.
263 *
264 * @return
265 */
266 public static boolean isBenchmarkingEnabled() {
267 return benchmarkingEnabled;
268 }
269
270 /**
271 * Enables or disables the logging.
272 *
273 * @param benchmarkingEnabled
274 */
275 public static void setBenchmarkingEnabled(boolean benchmarkingEnabled) {
276 Benchmark.benchmarkingEnabled = benchmarkingEnabled;
277 }
278
279 /**
280 * Executes the given {@link Executable}, logging its runtime under
281 * the given benchmark ID (which is propagated to the Executable if it
282 * is itself {@link Benchmarkable}).
283 *
284 * @param executable the object to execute
285 * @param benchmarkID the benchmark ID, which must not contain spaces
286 * as it is already used as a separator in the log, you can use
287 * {@link #createBenchmarkId(String, String)} for it.
288 * @param objectInvokingThisCheckPoint the object invoking this method
289 * (typically the caller would pass <code>this</code> here)
290 * @param benchmarkingFeatures features to include in the check point
291 * log
292 * @throws ExecutionException any exceptions thrown by the underlying
293 * Executable are propagated.
294 */
295 public static void executeWithBenchmarking(Executable executable,
296 String benchmarkID, Object objectInvokingThisCheckPoint,
297 Map benchmarkingFeatures) throws ExecutionException {
298 if(!benchmarkingEnabled) {
299 executable.execute();
300 }
301 else {
302 long startTime = startPoint();
303 String savedBenchmarkID = null;
304 try {
305 if(executable instanceof Benchmarkable) {
306 savedBenchmarkID = ((Benchmarkable)executable).getBenchmarkId();
307 ((Benchmarkable)executable).setBenchmarkId(benchmarkID);
308 }
309
310 executable.execute();
311 }
312 catch(Exception e) {
313 Map tempFeatures = new HashMap();
314 if(benchmarkingFeatures != null) {
315 tempFeatures.putAll(benchmarkingFeatures);
316 }
317 tempFeatures.put("exceptionThrown", e);
318 checkPoint(startTime, benchmarkID, objectInvokingThisCheckPoint,
319 tempFeatures);
320 if(e instanceof ExecutionException) {
321 throw (ExecutionException)e;
322 }
323 else {
324 throw (RuntimeException)e;
325 }
326 }
327 finally {
328 if(savedBenchmarkID != null) {
329 ((Benchmarkable)executable).setBenchmarkId(savedBenchmarkID);
330 }
331 }
332
333 // succeeded, so log checkpoint with the original features
334 checkPoint(startTime, benchmarkID, objectInvokingThisCheckPoint,
335 benchmarkingFeatures);
336 }
337 }
338 }
|