Skip to content

Commit

Permalink
Cache preprocessed JMeter Reports (JENKINS-9031)
Browse files Browse the repository at this point in the history
Instead of parsing all available JTL results upon each request,
we now save the parsed report as a serialized Java object for later
reuse. The file will be next to the JTL file with a '.serialized'
suffix. Additionally the report also gets added to a in-memory cache
with a maximum capacity of 100 reports. This considerably speeds up the
performance trend display.

Signed-off-by: Michel Marti <mma@objectxp.com>
  • Loading branch information
matoxp authored and manolo committed Jan 10, 2014
1 parent 8fd9fe4 commit be7401b
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 1 deletion.
2 changes: 2 additions & 0 deletions src/main/java/hudson/plugins/performance/HttpSample.java
Expand Up @@ -10,6 +10,8 @@
*/
public class HttpSample implements Serializable, Comparable<HttpSample> {

private static final long serialVersionUID = -1980997520755400556L;

private long duration;

private boolean successful;
Expand Down
50 changes: 49 additions & 1 deletion src/main/java/hudson/plugins/performance/JMeterParser.java
Expand Up @@ -10,13 +10,22 @@
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.logging.Logger;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
Expand All @@ -29,6 +38,9 @@
*/
public class JMeterParser extends PerformanceReportParser {

private static final Logger LOGGER = Logger.getLogger(JMeterParser.class.getName());
private static final Cache<String, PerformanceReport> cache = CacheBuilder.newBuilder().maximumSize(100).build();

@Extension
public static class DescriptorImpl extends PerformanceReportParserDescriptor {
@Override
Expand Down Expand Up @@ -59,10 +71,31 @@ public Collection<PerformanceReport> parse(AbstractBuild<?, ?> build,

for (File f : reports) {
try {
String fser = f.getPath() + ".serialized";
ObjectInputStream in = null;
synchronized (JMeterParser.class) {
try {
PerformanceReport r = cache.getIfPresent(fser);
if (r == null) {
in = new ObjectInputStream(new FileInputStream(fser));
r = (PerformanceReport) in.readObject();
}
result.add(r);
continue;
} catch (FileNotFoundException fne) {
// That's OK
} catch (Exception unknown) {
LOGGER.warning("Deserialization failed. " + unknown);
} finally {
if (in != null) {
in.close();
}
}
}
SAXParser parser = factory.newSAXParser();
final PerformanceReport r = new PerformanceReport();
r.setReportFileName(f.getName());
logger.println("Performance: Parsing JMeter report file " + f.getName());
logger.println("Performance: Parsing JMeter report file " + f.getPath());
parser.parse(f, new DefaultHandler() {
HttpSample currentSample;
int counter = 0;
Expand Down Expand Up @@ -123,6 +156,21 @@ public void endElement(String uri, String localName, String qName) {
}
});
result.add(r);
ObjectOutputStream out = null;
synchronized(JMeterParser.class) {
try {
cache.put(fser, r);
out = new ObjectOutputStream(new FileOutputStream(fser));
out.writeObject(r);
} catch (Exception unknown) {
LOGGER.warning("Serialization failed. " + unknown);
} finally {
if (out != null) {
out.close();
}
}
}

} catch (ParserConfigurationException e) {
throw new IOException2("Failed to create parser ", e);
} catch (SAXException e) {
Expand Down
Expand Up @@ -25,6 +25,8 @@
public class PerformanceReport extends AbstractReport implements Serializable,
Comparable<PerformanceReport>{

private static final long serialVersionUID = -1422875677867003355L;

private transient PerformanceBuildAction buildAction;

private HttpSample httpSample;
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/hudson/plugins/performance/UriReport.java
Expand Up @@ -27,6 +27,8 @@
public class UriReport extends AbstractReport implements Serializable, ModelObject,
Comparable<UriReport> {

private static final long serialVersionUID = 6377220939528230222L;

public final static String END_PERFORMANCE_PARAMETER = ".endperformanceparameter";

/**
Expand Down

3 comments on commit be7401b

@nik0kin
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you forgot to update pom.xml

@xxxxzm
Copy link

@xxxxzm xxxxzm commented on be7401b Jan 26, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great job, is there any plan to save jmeter result into db?

@manolo
Copy link
Member

@manolo manolo commented on be7401b Jan 27, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

released 1.10

Please sign in to comment.