Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.github.johrstrom</groupId>
<artifactId>jmeter-prometheus-plugin</artifactId>
<version>0.7.2-SNAPSHOT</version>
<version>0.7.3-SNAPSHOT</version>
<name>Jmeter-Prometheus Listener Plugin</name>
<description>A Jmeter plugin that creates a Prometheus endpoint of results.</description>
<url>https://github.com/johrstrom/jmeter-prometheus-plugin</url>
Expand Down Expand Up @@ -104,6 +104,11 @@
<artifactId>simpleclient_hotspot</artifactId>
<version>${prometheus.version}</version>
</dependency>
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient_pushgateway</artifactId>
<version>${prometheus.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,10 @@
import org.slf4j.LoggerFactory;

import java.io.Serializable;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
* The main test element listener class of this library. Jmeter updates this
Expand All @@ -55,6 +57,8 @@ public class PrometheusListener extends CollectorElement<ListenerCollectorConfig

private transient PrometheusServer server = PrometheusServer.getInstance();

private PushGateway pushGateway;

private List<AbstractUpdater> updaters;

/*
Expand Down Expand Up @@ -104,6 +108,7 @@ public void sampleStopped(SampleEvent arg0) {
@Override
public void testEnded() {
try {
this.destroyPushGateway();
this.server.stop();
} catch (Exception e) {
log.error("Couldn't stop http server", e);
Expand All @@ -123,6 +128,29 @@ public void testEnded(String arg0) {
this.testEnded();
}

private void destroyPushGateway() {
if (Objects.nonNull(this.pushGateway)) {
this.pushGateway.finish();
}
}

private void configurePushGateway() {
boolean sendToPushGateway = getPropertyAsBoolean("sendToPushGateway", false);
log.info("Envio de métricas ao PushGateway está {}", sendToPushGateway ? "habilitado" : "desabilitado");
if (sendToPushGateway) {
try {
this.pushGateway = new PushGateway(
getPropertyAsString("pushGatewayHost", "http://localhost:9091"),
getPropertyAsString("jobName", "jmeter"),
getPropertyAsInt("interval", 30)
);
this.pushGateway.start();
} catch (MalformedURLException e) {
log.error("Erro ao configurar PushGateway", e);
}
}
}

/*
* (non-Javadoc)
*
Expand All @@ -144,6 +172,7 @@ public void testStarted() {
log.error("Couldn't start http server", e);
}

this.configurePushGateway();
}

/*
Expand Down
55 changes: 55 additions & 0 deletions src/main/java/com/github/johrstrom/listener/PushGateway.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package com.github.johrstrom.listener;

import com.github.johrstrom.collector.JMeterCollectorRegistry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.time.LocalDateTime;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class PushGateway {

private static final Logger log = LoggerFactory.getLogger(PushGateway.class);

private final io.prometheus.client.exporter.PushGateway pg;
private final String jobName;
private final int interval;
private final ScheduledExecutorService scheduler;

public PushGateway(String hostName, String jobName, int interval) throws MalformedURLException {
log.info("Configurando PushGateway: Host={}, JobName={}", hostName, jobName);

URL url = new URL(hostName);
pg = new io.prometheus.client.exporter.PushGateway(url);
scheduler = Executors.newScheduledThreadPool(1);
this.jobName = jobName;
this.interval = interval;
}

public void start() {
log.info("Iniciando processo que envia métricas ao PushGateway em um intervalo de {} segundos", interval);
scheduler.scheduleAtFixedRate(this::send, 0, this.interval, TimeUnit.SECONDS);
}

private void send() {
try {
log.debug("Enviando as métricas para o PushGateway - {}", LocalDateTime.now());
pg.pushAdd(JMeterCollectorRegistry.getInstance(), jobName);
log.debug("Métricas enviadas para o PushGateway");
} catch (IOException e) {
log.error("Erro ao enviar as métricas para o PushGateway", e);
}
}

public void finish() {
this.send();
log.info("Finalizando processo que envia métricas ao PushGateway");
this.scheduler.shutdown();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
Expand All @@ -49,6 +50,11 @@ public class PrometheusListenerGui extends AbstractListenerGui {
private ListenerCollectorTable table = new ListenerCollectorTable();
private Logger log = LoggerFactory.getLogger(PrometheusListenerGui.class);

private JCheckBox sendToPushGatewayCheckBox;
private JTextField jobNameField;
private JTextField pushGatewayHostField;
private JTextField intervalField;

public PrometheusListenerGui() {
super();
log.debug("making a new listener gui: {}", this.toString());
Expand Down Expand Up @@ -106,26 +112,111 @@ public void configure(TestElement ele) {
//ele.getName() == null ? this.setName(ele.getName()) : this.setName(getStaticLabel());;
this.setName(ele.getName() == null ? getStaticLabel() : ele.getName());
this.setComment(ele.getComment() == null ? "" : ele.getComment());


String jobName = ele.getPropertyAsString("jobName");
String pushGatewayHost = ele.getPropertyAsString("pushGatewayHost");
String interval = ele.getPropertyAsString("interval");
String sendToPushGateway = ele.getPropertyAsString("sendToPushGateway");

sendToPushGatewayCheckBox.setSelected("true".equals(sendToPushGateway));
jobNameField.setText(jobName);
pushGatewayHostField.setText(pushGatewayHost);
intervalField.setText(interval);
updatePushGatewayFieldsState();
}

@Override
public TestElement createTestElement() {
PrometheusListener listener = new PrometheusListener();

setPushGatewayProperties(listener);

listener.setProperty(TestElement.GUI_CLASS, PrometheusListenerGui.class.getName());
listener.setProperty(TestElement.TEST_CLASS, PrometheusListener.class.getName());
this.modifyTestElement(listener);
listener.setCollectorConfigs(defaultCollectors());
return listener;
}

private void init() {
this.setLayout(new BorderLayout(0, 5));
this.add(makeTitlePanel(), BorderLayout.NORTH);
this.add(this.table, BorderLayout.CENTER);
}
private void init() {
this.setLayout(new BorderLayout(0, 10)); // Aumentei o espaçamento vertical
this.add(makeTitlePanel(), BorderLayout.NORTH);

@Override
sendToPushGatewayCheckBox = new JCheckBox("Enviar para Pushgateway?");
sendToPushGatewayCheckBox.addActionListener(e -> updatePushGatewayFieldsState());

jobNameField = new JTextField(20);
pushGatewayHostField = new JTextField(20);
intervalField = new JTextField(10);

JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));

JPanel pushGatewayPanel = new JPanel();
pushGatewayPanel.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(5, 5, 5, 5);

gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 2;
gbc.anchor = GridBagConstraints.WEST;
pushGatewayPanel.add(sendToPushGatewayCheckBox, gbc);

gbc.gridwidth = 1;

gbc.gridx = 0;
gbc.gridy = 1;
gbc.anchor = GridBagConstraints.WEST;
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 0;
pushGatewayPanel.add(new JLabel("Job Name:"), gbc);

gbc.gridx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0;
pushGatewayPanel.add(jobNameField, gbc);

gbc.gridx = 0;
gbc.gridy = 2;
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 0;
pushGatewayPanel.add(new JLabel("Pushgateway Host:"), gbc);

gbc.gridx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0;
pushGatewayPanel.add(pushGatewayHostField, gbc);

gbc.gridx = 0;
gbc.gridy = 3;
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 0;
pushGatewayPanel.add(new JLabel("Interval (em segundos):"), gbc);

gbc.gridx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0;
pushGatewayPanel.add(intervalField, gbc);

mainPanel.add(pushGatewayPanel);
mainPanel.add(new JScrollPane(table));

add(mainPanel, BorderLayout.CENTER);

updatePushGatewayFieldsState();
}


private void updatePushGatewayFieldsState() {
boolean isEnabled = sendToPushGatewayCheckBox.isSelected();
jobNameField.setEnabled(isEnabled);
pushGatewayHostField.setEnabled(isEnabled);
intervalField.setEnabled(isEnabled);
}

@Override
public void modifyTestElement(TestElement ele) {
if (!(ele instanceof CollectorElement)) {
return;
Expand All @@ -138,12 +229,33 @@ public void modifyTestElement(TestElement ele) {

config.setName(this.getName());
config.setComment(this.getComment());
}

@Override
setPushGatewayProperties(ele);
}

private void setPushGatewayProperties(TestElement ele) {
ele.setProperty("sendToPushGateway", sendToPushGatewayCheckBox.isSelected());
if (sendToPushGatewayCheckBox.isSelected()) {
ele.setProperty("jobName", jobNameField.getText());
ele.setProperty("pushGatewayHost", pushGatewayHostField.getText());
ele.setProperty("interval", intervalField.getText());
} else {
ele.setProperty("jobName", "");
ele.setProperty("pushGatewayHost", "");
ele.setProperty("interval", "");
}
}

@Override
public void clearGui() {
super.clearGui();
this.table.clearModelData();

jobNameField.setText("");
pushGatewayHostField.setText("");
intervalField.setText("");
sendToPushGatewayCheckBox.setSelected(false);
updatePushGatewayFieldsState();
}


Expand Down