/*
* Copyright (C) 2008 Digital Sundhed (SDSD)
*
* All source code and information supplied as part of chronos
* is copyright to its contributers.
*
* The source code has been released under a dual license - meaning you can
* use either licensed version of the library with your code.
*
* It is released under the Common Public License 1.0, a copy of which can
* be found at the link below.
* http://www.opensource.org/licenses/cpl.php
*
* It is released under the LGPL (GNU Lesser General Public License), either
* version 2.1 of the License, or (at your option) any later version. A copy
* of which can be found at the link below.
* http://www.gnu.org/copyleft/lesser.html
*/
package org.codehaus.mojo.chronos.gc;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* This class is responsible for parsing garbage collection logs.
*
* @author ksr@lakeside.dk
*/
public final class GCLogParser {
/**
* Parses the garbage collection log.
*
* @param gcFilePath
* The path to the garbage collection log
* @return {@link GCSamples}
* @throws IOException
* if the logfile could not be parsed
*/
public GCSamples parseGCLog(String gcFilePath) throws IOException {
File gcFile = new File(gcFilePath);
return parseGCLog(gcFile);
}
/**
* Parses the garbage collection log.
*
* @param gcFile
* The garbage collection logfile
* @return {@link GCSamples}
* @throws IOException
* if the logfile could not be parsed
*/
public GCSamples parseGCLog(File gcFile) throws IOException {
FileReader fileReader = new FileReader(gcFile);
GCSamples samples = new GCSamples();
LineNumberReader reader = new LineNumberReader(fileReader);
String line;
StringBuffer concatLines = new StringBuffer();
try {
while ((line = reader.readLine()) != null) {
concatLines.append(line);
if(line.indexOf("]") > -1) { // end of the logentry
samples.add(parseGCLogItem(concatLines.toString()));
concatLines.setLength(0);
}
}
return samples;
} finally {
reader.close();
}
}
/**
* Runs a regular expression on source.<br />
* Puts the info in a {@link GCSample} and adds that to samples The log entries might be JDK1.4 or JDK5
*
* @param source
* @param samples
* @return {@link GCSamples}
*/
private GCSample parseGCLogItem(String source) {
String timeinstant = null, heapbefore = null, heapafter = null, totalheap = null, processingtime = null;
Pattern pattern = Pattern.compile("[0-9]*\\.[0-9]*:|[0-9]*K|[0-9]*\\.[0-9]*");
Matcher matcher = pattern.matcher(source);
int index = 0;
while (matcher.find()) {
if(matcher.group().length() > 0) {
switch (index) {
case 0:
timeinstant = matcher.group();
timeinstant = timeinstant.substring(0, timeinstant.length() - 1);
break;
case 1:
heapbefore = matcher.group();
heapbefore = heapbefore.substring(0, heapbefore.length() - 1);
break;
case 2:
heapafter = matcher.group();
heapafter = heapafter.substring(0, heapafter.length() - 1);
break;
case 3:
totalheap = matcher.group();
totalheap = totalheap.substring(0, totalheap.length() - 1);
break;
case 4:
processingtime = matcher.group();
processingtime = matcher.group();
break;
default:
throw new IllegalArgumentException();
}
index++;
}
}
return new GCSample(Double.parseDouble(timeinstant), Integer.parseInt(heapbefore), Integer.parseInt(heapafter),
Integer.parseInt(totalheap), Double.parseDouble(processingtime));
}
}