package com.blazemeter.jmeter; import org.apache.jmeter.reporters.ResultCollector; import org.apache.jmeter.samplers.SampleEvent; import org.apache.jorphan.logging.LoggingManager; import org.apache.log.Logger; import java.lang.reflect.Field; public class RotatingResultCollector extends ResultCollector { private static final Logger LOGGER = LoggingManager.getLoggerForClass(); public static final String MAX_SAMPLES_COUNT = "maxSamplesCount"; private int maxSamplesCount; private int currentSamplesCount; protected String filename; private boolean isChanging; @Override public void sampleOccurred(SampleEvent event) { isChanging = true; try { if (currentSamplesCount >= maxSamplesCount) { testEnded(); nullifyPrintWriter(); // HACK for previous versions filename = getRotatedFilename(filename); LOGGER.info("Creating new log chunk: " + filename); currentSamplesCount = 0; testStarted(); } super.sampleOccurred(event); if (this.isSampleWanted(event.getResult().isSuccessful())) { currentSamplesCount++; } } finally { isChanging = false; } } @Override public String getFilename() { if (!isChanging) { filename = super.getFilename(); } return filename; } @Override public void testStarted(String host) { super.testStarted(host); this.maxSamplesCount = getMaxSamplesCountAsInt(); } protected int getMaxSamplesCountAsInt() { try { return Integer.parseInt(getMaxSamplesCount()); } catch (NumberFormatException e) { LOGGER.warn("Incorrect value of max samples count: " + getMaxSamplesCount()); return Integer.MAX_VALUE; } } public String getMaxSamplesCount() { return getPropertyAsString(MAX_SAMPLES_COUNT, ""); } public void setMaxSamplesCount(String maxSamplesCount) { setProperty(MAX_SAMPLES_COUNT, maxSamplesCount); } protected static String getRotatedFilename(String origFile) { String[] parts = origFile.split("[.]"); final int length = parts.length; if (length > 2) { try { parts[length - 2] = String.valueOf(Integer.parseInt(parts[length - 2]) + 1); } catch (NumberFormatException ex) { LOGGER.debug("Can't cast to integer " + parts[length - 2], ex); parts[length - 1] = "1." + parts[length - 1]; } } else { parts[length - 1] = "1." + parts[length - 1]; } final StringBuilder builder = new StringBuilder(); for (int i = 0; i < length; i++) { builder.append(parts[i]); if (i < length - 1) { builder.append('.'); } } return builder.toString(); } private void nullifyPrintWriter() { try { Class<?> cls = getClass().getSuperclass(); Field outField = cls.getDeclaredField("out"); outField.setAccessible(true); // nullify out stream, that must nullify in org.apache.jmeter.reporters.ResultCollector#finalizeFileOutput() outField.set(this, null); } catch (NoSuchFieldException | IllegalAccessException ex) { LOGGER.error("Cannot nullify out stream", ex); } } }