如何跟踪jmeter中的指标以查找' java请求'与子结果?

时间:2014-07-31 18:32:38

标签: jmeter

我正在使用带有Java Request采样器的jmeter。这些调用我编写的java类,它返回一个SampleResult对象,该对象包含用例的时序度量。 SampleResult是一棵树,可以有子SampleResult对象(SampleResult.addSubResult方法)。我似乎无法在jmeter中找到一个跟踪子结果的好方法,因此我只能轻松获得父SampleResult的结果。

是否有jmeter中的监听器允许我查看子结果的统计数据/图表(例如,查看所有具有相同名称的子结果的平均时间)。

3 个答案:

答案 0 :(得分:2)

我刚刚成功完成了这项工作,并想分享它。如果您按照我在此提供的说明操作,它也适用于您。我为摘要表监听器做了这个。而且,我在Windows上做到了。而且,我使用了Eclipse

步骤:

  1. 访问JMeter的网站并下载源代码。你可以在3.0版本中找到它。 http://jmeter.apache.org/download_jmeter.cgi
  2. 在那里,我点击了下载Zip文件的选项。

    然后,在同一页面上,下载3.0版的二进制文件,如果你还没有这样做的话。然后,将该zip文件解压缩到硬盘上。

    1. 将zip文件解压缩到硬盘后,抓取文件" SummaryReport.java"。它可以在这里找到:" \ apache-jmeter-3.0 \ src \ components \ org \ apache \ jmeter \ visualizers \ SummaryReport.java"

    2. 在Eclipse中创建一个新类,然后将所有代码复制/粘贴到新类中。然后,重命名你的课程," SummaryReport"换个名字。在代码中的任何地方,替换" SummaryReport"用你班上的新名字。

    3. 我正在使用Java 8.因此,有一行代码不能为我编译。它是下面的一行。

    4. private final Map tableRows = new ConcurrentHashMap<>();

      您需要删除<>在那条线上,Java 1.8并不支持它。然后,它将编译

      还有一行产生了编译错误。这是下面的那个。

      CSVSaveService.saveCSVStats(StatGraphVisualizer.getAllTableData(model, FORMATS),writer,` 
                              saveHeaders.isSelected() ? StatGraphVisualizer.getLabels(COLUMNS) : null);
      

      首先,它没有找到StatGraphVisualizer类的来源。所以,我导入了它,如下所示。

      import org.apache.jmeter.visualizers.StatGraphVisualizer;
      

      其次,它没有找到方法" getLabels"在" StatGraphVisualizer.getLabels。"所以,这就是我修复它之后这段代码的样子。如下所示。

      CSVSaveService.saveCSVStats(StatGraphVisualizer.getAllTableData(model, FORMATS),writer);
      

      编译。那种方法不需要第二个参数。

      现在,一切都应该编译。

      1. 在下面找到此方法。您可以在此处开始添加自定义项。

        @覆盖 public void add(final SampleResult res){

      2. 您需要像我一样创建所有子结果的数组,如下所示。 Bold中的行是新代码。 (所有新代码都以粗体显示)。

        public void add(final SampleResult res) {
                final String sampleLabel = res.getSampleLabel(); // useGroupName.isSelected());
        
        
        
        **final SampleResult[] theSubResults = res.getSubResults();**
        

        然后,为子结果对象的每个标签创建一个String,如下所示。

        **final String writesampleLabel = theSubResults[0].getSampleLabel(); // (useGroupName.isSelected());
                final String readsampleLabel =  theSubResults[1].getSampleLabel(); // (useGroupName.isSelected());**
        

        接下来,转到下面的方法。

        JMeterUtils.runSafe(false, new Runnable() {
                    @Override
                    public void run() {
        

        新增的代码如下所示,粗体。

        JMeterUtils.runSafe(false, new Runnable() {
                    @Override
                    public void run() {
                        Calculator row = null;
                        **Calculator row1 = null;
                        Calculator row2 = null;**
                        synchronized (lock) {
                            row =  tableRows.get(sampleLabel);
                            **row1 = tableRows.get(writesampleLabel);
                            row2 = tableRows.get(readsampleLabel);**
        
        if (row == null) {
                                row = new Calculator(sampleLabel);
                                tableRows.put(row.getLabel(), row);
                                model.insertRow(row, model.getRowCount() - 1);
                            }
        
                            **if (row1 == null) {
                                row1 = new Calculator(writesampleLabel);
                                tableRows.put(row1.getLabel(), row1);
                                model.insertRow(row1, model.getRowCount() - 1);
                            }
        
                             if (row2 == null) {
                                row2 = new Calculator(readsampleLabel);
                                tableRows.put(row2.getLabel(), row2);
                                model.insertRow(row2, model.getRowCount() - 1);
                            }**
        
                        } // close lock
                        /*
                         * Synch is needed because multiple threads can update the counts.
                         */
                        synchronized(row) {
                            row.addSample(res);    
                        }
        
                        **synchronized(row1) {
                           row1.addSample(theSubResults[0]);      
                        }**
        
                        **synchronized(row2) {
                            row2.addSample(theSubResults[1]);
                        }**
        

        这就是需要定制的全部内容。

        1. 在Eclipse中,将新类导出到Jar文件中。然后将它放在您从上面的步骤1中提取的Jmeter二进制文件的lib / ext文件夹中。

        2. 像往常一样启动Jmeter。

        3. 在Java sampler中,添加一个新的Listener。您现在将看到两个"摘要表"听众。其中一个将是您刚刚创建的新的一个。将新的一个引入Java Sampler后,将其重命名为唯一的。然后运行测试并查看新的"摘要表"监听器。您将看到所有样本结果的摘要结果/统计数据。

        4. 我的下一步是为我想要自定义的所有其他听众执行相同的步骤。

        5. 我希望这篇文章有所帮助。

答案 1 :(得分:1)

以下是我的一些插件代码,您可以将其作为编写自己的插件的起点。我真的不能发布所有内容,因为有几十个课程。很少有人知道:

  • 我的插件就像所有可视化器插件一样扩展了jmeter类 AbstractVisualizer
  • 你需要在eclipse中使用以下罐子来装配: jfxrt.jar,ApacheJMeter_core.jar
  • 你需要java for javafx(jar文件来自sdk)
  • 如果编译插件,则需要将其放在jmeter / lib / ext中。 你还需要把子弹2中的罐放在jmeter / lib
  • 有一种名为" add(SampleResult)"在我班上这个 每次java样本时都会被jmeter框架调用 完成并将SampleResult作为参数传递。假设你 拥有可扩展的Java Sample类 AbstractJavaSamplerClient你的类将有一个名为的方法 runTest返回sampleresult。同样的回归对象将是 传入你的插件添加方法。
  • 我的插件只将所有示例结果放入缓冲区 每5个结果更新一次屏幕。

以下是代码:

import java.awt.BorderLayout;
import java.util.ArrayList;
import java.util.List;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import org.apache.jmeter.samplers.SampleResult;
import org.apache.jmeter.testelement.TestStateListener;
import org.apache.jmeter.visualizers.gui.AbstractVisualizer;

public class FxVisualizer extends AbstractVisualizer  implements TestStateListener {


    int currentId = 0;

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    private static final int BUFFER_SIZE = 5; 

    @Override
    public String getName() 
    {
        return super.getName();//"George's sub result viewer.";
    }

    @Override
      public String getStaticLabel()
      {
        return "Georges FX Visualizer";
      }



    @Override
    public String getComment() 
    {
        return "George wrote this plugin. There are many plugins like it but this one is mine.";
    }
    static Long initCount = new Long(0);
    public FxVisualizer()
    {
        init();
    }
    private void init()
    { 
        //LoggingUtil.debug("in FxVisualizer init()");
        try
        {

            FxTestListener.setListener(this); 
            this.setLayout(new BorderLayout());
            Border margin = new EmptyBorder(10, 10, 5, 10);
            this.setBorder(margin);
            //this.add(makeTitlePanel(), BorderLayout.NORTH);
            final JFXPanel fxPanel = new JFXPanel();
            add(fxPanel);
            //fxPanel.setScene(getScene()); 

            Platform.runLater(new Runnable() {
                @Override
                public void run() {
                    initFX(fxPanel);
                }
           });


        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    } 
    static FxVisualizerScene fxScene;
    private static void initFX(JFXPanel fxPanel) {
        // This method is invoked on the JavaFX thread
        fxScene = new FxVisualizerScene();

        fxPanel.setScene(fxScene.getScene());
    }

    final List <Event> bufferedEvents = new ArrayList<Event>();
    @Override
    public void add(SampleResult result) 
    {


        final List <Event> events = ...;//here you need to take the result.getSubResults() parameter and get all the children events.
        final List<Event> eventsToAdd = new ArrayList<Event>();

        synchronized(bufferedEvents)
        {
            for (Event evt : events)
            {
                bufferedEvents.add(evt);
            }


            if (bufferedEvents.size() >= BUFFER_SIZE)
            {
                eventsToAdd.addAll(bufferedEvents);
                bufferedEvents.clear();
            }
        }





        if (eventsToAdd.size() > 0)
        {
            Platform.runLater(new Runnable() {
                @Override
                public void run() {
                    updatePanel(eventsToAdd);
                }
           });

        }       


    }



    public void updatePanel(List <Event> events )
    {

        for (Event evt: events)
        {
            fxScene.addEvent(evt);
        }


    }

    @Override
    public void clearData() 
    {
        synchronized(bufferedEvents)
        {
            Platform.runLater(new Runnable() {
                @Override
                public void run() {
                    bufferedEvents.clear();
                    fxScene.clearData();
                }
           });
        }
    }

    @Override
    public String getLabelResource() {

        return "Georges Java Sub FX Sample Listener";
    }

    Boolean isRunning = false;

    @Override
    public void testEnded()
    {


        final List<Event> eventsToAdd = new ArrayList<Event>();

        synchronized(bufferedEvents)
        {
            eventsToAdd.addAll(bufferedEvents);
            bufferedEvents.clear();
        }

        if (eventsToAdd.size() > 0)
        {
            Platform.runLater(new Runnable() {
                @Override
                public void run() {
                    updatePanel(eventsToAdd);
                    fxScene.testStopped();
                }
           });

        }       
    }
    Long testCount = new Long(0);
    @Override
    public void testStarted() {

        synchronized(bufferedEvents)
        {
                Platform.runLater(new Runnable() {
                    @Override
                    public void run() {                     
                        updatePanel(bufferedEvents);
                        bufferedEvents.clear();
                        fxScene.testStarted();
                    }
               });
        }

    }



    @Override
    public void testEnded(String arg0) 
    {
        //LoggingUtil.debug("testEnded 2:" + arg0);
        testEnded();
    }

    int registeredCount = 0;

    @Override
    public void testStarted(String arg0) {
        //LoggingUtil.debug("testStarted 2:" + arg0);
        testStarted();
    }
}

答案 2 :(得分:0)

好的,所以我决定编写自己的jmeter插件,这很简单。我会在完成时分享后代的代码。只需编写一个扩展AbstractVisualizer的类,将其编译成jar,然后将其放入jmeter lib / ext目录。当您添加可视化工具时,该插件将显示在jmeter的侦听器部分中。