You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jmeter-dev@jakarta.apache.org by wo...@apache.org on 2005/01/07 05:08:43 UTC

cvs commit: jakarta-jmeter/src/core/org/apache/jmeter/reporters StatsCollector.java

woolfel     2005/01/06 20:08:43

  Added:       src/core/org/apache/jmeter/reporters StatsCollector.java
  Log:
  adding a new collector for visualizer data like aggregate and monitor
  listener.
  
  peter
  
  Revision  Changes    Path
  1.1                  jakarta-jmeter/src/core/org/apache/jmeter/reporters/StatsCollector.java
  
  Index: StatsCollector.java
  ===================================================================
  /*
   * Copyright 2001-2004 The Apache Software Foundation.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *   http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   * 
   */
  
  package org.apache.jmeter.reporters;
  
  import java.io.BufferedOutputStream;
  import java.io.File;
  import java.io.FileNotFoundException;
  import java.io.FileOutputStream;
  import java.io.IOException;
  import java.io.OutputStreamWriter;
  import java.io.PrintWriter;
  import java.io.RandomAccessFile;
  import java.io.Serializable;
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.Map;
  import java.util.Set;
  
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
  import org.apache.avalon.framework.configuration.DefaultConfigurationSerializer;
  
  import org.apache.jmeter.engine.event.LoopIterationEvent;
  import org.apache.jmeter.engine.util.NoThreadClone;
  import org.apache.jmeter.samplers.Clearable;
  import org.apache.jmeter.samplers.Remoteable;
  import org.apache.jmeter.samplers.SampleSaveConfiguration;
  import org.apache.jmeter.save.OldSaveService;
  import org.apache.jmeter.save.SaveService;
  import org.apache.jmeter.save.ListenerResultWrapper;
  import org.apache.jmeter.testelement.AbstractTestElement;
  import org.apache.jmeter.testelement.TestElement;
  import org.apache.jmeter.testelement.TestListener;
  import org.apache.jmeter.testelement.property.BooleanProperty;
  import org.apache.jmeter.testelement.property.ObjectProperty;
  import org.apache.jorphan.logging.LoggingManager;
  import org.apache.log.Logger;
  
  import org.xml.sax.SAXException;
  
  /**
   * @author pete
   *
   * StatsCollector is used to save the calculated statistics generated
   * by visualizers. It makes sense to have a separete collector for
   * stats, since the runtime behavior is different than raw SampleResults.
   */
  public class StatsCollector extends AbstractTestElement implements Clearable,
      Serializable, TestListener, Remoteable,
      NoThreadClone
  {
  
  	static final long serialVersionUID = 1;
  	private static final String TESTRESULTS_START = "<calculatedResults>";
  	private static final String TESTRESULTS_END = "</calculatedResults>";
  	private static final String XML_HEADER = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
  	private static final int MIN_XML_FILE_LEN = XML_HEADER.length()
  		  + TESTRESULTS_START.length() + TESTRESULTS_END.length();
  	transient private static Logger log = LoggingManager.getLoggerForClass();
  	public final static String FILENAME = "filename";
  	public final static String SAVE_CONFIG = "saveConfig";
  	private static boolean functionalMode = false;
  	public static final String ERROR_LOGGING = "ResultCollector.error_logging";
  	transient private DefaultConfigurationSerializer serializer;
  	transient private volatile PrintWriter out;
  	private boolean inTest = false;
  	private static Map files = new HashMap();
  	private Set hosts = new HashSet();
  
      /**
       * 
       */
      public StatsCollector() {
          super();
  		serializer = new DefaultConfigurationSerializer();
  		setErrorLogging(false);
  		setProperty(new ObjectProperty(SAVE_CONFIG,new SampleSaveConfiguration()));
      }
  
  	public void testStarted(){
  		testStarted("local");
  	}
  
  	public void testEnded(){
  		testEnded("local");
  	}
  
  	public void testStarted(String host){
  		hosts.add(host);
  		try
  		{
  		   initializeFileOutput();
  		}
  		catch (Exception e)
  		{
  		   log.error("", e);
  		}
  		inTest = true;
  	}
  
  	public void testEnded(String host){
  		hosts.remove(host);
  		if (hosts.size() == 0)
  		{
  		   finalizeFileOutput();
  		   inTest = false;
  		}
  	}
      
  	/**
  	 * Each time through a Thread Group's test script, an iteration event is
  	 * fired.
  	 * @param event
  	 */
  	public void testIterationStart(LoopIterationEvent event){
  	}
  
  	//------- file related methods --------//
  	private void setFilenameProperty(String f)
  	{
  	   setProperty(FILENAME, f);
  	}
  
  	public String getFilename()
  	{
  	   return getPropertyAsString(FILENAME);
  	}
  
  	public void setFilename(String f)
  	{
  	   if (inTest) { return; }
  	   setFilenameProperty(f);
  	}
  
  	private void initializeFileOutput() throws IOException,
  		  ConfigurationException, SAXException
  	{
  
  	   String filename = getFilename();
  	   if (out == null && filename != null)
  	   {
  		  if (out == null)
  		  {
  			 try
  			 {
  				out = getFileWriter(filename,getSaveConfig());
  			 }
  			 catch (FileNotFoundException e)
  			 {
  				out = null;
  			 }
  		  }
  	   }
  	}
  
  	private synchronized void finalizeFileOutput()
  	{
  	   if (out != null)
  	   {
  		  writeFileEnd(out,getSaveConfig());
  		  out.close();
  		  files.remove(getFilename());
  		  out = null;
  	   }
  	}
  
  	private static synchronized PrintWriter getFileWriter(String filename,SampleSaveConfiguration saveConfig)
  		  throws IOException
  	{
  	   if (filename == null || filename.length() == 0) { return null; }
  	   PrintWriter writer = (PrintWriter) files.get(filename);
  	   boolean trimmed = true;
  
  	   if (writer == null)
  	   {
  		  if (saveConfig.saveAsXml())
  		  {
  			 trimmed = trimLastLine(filename);
  		  }
  		  // Find the name of the directory containing the file
  		  // and create it - if there is one
  		  File pdir = new File(filename).getParentFile();
  		  if (pdir != null) pdir.mkdirs();
  		  writer = new PrintWriter(
  				new OutputStreamWriter(new BufferedOutputStream(
  					  new FileOutputStream(filename, trimmed)), "UTF-8"), true);
  		  files.put(filename, writer);
  	   }
  	   if (!trimmed)
  	   {
  		  writeFileStart(writer,saveConfig);
  	   }
  	   return writer;
  	}
  
  	// returns false if the file did not contain the terminator
  	private static boolean trimLastLine(String filename)
  	{
  	   RandomAccessFile raf = null;
  	   try
  	   {
  		  raf = new RandomAccessFile(filename, "rw");
  		  long len = raf.length();
  		  if (len < MIN_XML_FILE_LEN) { return false; }
  		  raf.seek(len - TESTRESULTS_END.length() - 10);//TODO: may not work on
  														// all OSes?
  		  String line;
  		  long pos = raf.getFilePointer();
  		  int end = 0;
  		  while ((line = raf.readLine()) != null)// reads to end of line OR file
  		  {
  			 end = line.indexOf(TESTRESULTS_END);
  			 if (end >= 0) // found the string
  			 {
  				break;
  			 }
  			 pos = raf.getFilePointer();
  		  }
  		  if (line == null)
  		  {
  			 log.warn("Unexpected EOF trying to find XML end marker in "
  				   + filename);
  			 raf.close();
  			 return false;
  		  }
  		  raf.setLength(pos + end);// Truncate the file
  		  raf.close();
  	   }
  	   catch (FileNotFoundException e)
  	   {
  		  return false;
  	   }
  	   catch (IOException e)
  	   {
  		  log.warn("Error trying to find XML terminator " + e.toString());
  		  try
  		  {
  			 if (raf != null) raf.close();
  		  }
  		  catch (IOException e1)
  		  {
  		  }
  		  return false;
  	   }
  	   return true;
  	}
  
  	private static void writeFileStart(PrintWriter writer,SampleSaveConfiguration saveConfig)
  	{
  	   if (saveConfig.saveAsXml())
  	   {
  		  writer.println(XML_HEADER);
  		  writer.println(TESTRESULTS_START);
  	   }
  	   else if (saveConfig.saveFieldNames())
  		  {
  			 writer.println(OldSaveService.printableFieldNamesToString());
  		  }
  	}
  
  	private static void writeFileEnd(PrintWriter pw,SampleSaveConfiguration saveConfig)
  	{
  	   if (saveConfig.saveAsXml())
  	   {
  		  pw.print("\n");
  		  pw.print(TESTRESULTS_END);
  	   }
  	}
  
  	private void recordResult(TestElement e) throws Exception
  	{
  	   if (out != null)
  	   {
            SaveService.saveElement(e, out);
  	   }
  	}
  
  	public void loadExistingFile() throws SAXException, IOException,
  		  ConfigurationException
  	{
  	}
  
  	private void readSamples(ListenerResultWrapper testResults) throws Exception
  	{
  	}
  
  	//------- error related methods --------//
  	public boolean isErrorLogging()
  	{
  	   return getPropertyAsBoolean(ERROR_LOGGING);
  	}
  
  	public void setErrorLogging(boolean errorLogging)
  	{
  	   setProperty(new BooleanProperty(ERROR_LOGGING, errorLogging));
  	}
  
      //------- config related methods -------//
  	/**
  	 * @return Returns the saveConfig.
  	 */
  	public SampleSaveConfiguration getSaveConfig()
  	{
  	   return (SampleSaveConfiguration)getProperty(SAVE_CONFIG).getObjectValue();
  	}
  	/**
  	 * @param saveConfig The saveConfig to set.
  	 */
  	public void setSaveConfig(SampleSaveConfiguration saveConfig)
  	{
  	   getProperty(SAVE_CONFIG).setObjectValue(saveConfig);
  	}
  
  	private Configuration getConfiguration(String filename) throws SAXException,
  		  IOException, ConfigurationException
  	{
  	   DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
  
  	   return builder.buildFromFile(filename);
  	}
  
  	public void sampleOccurred(TestElement e){
  		
  	}
  
  	//------- functional mode related methods -------//
  	public static void enableFunctionalMode(boolean mode)
  	{
  	   functionalMode = mode;
  	}
  
  	public boolean getFunctionalMode()
  	{
  	   return functionalMode || isErrorLogging();
  	}
  
  }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: jmeter-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: jmeter-dev-help@jakarta.apache.org