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 2004/03/13 06:58:31 UTC

cvs commit: jakarta-jmeter/src/monitor/components/org/apache/jmeter/visualizers MonitorAccumModel.java ServerPanel.java MonitorStats.java MonitorModel.java MonitorHealthPanel.java MonitorTabPane.java MonitorPerformancePanel.java MonitorHealthVisualizer.java MonitorGuiListener.java MonitorListener.java MonitorGraph.java

woolfel     2004/03/12 21:58:31

  Added:       src/monitor/components/org/apache/jmeter/monitor/util
                        Stats.java
               src/monitor/components/org/apache/jmeter/visualizers
                        MonitorAccumModel.java ServerPanel.java
                        MonitorStats.java MonitorModel.java
                        MonitorHealthPanel.java MonitorTabPane.java
                        MonitorPerformancePanel.java
                        MonitorHealthVisualizer.java
                        MonitorGuiListener.java MonitorListener.java
                        MonitorGraph.java
  Log:
  Adding the source to CVS, but I'm going to wait to add the build
  task to compile and package the monitor. Once I get the custom
  parser ready I will add the ANT task.
  
  peter lin
  
  Revision  Changes    Path
  1.1                  jakarta-jmeter/src/monitor/components/org/apache/jmeter/monitor/util/Stats.java
  
  Index: Stats.java
  ===================================================================
  // $Header:
  /*
   * 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.monitor.util;
  
  import javax.xml.bind.*;
  import org.apache.jorphan.tomcat.manager.*;
  
  /**
   * 
   * Description:<p>
   * Stats is responsible for calculating the load and
   * health of a given server. It uses tomcat's status
   * servlet results. A schema was generated for the
   * XML output and JAXB was used to generate classes.
   * <p>
   * The equations are:<p>
   * memory weight = (int)(33 * (used/max))<br>
   * thread weight = (int)(67 * (current/max))<p>
   * The load factors are stored in the properties
   * files. Simply change the values in the properties
   * to change how load is calculated. The defaults
   * values are memory (33) and threads (67). The sum
   * of the factors must equal 100.
   */
  public class Stats
  {
  
  	public static final int DEAD = 0;
  	public static final int ACTIVE = 2;
  	public static final int WARNING = 1;
  	public static final int HEALTHY = 3;
  
  	public static int DEFAULT_MEMORY_FACTOR = 50;
  	public static int DEFAULT_THREAD_FACTOR = 50;
  	public static double HEALTHY_PER = 0.00;
  	public static double ACTIVE_PER = 0.25;
  	public static double WARNING_PER = 0.67;
  
  	/**
  	 * The method is responsible for taking a status
  	 * object and calculating an int value from 1 to
  	 * 100. We use a combination of free memory and
  	 * free threads. Since memory is a bigger risk,
  	 * it counts for 2/3.<p>
  	 * @param stat
  	 * @return
  	 */
  	public static int calculateLoad(Status stat){
  		if (stat != null){
  			// equation for calculating the weight
  			// w = (int)(33 * (used/max))
  			long totMem = stat.getJvm().getMemory().getTotal();
  			long usedMem = stat.getJvm().getMemory().getFree();
  			double memdiv = (double)usedMem/(double)totMem;
  			double memWeight = DEFAULT_MEMORY_FACTOR * memdiv;
  
  			Connector cntr = (Connector)stat.getConnector().get(0);
  			int maxThread = cntr.getThreadInfo().getMaxThreads();
  			int curThread = cntr.getThreadInfo().getCurrentThreadsBusy();
  			double thdiv = (double)curThread/(double)maxThread;
  			double threadWeight = DEFAULT_THREAD_FACTOR * thdiv;
  			return (int)(memWeight + threadWeight);
  		} else {
  			return 0;
  		}
  	}
  	
  	/**
  	 * Method should calculate if the server is:
  	 * dead, active, warning or healthy. We do
  	 * this by looking at the current busy threads.
  	 * <ol>
  	 * <li> free &gt; spare is healthy
  	 * <li> free &lt; spare is active
  	 * <li> busy threads &gt; 75% is warning
  	 * <li> none of the above is dead
  	 * </ol>
  	 * @param stat
  	 * @return
  	 */
  	public static int calculateStatus(Status stat){
  		if (stat != null){
  			Connector cntr = (Connector)stat.getConnector().get(0);
  			int max = cntr.getThreadInfo().getMaxThreads();
  			int current = cntr.getThreadInfo().getCurrentThreadsBusy();
  			int spare = cntr.getThreadInfo().getMaxSpareThreads();
  			double per = (double)current/(double)max;
  			if (per > WARNING_PER){
  				return WARNING;
  			} else if (per >= ACTIVE_PER && per <= WARNING_PER){
  				return ACTIVE;
  			} else if (per < ACTIVE_PER && per > HEALTHY_PER){
  				return HEALTHY;
  			} else {
  				return DEAD;
  			}
  		} else {
  			return DEAD;
  		}
  	}
  
  	/**
  	 * Method will calculate the memory load:
  	 * used / max = load. The load value is an
  	 * integer between 1 and 100. It is the
  	 * percent memory used.
  	 * @param stat
  	 * @return
  	 */	
  	public static int calculateMemoryLoad(Status stat){
  		double load = 0;
  		if (stat != null){
  			double total = (double)stat.getJvm().getMemory().getTotal();
  			double used = (double)stat.getJvm().getMemory().getFree();
  			load = (used/total);
  		}
  		return (int)(load * 100);
  	}
  
  	/**
  	 * Method will calculate the thread load:
  	 * busy / max = load. The value is an
  	 * integer between 1 and 100. It is the
  	 * percent busy.
  	 * @param stat
  	 * @return
  	 */	
  	public static int calculateThreadLoad(Status stat){
  		int load = 0;
  		if (stat != null){
  			Connector cntr = (Connector)stat.getConnector().get(0);
  			double max = (double)cntr.getThreadInfo().getMaxThreads();
  			double current =
  				(double)cntr.getThreadInfo().getCurrentThreadsBusy();
  			load = (int)((current/max) * 100);
  		}
  		return load;
  	}
  	
  	/**
  	 * Simple unit test to make sure it works correctly.
  	 * Will write a JUnit test later for this.
  	 * @param args
  	 */
      public static void main(String[] args)
      {
      	try {
  			JAXBContext jxbc = new ObjectFactory();
  				// ObjectFactory.newInstance("org.apache.jorphan.tomcat.manager");
  			Unmarshaller mar = jxbc.createUnmarshaller();
  			Object ld = mar.unmarshal(new java.io.File("status3.xml"));
  			System.out.println("successfully unmarshalled sample status");
  			if (ld instanceof Status){
  				System.out.println("status is " + calculateStatus((Status)ld));
  				System.out.println("load is " + calculateLoad((Status)ld));
  				System.out.println("mem load is " + calculateMemoryLoad((Status)ld));
  				System.out.println("th load is " + calculateThreadLoad((Status)ld));
  			}
      	} catch (JAXBException e){
      		e.printStackTrace();
      	}
      }
  }
  
  
  
  1.1                  jakarta-jmeter/src/monitor/components/org/apache/jmeter/visualizers/MonitorAccumModel.java
  
  Index: MonitorAccumModel.java
  ===================================================================
  // $Header:
  /*
   * 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.visualizers;
  
  import java.io.ByteArrayInputStream;
  import java.io.Serializable;
  import java.net.URL;
  import java.util.ArrayList;
  import java.util.Collections;
  import java.util.HashMap;
  import java.util.List;
  import java.util.LinkedList;
  
  import javax.xml.bind.*;
  import javax.xml.transform.stream.StreamSource;
  
  import org.apache.jmeter.samplers.Clearable;
  import org.apache.jmeter.samplers.SampleResult;
  import org.apache.jorphan.tomcat.manager.*;
  import org.apache.jmeter.monitor.util.Stats;
  import org.apache.jmeter.protocol.http.sampler.HTTPSampleResult;
  
  public class MonitorAccumModel implements Clearable, Serializable
  {
  
  	private HashMap MAP;
  	private MonitorModel CURRENT;
  	private List listeners;
  	/**
  	 * By default, we set the default to 800
  	 */
  	private int DEFAULT_BUFFER = 800;
  	
      /**
       * 
       */
      public MonitorAccumModel()
      {
      	MAP = new HashMap();
  		listeners = new LinkedList();
      }
      
      public int getBufferSize(){
      	return DEFAULT_BUFFER;
      }
      
      public void setBufferSize(int buffer){
      	DEFAULT_BUFFER = buffer;
      }
      
      /**
       * Method will look up the server in the map. The
       * MonitorModel will be added to an existing list,
       * or a new one will be created.
       * @param model
       */
      public void addSample(MonitorModel model){
  		this.CURRENT = model;
      	if (MAP.containsKey(model.getURL())){
      		List newlist = updateArray(model,(List)MAP.get(model.getURL()));
      		MAP.put(model.getURL(),newlist);
      	} else {
  			List samples = Collections.synchronizedList(new LinkedList());
  			samples.add(model);
      		MAP.put(model.getURL(),samples);
      	}
      }
  
  	/**
  	 * We want to keep only 240 entries for each server,
  	 * so we handle the object array ourselves.
  	 * @param model
  	 */
  	private List updateArray(MonitorModel model, List list){
  		if (list.size() < DEFAULT_BUFFER){
  			list.add(model);
  		} else {
  			list.add(model);
  			list.remove(0);
  		}
  		return list;
  	}
  	
  	/**
  	 * Get all MonitorModels matching the URL.
  	 * @param url
  	 * @return
  	 */
  	public List getAllSamples(String url){
  		if (!MAP.containsKey(url)){
  			return Collections.synchronizedList(new LinkedList());
  		} else {
  			return (List)MAP.get(url);
  		}
  	}
  	
  	/**
  	 * Get the MonitorModel matching the url.
  	 * @param url
  	 * @return
  	 */
  	public MonitorModel getSample(String url){
  		if (MAP.containsKey(url)){
  			ArrayList list = (ArrayList)MAP.get(url);
  			return (MonitorModel)list.get(0);
  		} else {
  			return null;
  		}
  	}
  	
  	/**
  	 * Method will try to parse the response data. If the
  	 * request was a monitor request, but the response was
  	 * incomplete, bad or the server refused the connection,
  	 * we will set the server's health to "dead". If the
  	 * request was not a monitor sample, the method will
  	 * ignore it.
  	 * @param sample
  	 */
  	public void addSample(SampleResult sample){
  		URL surl = null;
  		if (sample instanceof HTTPSampleResult){
  			surl = ((HTTPSampleResult)sample).getURL();
  		}
  		String rescontent = new String(sample.getResponseData());
  		if (sample.getResponseCode().equals("200") &&
  			((HTTPSampleResult)sample).isMonitor()){
  			try {
  				JAXBContext jxbc = new ObjectFactory();
  				Unmarshaller mar = jxbc.createUnmarshaller();
  				String resdata = new String(sample.getResponseData());
  				// we trim because SAX still has a problem if there
  				// extra linebreaks at the beginning. That has been
  				// around for a long time.
  				resdata = resdata.trim();
  				resdata = resdata.replaceAll("\"&#63;\"","\"0\"");
  				StreamSource ss = new StreamSource(
  					new ByteArrayInputStream(resdata.getBytes()));
  				Object ld =
  					mar.unmarshal(ss);
  				if (ld instanceof Status){
  					Status st = (Status)ld;
  					MonitorStats stat =
  						new MonitorStats(Stats.calculateStatus(st),
  							Stats.calculateLoad(st),
  							0,
  							Stats.calculateMemoryLoad(st),
  							Stats.calculateThreadLoad(st),
  							surl.getHost(),
  							String.valueOf(surl.getPort()),
  							surl.getProtocol(),
  							System.currentTimeMillis());
  
  					MonitorModel mo = new MonitorModel(stat);
  					this.addSample(mo);
  					notifyListeners(mo);
  				}
  			} catch (JAXBException e){
  				// we don't log the errors
  				// e.printStackTrace();
  				noResponse(surl);
  			}
  		} else if (((HTTPSampleResult)sample).isMonitor() ){
  			noResponse(surl);
  		}
  	}
  
  	/**
  	 * If there is no response from the server, we
  	 * create a new MonitorStats object with the
  	 * current timestamp and health "dead".
  	 * @param url
  	 */
  	public void noResponse(URL url){
  		notifyListeners(createNewMonitorModel(url));
  	}
  	
  	public MonitorModel createNewMonitorModel(URL url){
  		MonitorStats stat = new MonitorStats(Stats.DEAD,
  			0,
  			0,
  			0,
  			0,
  			url.getHost(),
  			String.valueOf(url.getPort()),
  			url.getProtocol(),
  			System.currentTimeMillis());
  		MonitorModel mo = new MonitorModel(stat);
  		return mo;
  	}
  	
  	/**
  	 * Clears everything.
  	 */
  	public void clear(){
  		listeners.clear();
  		this.MAP.clear();
  	}
  	
  	/**
  	 * notify the listeners with the MonitorModel object.
  	 * @param model
  	 */
  	public void notifyListeners(MonitorModel model)
  	{
  		for (int idx=0; idx < listeners.size(); idx++){
  			MonitorListener ml = (MonitorListener)listeners.get(idx);
  			ml.addSample(model);
  		}
  	}
  	
  	/**
  	 * Add a listener. When samples are added, the class will
  	 * notify the listener of the change.
  	 * @param listener
  	 */
  	public void addListener(MonitorListener listener){
  		listeners.add(listener);
  	}
  }
  
  
  
  1.1                  jakarta-jmeter/src/monitor/components/org/apache/jmeter/visualizers/ServerPanel.java
  
  Index: ServerPanel.java
  ===================================================================
  // $Header:
  /*
   * 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.visualizers;
  
  import java.awt.Dimension;
  import java.awt.FlowLayout;
  
  import javax.swing.ImageIcon;
  import javax.swing.JPanel;
  import javax.swing.JLabel;
  import org.apache.jmeter.util.JMeterUtils;
  import org.apache.jmeter.monitor.util.Stats;
  
  /**
   * The purpose of ServerPanel is to display an unique
   * server and its current status. The server label
   * consist of the protocol, host and port. For example,
   * a system with multiple Tomcat's running on different
   * ports would be different ServerPanel.
   */
  public class ServerPanel extends JPanel
  	implements MonitorGuiListener
  {
  
  	private JLabel serverField;
  	private JLabel timestampField;
  	/**
  	 * Preference size for the health icon
  	 */
  	private Dimension prefsize = new Dimension(25,75);
  	private JLabel healthIcon;
  	private JLabel loadIcon;
  
  	/**
  	 * Health Icons
  	 */
  	public static final ImageIcon HEALTHY =
  		JMeterUtils.getImage("monitor-healthy.gif");
  	public static final ImageIcon ACTIVE =
  		JMeterUtils.getImage("monitor-active.gif");
  	public static final ImageIcon WARNING =
  		JMeterUtils.getImage("monitor-warning.gif");
  	public static final ImageIcon DEAD =
  		JMeterUtils.getImage("monitor-dead.gif");
  	/**
  	 * Load Icons
  	 */
  	public static final ImageIcon LOAD_1 =
  		JMeterUtils.getImage("monitor-load-1.gif");
  	public static final ImageIcon LOAD_2 =
  		JMeterUtils.getImage("monitor-load-2.gif");
  	public static final ImageIcon LOAD_3 =
  		JMeterUtils.getImage("monitor-load-3.gif");
  	public static final ImageIcon LOAD_4 =
  		JMeterUtils.getImage("monitor-load-4.gif");
  	public static final ImageIcon LOAD_5 =
  		JMeterUtils.getImage("monitor-load-5.gif");
  	public static final ImageIcon LOAD_6 =
  		JMeterUtils.getImage("monitor-load-6.gif");
  	public static final ImageIcon LOAD_7 =
  		JMeterUtils.getImage("monitor-load-7.gif");
  	public static final ImageIcon LOAD_8 =
  		JMeterUtils.getImage("monitor-load-8.gif");
  	public static final ImageIcon LOAD_9 =
  		JMeterUtils.getImage("monitor-load-9.gif");
  	public static final ImageIcon LOAD_10 =
  		JMeterUtils.getImage("monitor-load-10.gif");
  	
  	private MonitorModel DATA;
  	
      /**
       * 
       */
      public ServerPanel(MonitorModel model)
      {
          super();
          DATA = model;
          init(model);
      }
  
  	/**
  	 * Init will create the JLabel widgets for the
  	 * host, health, load and timestamp.
  	 * @param model
  	 */
  	private void init(MonitorModel model)
  	{
  		this.setLayout(new FlowLayout());
  		serverField = new JLabel(model.getURL());
  		this.add(serverField);
  		healthIcon = new JLabel(getHealthyImageIcon(model.getHealth()));
  		healthIcon.setPreferredSize(prefsize);
  		this.add(healthIcon);
  		loadIcon = new JLabel(getLoadImageIcon(model.getLoad()));
  		this.add(loadIcon);
  		timestampField = new JLabel(model.getTimestampString());
  		this.add(timestampField);
  	}
  	
  	/**
  	 * Static method for getting the right ImageIcon for
  	 * the health.
  	 * @param health
  	 * @return
  	 */
  	public static ImageIcon getHealthyImageIcon(int health){
  		ImageIcon i = null;
  		switch(health){
  			case Stats.HEALTHY:
  				i = HEALTHY;
  				break;
  			case Stats.ACTIVE:
  				i = ACTIVE;
  				break;
  			case Stats.WARNING:
  				i = WARNING;
  				break;
  			case Stats.DEAD:
  				i = DEAD;
  				break;
  		}
  		return i;
  	}
  	
  	/**
  	 * Static method looks up the right ImageIcon from
  	 * the load value.
  	 * @param load
  	 * @return
  	 */
  	public static ImageIcon getLoadImageIcon(int load){
  		if (load <= 10){
  			return LOAD_1;
  		} else if (load > 10 && load <= 20){
  			return LOAD_2;
  		} else if (load > 20 && load <= 30){
  			return LOAD_3;
  		} else if (load > 30 && load <= 40){
  			return LOAD_4;
  		} else if (load > 40 && load <= 50){
  			return LOAD_5;
  		} else if (load > 50 && load <= 60){
  			return LOAD_6;
  		} else if (load > 60 && load <= 70){
  			return LOAD_7;
  		} else if (load > 70 && load <= 80){
  			return LOAD_8;
  		} else if (load > 80 && load <= 90){
  			return LOAD_9;
  		} else {
  			return LOAD_10;
  		}
  	}
  	
  	/**
  	 * Method will update the ServerPanel's health, load,
  	 * and timestamp. For efficiency, it uses the static
  	 * method to lookup the images.
  	 */
  	public void updateGui(MonitorModel stat){
  		this.DATA = null;
  		this.DATA = stat;
  		loadIcon.setIcon(getLoadImageIcon(stat.getLoad()));
  		healthIcon.setIcon(getHealthyImageIcon(stat.getHealth()));
  		timestampField.setText(stat.getTimestampString());
  		this.updateGui();
  	}
  	
  	/**
  	 * update the gui
  	 */
  	public void updateGui(){
  		this.repaint();
  	}
  }
  
  
  
  1.1                  jakarta-jmeter/src/monitor/components/org/apache/jmeter/visualizers/MonitorStats.java
  
  Index: MonitorStats.java
  ===================================================================
  // $Header:
  /*
   * 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.visualizers;
  
  import java.io.Serializable;
  
  public class MonitorStats implements Serializable
  {
  
  	public int health;
  	public int load;
  	public int cpuload;
  	public int memload;
  	public int threadload;
  	public String host;
  	public String port;
  	public String protocol;
  	public long timestamp;
  	
      /**
       * 
       */
      public MonitorStats()
      {
          super();
      }
      
      /**
       * Default constructor
       * @param health
       * @param load
       * @param cpuload
       * @param memload
       * @param threadload
       * @param host
       * @param port
       * @param protocol
       * @param time
       */
      public MonitorStats(int health,
      	int load,
      	int cpuload,
      	int memload,
      	int threadload,
      	String host,
      	String port,
      	String protocol,
      	long time){
      		this.health = health;
      		this.load = load;
      		this.cpuload = cpuload;
      		this.memload = memload;
      		this.threadload = threadload;
      		this.host = host;
      		this.port = port;
      		this.protocol = protocol;
      		this.timestamp = time;
      	}
  
  	/**
  	 * For convienance, this method returns the protocol,
  	 * host and port as a URL.
  	 * @return
  	 */
  	public String getURL(){
  		return protocol + "://" + host + ":" + port;
  	}
  }
  
  
  
  1.1                  jakarta-jmeter/src/monitor/components/org/apache/jmeter/visualizers/MonitorModel.java
  
  Index: MonitorModel.java
  ===================================================================
  // $Header:
  /*
   * 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.visualizers;
  
  import java.io.Serializable;
  
  import org.apache.jmeter.samplers.Clearable;
  
  import java.text.SimpleDateFormat;
  import java.util.Date;
  import java.util.LinkedList;
  import java.util.List;
  
  public class MonitorModel implements Clearable, Serializable, Cloneable
  {
  
  	private String name;
  	private List listeners;
  	private MonitorStats current =
  		new MonitorStats(0,0,0,0,0,"","","",System.currentTimeMillis());
  	
      /**
       * 
       */
      public MonitorModel()
      {
          super();
          listeners = new LinkedList();
      }
  
  	public MonitorModel(MonitorStats stat){
  		this.current = stat;
  	}
  	public void setName(String name){
  		this.name = name;
  	}
  	
  	public String getName(){
  		return this.getURL();
  	}
  	
  	public int getHealth(){
  		return this.current.health;
  	}
  	
  	public int getLoad(){
  		return this.current.load;
  	}
  
  	public int getCpuload(){
  		return this.current.cpuload;	
  	}
  	
  	public int getMemload(){
  		return this.current.memload;
  	}
  	
  	public int getThreadload(){
  		return this.current.threadload;
  	}
  	
  	public String getHost(){
  		return this.current.host;
  	}
  	
  	public String getPort(){
  		return this.current.port;
  	}
  	
  	public String getProtocol(){
  		return this.current.protocol;
  	}
  	
  	public long getTimestamp(){
  		return this.current.timestamp;
  	}
  	
  	public String getURL(){
  		return this.current.getURL();
  	}
  	
  	public String getTimestampString(){
  		Date date = new Date(this.current.timestamp);
  		SimpleDateFormat ft = new SimpleDateFormat();
  		return ft.format(date);
  	}
  	
  	/**
  	 * Method is used by DefaultMutableTreeNode to get
  	 * the label for the node.
  	 */
  	public String toString(){
  		return getURL();
  	}
  	
      /* (non-Javadoc)
       * @see org.apache.jmeter.samplers.Clearable#clear()
       */
      public void clear()
      {
  		current = 
  			new MonitorStats(0,0,0,0,0,"","","",System.currentTimeMillis());
      }
  
  	/**
  	 * notify the listeners with the MonitorModel object.
  	 * @param model
  	 */
  	public void notifyListeners(MonitorModel model)
  	{
  		for (int idx=0; idx < listeners.size(); idx++){
  			MonitorListener ml = (MonitorListener)listeners.get(idx);
  			ml.addSample(model);
  		}
  	}
  	
  	public void addListener(MonitorListener listener){
  		listeners.add(listener);
  	}
  	
  	public Object clone(){
  		MonitorStats newstats =
  			new MonitorStats(current.health,
  				current.load,
  				current.cpuload,
  				current.memload,
  				current.threadload,
  				current.host,
  				current.port,
  				current.protocol,
  				current.timestamp);
  		return new MonitorModel(newstats);
  	}
  }
  
  
  
  1.1                  jakarta-jmeter/src/monitor/components/org/apache/jmeter/visualizers/MonitorHealthPanel.java
  
  Index: MonitorHealthPanel.java
  ===================================================================
  // $Header:
  /*
   * 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.visualizers;
  
  import java.awt.BorderLayout;
  import java.awt.Component;
  import java.awt.Dimension;
  import java.awt.Font;
  import javax.swing.BoxLayout;
  import javax.swing.ImageIcon;
  import javax.swing.JLabel;
  import javax.swing.JPanel;
  
  import java.util.HashMap;
  import java.util.Random;
  
  import javax.swing.JScrollPane;
  
  import org.apache.jmeter.util.JMeterUtils;
  import org.apache.jmeter.samplers.Clearable;
  /**
   * The health panel is responsible for showing the health
   * of the servers. It only uses the most current information
   * to show the status.
   */
  public class MonitorHealthPanel extends JPanel
  	implements MonitorListener, Clearable
  {
  	private HashMap SERVERMAP = new HashMap();
  	private JPanel SERVERS = null;
  	private MonitorAccumModel MODEL;
  	private JScrollPane SCROLL = null;
  	
  	Font plainText = new Font("plain", Font.PLAIN, 9);
  	public static final String INFO_H =
  		JMeterUtils.getResString("monitor_equation_healthy");
  	public static final String INFO_A =
  		JMeterUtils.getResString("monitor_equation_active");
  	public static final String INFO_W =
  		JMeterUtils.getResString("monitor_equation_warning");
  	public static final String INFO_D =
  		JMeterUtils.getResString("monitor_equation_dead");
  	public static final String INFO_LOAD =
  		JMeterUtils.getResString("monitor_equation_load");
  	
      /**
       * 
       */
      public MonitorHealthPanel(MonitorAccumModel model)
      {
      	this.MODEL = model;
      	this.MODEL.addListener(this);
          init();
      }
  
  	private void init(){
  		this.setLayout(new BorderLayout());
  		ImageIcon legend = JMeterUtils.getImage("monitor-legend.gif");
  		JLabel label = new JLabel(legend);
  		label.setPreferredSize(new Dimension(550,25));
  		this.add(label,BorderLayout.NORTH);
  
  		this.SERVERS = new JPanel();
  		this.SERVERS.setLayout(new BoxLayout(SERVERS, BoxLayout.Y_AXIS));
  		this.SERVERS.setAlignmentX(Component.LEFT_ALIGNMENT);
  
  		SCROLL = new JScrollPane(this.SERVERS);
  		SCROLL.setPreferredSize(new Dimension(300,300));
  		this.add(SCROLL,BorderLayout.CENTER);
  		
  		// the equations
  		String eqstring1 = " " + INFO_H + "   |   " + INFO_A;
  		String eqstring2 = " " + INFO_W + "   |   " + INFO_D;
  		String eqstring3 = " " + INFO_LOAD;
  		JLabel eqs = new JLabel();
  		eqs.setLayout(new BorderLayout());
  		eqs.setPreferredSize(new Dimension(500,60));
  		eqs.add(new JLabel(eqstring1),BorderLayout.NORTH);
  		eqs.add(new JLabel(eqstring2),BorderLayout.CENTER);
  		eqs.add(new JLabel(eqstring3),BorderLayout.SOUTH);
  		this.add(eqs,BorderLayout.SOUTH);
  	}
  
  	public void createTestData(){	
  		Random ran = new Random(System.currentTimeMillis());
  		for (int idx = 0; idx < 21; idx++){
  			MonitorStats stat = new MonitorStats();
  			stat.host = "localhost" + idx;
  			stat.port = "8080";
  			stat.protocol = "http";
  			stat.health = ran.nextInt(3);
  			stat.load = ran.nextInt(100);
  			stat.timestamp = (System.currentTimeMillis() - ran.nextLong());
  			
  			MonitorModel mm = new MonitorModel(stat);
  			ServerPanel sp = new ServerPanel(mm);
  			this.SERVERMAP.put(stat.getURL(),sp);
  			this.SERVERS.add(sp);
  		}
  	}
  	
  	/**
  	 * 
  	 * @param stats
  	 */
  	public void addSample(MonitorModel model){
  		if (SERVERMAP.containsKey(model.getURL())){
  			ServerPanel pane = null;
  			if(SERVERMAP.get(model.getURL()) != null){
  				pane = (ServerPanel)SERVERMAP.get((model.getURL()));
  			} else {
  				pane = new ServerPanel(model);
  				SERVERMAP.put(model.getURL(),pane);
  			}
  			pane.updateGui(model);
  			this.SERVERS.updateUI();
  		} else {
  			ServerPanel newpane = new ServerPanel(model);
  			SERVERMAP.put(model.getURL(),newpane);
  			this.SERVERS.add(newpane);
  			newpane.updateGui(model);
  			this.SERVERS.updateUI();
  		}
  	}
  
  	public void clear(){
  		this.SERVERS.removeAll();
  		this.SERVERS.updateUI();
  	}
  }
  
  
  
  1.1                  jakarta-jmeter/src/monitor/components/org/apache/jmeter/visualizers/MonitorTabPane.java
  
  Index: MonitorTabPane.java
  ===================================================================
  // $Header:
  /*
   * 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.visualizers;
  
  import javax.swing.JTabbedPane;
  
  public class MonitorTabPane extends JTabbedPane
  {
  
      /**
       * 
       */
      public MonitorTabPane()
      {
          super(TOP);
      }
  
  }
  
  
  
  1.1                  jakarta-jmeter/src/monitor/components/org/apache/jmeter/visualizers/MonitorPerformancePanel.java
  
  Index: MonitorPerformancePanel.java
  ===================================================================
  /*
   * Created on Mar 8, 2004
   *
   * To change the template for this generated file go to
   * Window>Preferences>Java>Code Generation>Code and Comments
   */
  package org.apache.jmeter.visualizers;
  
  import java.util.HashMap;
  import java.awt.BorderLayout;
  import java.awt.Dimension;
  import java.awt.Font;
  import java.awt.FlowLayout;
  
  import javax.swing.ImageIcon;
  import javax.swing.JLabel;
  import javax.swing.JPanel;
  import javax.swing.JScrollPane;
  import javax.swing.JSplitPane;
  import javax.swing.JTree;
  import javax.swing.tree.DefaultMutableTreeNode;
  import javax.swing.tree.DefaultTreeModel;
  import javax.swing.tree.TreeSelectionModel;
  import javax.swing.event.TreeSelectionListener;
  import javax.swing.event.TreeSelectionEvent;
  
  
  import org.apache.jmeter.gui.util.JMeterColor;
  import org.apache.jmeter.samplers.Clearable;
  import org.apache.jmeter.samplers.SampleResult;
  import org.apache.jmeter.util.JMeterUtils;
  
  public class MonitorPerformancePanel extends JSplitPane
  	implements TreeSelectionListener, MonitorListener, Clearable
  {
  
  	private JScrollPane TREEPANE;
  	private JPanel GRAPHPANEL;
  	private JTree SERVERTREE;
  	private DefaultTreeModel TREEMODEL;
  	private MonitorGraph GRAPH;
  	private DefaultMutableTreeNode ROOTNODE;
  	private HashMap SERVERMAP;
  	private MonitorAccumModel MODEL;
  	private SampleResult ROOTSAMPLE;
  	
  	public static final String LEGEND_HEALTH =
  		JMeterUtils.getResString("monitor_legend_health");
  	public static final String LEGEND_LOAD =
  		JMeterUtils.getResString("monitor_legend_load");
  	public static final String LEGEND_MEM =
  		JMeterUtils.getResString("monitor_legend_memory_per");
  	public static final String LEGEND_THREAD =
  		JMeterUtils.getResString("monitor_legend_thread_per");
  	public static ImageIcon LEGEND_HEALTH_ICON =
  		JMeterUtils.getImage("monitor-green-legend.gif");
  	public static ImageIcon LEGEND_LOAD_ICON =
  		JMeterUtils.getImage("monitor-blue-legend.gif");
  	public static ImageIcon LEGEND_MEM_ICON =
  		JMeterUtils.getImage("monitor-orange-legend.gif");
  	public static ImageIcon LEGEND_THREAD_ICON =
  		JMeterUtils.getImage("monitor-red-legend.gif");
  	public static final String GRID_LABEL_TOP =
  		JMeterUtils.getResString("monitor_label_left_top");
  	public static final String GRID_LABEL_MIDDLE =
  		JMeterUtils.getResString("monitor_label_left_middle");
  	public static final String GRID_LABEL_BOTTOM =
  		JMeterUtils.getResString("monitor_label_left_bottom");
  	public static final String GRID_LABEL_HEALTHY =
  		JMeterUtils.getResString("monitor_label_right_healthy");
  	public static final String GRID_LABEL_ACTIVE =
  		JMeterUtils.getResString("monitor_label_right_active");
  	public static final String GRID_LABEL_WARNING =
  		JMeterUtils.getResString("monitor_label_right_warning");
  	public static final String GRID_LABEL_DEAD =
  		JMeterUtils.getResString("monitor_label_right_dead");
  	
  	public static final String PERF_TITLE =
  		JMeterUtils.getResString("monitor_performance_title");
  	public static final String SERVER_TITLE =
  		JMeterUtils.getResString("monitor_performance_servers");
  
  	protected Font plaintext = new Font("plain", Font.TRUETYPE_FONT, 10);
  
      /**
       * 
       */
      public MonitorPerformancePanel(MonitorAccumModel model, MonitorGraph graph)
      {
          super();
          this.SERVERMAP = new HashMap();
          this.MODEL = model;
          this.MODEL.addListener(this);
          this.GRAPH = graph;
          init();
      }
  
  	public void init(){
  		ROOTSAMPLE = new SampleResult();
  		ROOTSAMPLE.setSampleLabel(SERVER_TITLE);
  		ROOTSAMPLE.setSuccessful(true);
  		ROOTNODE = new DefaultMutableTreeNode(ROOTSAMPLE);
  		TREEMODEL = new DefaultTreeModel(ROOTNODE);
  		SERVERTREE = new JTree(TREEMODEL);
  		SERVERTREE.getSelectionModel().setSelectionMode(
  			TreeSelectionModel.SINGLE_TREE_SELECTION);
  		SERVERTREE.addTreeSelectionListener(this);
  		SERVERTREE.setShowsRootHandles(true);
  		TREEPANE = new JScrollPane(SERVERTREE);
  		TREEPANE.setPreferredSize(new Dimension(150,200));
  		this.add(TREEPANE,JSplitPane.LEFT);
  		this.setDividerLocation(0.18);
  	
  		JPanel right = new JPanel();
  		right.setLayout(new BorderLayout());
  		JLabel title = new JLabel(" " + PERF_TITLE);
  		title.setPreferredSize(new Dimension(200,40));
  		GRAPHPANEL = new JPanel();
  		GRAPHPANEL.setLayout(new BorderLayout());
  		GRAPHPANEL.setMaximumSize(
  			new Dimension(MODEL.getBufferSize(),MODEL.getBufferSize()));
  		GRAPHPANEL.setBackground(JMeterColor.WHITE);
  		GRAPHPANEL.add(GRAPH,BorderLayout.CENTER);
  		right.add(GRAPHPANEL,BorderLayout.CENTER);
  		
  		right.add(title,BorderLayout.NORTH);
  		right.add(createLegend(),BorderLayout.SOUTH);
  		right.add(createLeftGridLabels(),BorderLayout.WEST);
  		right.add(createRightGridLabels(),BorderLayout.EAST);
  		this.add(right,JSplitPane.RIGHT);		
  	}
  	
  	public JPanel createLegend(){
  		Dimension lsize = new Dimension(130,18);
  		
  		JPanel legend = new JPanel();
  		legend.setLayout(new FlowLayout());
  		JLabel health = new JLabel(LEGEND_HEALTH);
  		health.setFont(plaintext);
  		health.setPreferredSize(lsize);
  		health.setIcon(LEGEND_HEALTH_ICON);
  		legend.add(health);
  		
  		JLabel load = new JLabel(LEGEND_LOAD);
  		load.setFont(plaintext);
  		load.setPreferredSize(lsize);
  		load.setIcon(LEGEND_LOAD_ICON);
  		legend.add(load);
  		
  		JLabel mem = new JLabel(LEGEND_MEM);
  		mem.setFont(plaintext);
  		mem.setPreferredSize(lsize);
  		mem.setIcon(LEGEND_MEM_ICON);
  		legend.add(mem);
  		
  		JLabel thd = new JLabel(LEGEND_THREAD);
  		thd.setFont(plaintext);
  		thd.setPreferredSize(lsize);
  		thd.setIcon(LEGEND_THREAD_ICON);
  		legend.add(thd);
  		return legend;
  	}
  	
  	public JPanel createLeftGridLabels(){
  		Dimension lsize = new Dimension(33,20);
  		JPanel labels = new JPanel();
  		labels.setLayout(new BorderLayout());
  		
  		JLabel top = new JLabel(" " + GRID_LABEL_TOP);
  		top.setFont(plaintext);
  		top.setPreferredSize(lsize);
  		labels.add(top,BorderLayout.NORTH);
  		
  		JLabel mid = new JLabel(" " + GRID_LABEL_MIDDLE);
  		mid.setFont(plaintext);
  		mid.setPreferredSize(lsize);
  		labels.add(mid,BorderLayout.CENTER);
  		
  		JLabel bottom = new JLabel(" " + GRID_LABEL_BOTTOM);
  		bottom.setFont(plaintext);
  		bottom.setPreferredSize(lsize);
  		labels.add(bottom,BorderLayout.SOUTH);
  		return labels;
  	}
  	
  	public JPanel createRightGridLabels(){
  		JPanel labels = new JPanel();
  		labels.setLayout(new BorderLayout());
  		labels.setPreferredSize(new Dimension(40,GRAPHPANEL.getWidth() - 100));
  		Dimension lsize = new Dimension(40,20);
  		JLabel h = new JLabel(GRID_LABEL_HEALTHY);
  		h.setFont(plaintext);
  		h.setPreferredSize(lsize);
  		labels.add(h,BorderLayout.NORTH);
  		
  		JLabel d = new JLabel(GRID_LABEL_DEAD);
  		d.setFont(plaintext);
  		d.setPreferredSize(lsize);
  		labels.add(d,BorderLayout.SOUTH);
  		return labels;
  	}
  	
  	public void addSample(MonitorModel model){
  		if (!SERVERMAP.containsKey(model.getURL())){
  			DefaultMutableTreeNode newnode =
  				new DefaultMutableTreeNode(model);
  			newnode.setAllowsChildren(false);
  			SERVERMAP.put(model.getURL(),newnode);
  			ROOTNODE.add(newnode);
  			TREEPANE.updateUI();
  		}
  		DefaultMutableTreeNode node =
  			(DefaultMutableTreeNode) SERVERTREE.getLastSelectedPathComponent();
  		Object usrobj = node.getUserObject();
  		if (usrobj instanceof MonitorModel){
  			GRAPH.updateGui((MonitorModel)usrobj);
  		}
  	}
  	
  	/**
  	 * When the user selects a different node in the
  	 * tree, we get the selected node. From the node,
  	 * we get the UserObject used to create the
  	 * treenode in the constructor.
  	 */
  	public void valueChanged(TreeSelectionEvent e)
  	{
  		DefaultMutableTreeNode node =
  			(DefaultMutableTreeNode) SERVERTREE.getLastSelectedPathComponent();
  		Object usrobj = node.getUserObject();
  		if (usrobj instanceof MonitorModel && usrobj != null){
  			MonitorModel mo = (MonitorModel)usrobj;
  			GRAPH.updateGui(mo);
  			this.updateUI();
  		}
  		TREEPANE.updateUI();
  	}
  	
  	public void clear(){
  		this.SERVERMAP.clear();
  		ROOTNODE.removeAllChildren();
  		SERVERTREE.updateUI();
  		GRAPH.clear();
  	}
  }
  
  
  
  1.1                  jakarta-jmeter/src/monitor/components/org/apache/jmeter/visualizers/MonitorHealthVisualizer.java
  
  Index: MonitorHealthVisualizer.java
  ===================================================================
  // $Header:
  /*
   * 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.visualizers;
  
  import java.awt.BorderLayout;
  import java.awt.Container;
  import java.awt.Dimension;
  import java.awt.Graphics;
  import java.awt.event.ItemEvent;
  import java.awt.event.ItemListener;
  import java.awt.Image;
  
  import javax.swing.border.Border;
  import javax.swing.border.EmptyBorder;
  
  import org.apache.jmeter.gui.util.VerticalPanel;
  import org.apache.jmeter.reporters.ResultCollector;
  import org.apache.jmeter.testelement.TestElement;
  
  import org.apache.jmeter.samplers.Clearable;
  import org.apache.jmeter.samplers.SampleResult;
  import org.apache.jmeter.util.JMeterUtils;
  import org.apache.jmeter.visualizers.gui.AbstractVisualizer;
  
  /**
   * For performance reasons, I am using tabs for the
   * visualizers. Since a visualizer is heavy weight,
   * I don not want to have two separate result
   * collectors rather the same information. Instead,
   * I would rather have the visualizer be the
   * container for the data and simply pass the data
   * to child JComponents.
   */
  public class MonitorHealthVisualizer extends AbstractVisualizer
  	implements ImageVisualizer, ItemListener, GraphListener, Clearable
  {
  	private MonitorTabPane TABPANE;
  	private MonitorHealthPanel HEALTHPANE;
  	private MonitorPerformancePanel PERFPANE;
  	private MonitorAccumModel MODEL;
  	private MonitorGraph GRAPH;
  	
      /**
       * Constructor for the GraphVisualizer object.
       */
      public MonitorHealthVisualizer()
      {
      	MODEL = new MonitorAccumModel();
      	GRAPH = new MonitorGraph(MODEL);
      	init();
      }
  
      public String getStaticLabel()
      {
          return JMeterUtils.getResString("monitor_health_title");
      }
  
  	/**
  	 * Because of the unique requirements of a monitor
  	 * We have to handle the results differently than
  	 * normal GUI components. A monitor should be able
  	 * to run for a very long time without eating up
  	 * all the memory.
  	 */
  	public void add(SampleResult res)
  	{
  		MODEL.addSample(res);
  	}
  	
  	public Image getImage()
  	{
  		Image result = GRAPH.createImage(this.getWidth(),this.getHeight());
  		Graphics image = result.getGraphics();
  		GRAPH.paintComponent(image);
  		return result;
  	}
  
  	public void itemStateChanged(ItemEvent e)
  	{
  	}
  	
  	public synchronized void updateGui()
  	{
  		this.repaint();
  	}
  
  	public synchronized void updateGui(Sample s)
  	{
  		this.repaint();
  	}
  
  	/**
  	 * Initialize the GUI.
  	 */
  	private void init()
  	{
  		this.setLayout(new BorderLayout());
  
  		// MAIN PANEL
  		Border margin = new EmptyBorder(10, 10, 5, 10);
  		this.setBorder(margin);
  		
  		// Add the main panel and the graph
  		this.add(this.makeTitlePanel(), BorderLayout.NORTH);
  		this.createTabs();
  	}
  	
  	protected void createTabs(){
  		TABPANE = new MonitorTabPane();
  		createHealthPane(TABPANE);
  		createPerformancePane(TABPANE);
  		this.add(TABPANE, BorderLayout.CENTER);
  	}
  
  	/**
  	 * Create the JPanel
  	 * @param pane
  	 */	
  	public void createHealthPane(MonitorTabPane pane){
  		HEALTHPANE = new MonitorHealthPanel(MODEL);
  		pane.addTab(JMeterUtils.getResString("monitor_health_tab_title"),
  			HEALTHPANE);
  	}
  
  	/**
  	 * Create the JSplitPane for the performance history
  	 * @param pane
  	 */	
  	public void createPerformancePane(MonitorTabPane pane){
  		PERFPANE = new MonitorPerformancePanel(MODEL,GRAPH);
  		pane.addTab(JMeterUtils.getResString("monitor_performance_tab_title"),
  			PERFPANE);
  	}
  	
  	protected Container makeTitlePanel()
  	{
  		VerticalPanel titlePanel = new VerticalPanel();
  		titlePanel.add(createTitleLabel());
  		titlePanel.add(getNamePanel());
  		return titlePanel;
  	}
  
  	/**
  	 * Clear will clear the MonitorAccumModel and create a
  	 * new instance.
  	 */
  	public void clear(){
  		this.MODEL.clear();
  		this.HEALTHPANE.clear();
  		this.PERFPANE.clear();
  	}
  	
  	public TestElement createTestElement()
  	{
  		if (collector == null)
  		{
  			collector = new ResultCollector();
  		}
  		modifyTestElement(collector);
  		return (TestElement) collector.clone();
  	}
  }
  
  
  
  1.1                  jakarta-jmeter/src/monitor/components/org/apache/jmeter/visualizers/MonitorGuiListener.java
  
  Index: MonitorGuiListener.java
  ===================================================================
  // $Header:
  /*
   * 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.visualizers;
  
  public interface MonitorGuiListener
  {
  	void updateGui(MonitorModel event);
  	void updateGui();
  }
  
  
  
  1.1                  jakarta-jmeter/src/monitor/components/org/apache/jmeter/visualizers/MonitorListener.java
  
  Index: MonitorListener.java
  ===================================================================
  // $Header:
  /*
   * 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.visualizers;
  
  public interface MonitorListener
  {
  	public void addSample(MonitorModel model);
  }
  
  
  
  1.1                  jakarta-jmeter/src/monitor/components/org/apache/jmeter/visualizers/MonitorGraph.java
  
  Index: MonitorGraph.java
  ===================================================================
  /*
   * Created on Mar 9, 2004
   *
   * To change the template for this generated file go to
   * Window>Preferences>Java>Code Generation>Code and Comments
   */
  package org.apache.jmeter.visualizers;
  
  import java.awt.Color;
  import java.awt.Graphics;
  import java.awt.event.MouseEvent;
  import java.awt.event.MouseListener;
  import java.util.Iterator;
  import java.util.List;
  
  import javax.swing.JComponent;
  
  import org.apache.jmeter.gui.util.JMeterColor;
  import org.apache.jmeter.samplers.Clearable;
  
  public class MonitorGraph
      extends JComponent
      implements MouseListener, MonitorGuiListener, Clearable
  {
  	private static int width = 500;
  	private MonitorAccumModel MODEL;
  	private MonitorModel CURRENT;
  	
  	private boolean CPU = false;
  	private boolean HEALTH = true;
  	private boolean LOAD = true;
  	private boolean MEM = true;
  	private boolean THREAD = true;
  	private boolean YGRID = true;
  	private boolean XGRID = true;
  
  	private int COUNT = 0;
  	private int GRAPHMAX = 0;
      /**
       * 
       */
      public MonitorGraph(MonitorAccumModel model)
      {
          this.MODEL = model;
          GRAPHMAX = model.getBufferSize();
          init();
      }
  
  	private void init(){
  		repaint();
  	}
  	
  	public void setCpu(boolean cpu){
  		this.CPU = cpu;
  	}
  	
  	public void setHealth(boolean health){
  		this.HEALTH = health;
  	}
  	
  	public void setLoad(boolean load){
  		this.LOAD = load;
  	}
  	
  	public void setMem(boolean mem){
  		this.MEM = mem;
  	}
  	
  	public void setThread(boolean thread){
  		this.THREAD = thread;
  	}
  	
      /* (non-Javadoc)
       * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
       */
      public void mouseClicked(MouseEvent e)
      {
      }
  
      /* (non-Javadoc)
       * @see java.awt.event.MouseListener#mouseEntered(java.awt.event.MouseEvent)
       */
      public void mouseEntered(MouseEvent e)
      {
      }
  
      /* (non-Javadoc)
       * @see java.awt.event.MouseListener#mouseExited(java.awt.event.MouseEvent)
       */
      public void mouseExited(MouseEvent e)
      {
      }
  
      /* (non-Javadoc)
       * @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent)
       */
      public void mousePressed(MouseEvent e)
      {
      }
  
      /* (non-Javadoc)
       * @see java.awt.event.MouseListener#mouseReleased(java.awt.event.MouseEvent)
       */
      public void mouseReleased(MouseEvent e)
      {
  
      }
  
      /* (non-Javadoc)
       * @see org.apache.jmeter.visualizers.MonitorGuiListener#updateGui(org.apache.jmeter.visualizers.MonitorModel)
       */
      public void updateGui(final MonitorModel model)
      {
      	if (this.isShowing()){
  			this.CURRENT = model;
  			repaint();
      	}
      }
  
  	public void paintComponent(Graphics g)
  	{
  		super.paintComponent(g);
  		if (this.CURRENT != null){
  			synchronized(MODEL){
  				List samples = MODEL.getAllSamples(this.CURRENT.getURL());
  				int size = samples.size();
  				synchronized (samples)
  				{
  					Iterator e;
  					if (size > getWidth()){
  						e = samples.listIterator(size - getWidth());
  					} else {
  						e = samples.iterator();
  					}
  					MonitorModel last = null;
  					for (int i = 0; e.hasNext(); i++)
  					{
  						MonitorModel s = (MonitorModel) e.next();
  						if (last == null){
  							last = s;
  						}
  						drawSample(i, s, g, last);
  						last = s;
  					}
  				}
  			}
  		}
  	}
  
      /* (non-Javadoc)
       * @see org.apache.jmeter.visualizers.MonitorGuiListener#updateGui()
       */
      public void updateGui()
      {
      	repaint();
      }
  
      /* (non-Javadoc)
       * @see org.apache.jmeter.samplers.Clearable#clear()
       */
      public void clear()
      {
      	paintComponent(getGraphics());
      	this.repaint();
      }
      
  	private void drawSample(int x, MonitorModel model,
  		Graphics g, MonitorModel last)
  	{
  		double width = (double)getWidth();
  		double height = (double)getHeight() - 10.0;
  		// int xaxis = (int)(x % width);
  		// int lastx = (int)((x - 1) % width);
  		int xaxis = (int)(width * (x /width));
  		int lastx = (int)(width * ((x - 1)/width));
  		
  		// draw grid
  		if (YGRID && x == 1){
  			int q1 = (int)(height * 0.25);
  			int q2 = (int)(height * 0.50);
  			int q3 = (int)(height * 0.75);
  			g.setColor(JMeterColor.lightGray);
  			g.drawLine(0,q1,getWidth(),q1);
  			g.drawLine(0,q2,getWidth(),q2);
  			g.drawLine(0,q3,getWidth(),q3);
  		}
  		if (XGRID && x == 1){
  			int x1 = (int)(width * 0.25);
  			int x2 = (int)(width * 0.50);
  			int x3 = (int)(width * 0.75);
  			g.drawLine(x1,0,x1,getHeight());
  			g.drawLine(x2,0,x2,getHeight());
  			g.drawLine(x3,0,x3,getHeight());
  			g.drawLine(getWidth(),0,getWidth(),getHeight());
  		}
  		
  		if (HEALTH)
  		{
  			int hly =
  				(int)(height - (height * ((double)model.getHealth()/3.0)));
  			int lasty =
  				(int)(height - (height * ((double)last.getHealth()/3.0)));
  
  			g.setColor(JMeterColor.GREEN);
  			g.drawLine(lastx,lasty,xaxis,hly);
  		}
  
  		if (LOAD)
  		{
  			int ldy =
  				(int)(height - (height * ((double)model.getLoad()/100.0)));
  			int lastldy =
  				(int)(height - (height * ((double)last.getLoad()/100.0)));
  
  			g.setColor(Color.BLUE);
  			g.drawLine(lastx,lastldy,xaxis,ldy);
  		}
  
  		if (MEM)
  		{
  			int mmy =
  				(int)(height - (height * ((double)model.getMemload()/100.0)));
  			int lastmmy =
  				(int)(height - (height * ((double)last.getMemload()/100.0)));
  
  			g.setColor(JMeterColor.ORANGE);
  			g.drawLine(lastx,lastmmy,xaxis,mmy);
  		}
  
  		if (THREAD)
  		{
  			int thy =
  				(int)(height - (height * ((double)model.getThreadload()/100.0)));
  			int lastthy =
  				(int)(height - (height * ((double)last.getThreadload()/100.0)));
  
  			g.setColor(Color.RED);
  			g.drawLine(lastx,lastthy,xaxis,thy);
  		}
  	}
  
  }
  
  
  

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