diff --git a/rule-based/src/main/java/nl/jads/sodalite/api/RefactoringService.java b/rule-based/src/main/java/nl/jads/sodalite/api/RefactoringService.java index 5bdcb74..3b77603 100644 --- a/rule-based/src/main/java/nl/jads/sodalite/api/RefactoringService.java +++ b/rule-based/src/main/java/nl/jads/sodalite/api/RefactoringService.java @@ -11,7 +11,6 @@ import org.glassfish.jersey.media.multipart.FormDataContentDisposition; import org.glassfish.jersey.media.multipart.FormDataParam; -import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import javax.inject.Singleton; import javax.servlet.ServletContext; @@ -131,13 +130,24 @@ public Response uploadFile( } - @PostConstruct - public void init() { - try { - monitoringDataCollector.start(); - } catch (InterruptedException e) { - e.printStackTrace(); + @POST + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + @Path("/monitoring/pull") + public Response enableDisableMonitoring(@DefaultValue("disabled") @QueryParam("state") String state) { + if ("enabled".equalsIgnoreCase(state)) { + try { + monitoringDataCollector.start(); + return Response.status(200).entity("Monitoring Enabled").build(); + } catch (InterruptedException e) { + e.printStackTrace(); + return Response.status(500).entity(e.getMessage()).build(); + } + } else { + monitoringDataCollector.shutdown(); + return Response.status(200).entity("Monitoring Disabled/Stopped").build(); } + } @PreDestroy diff --git a/rule-based/src/main/java/nl/jads/sodalite/db/MetricsDatabase.java b/rule-based/src/main/java/nl/jads/sodalite/db/MetricsDatabase.java index b6b5823..fe9b417 100644 --- a/rule-based/src/main/java/nl/jads/sodalite/db/MetricsDatabase.java +++ b/rule-based/src/main/java/nl/jads/sodalite/db/MetricsDatabase.java @@ -1,9 +1,13 @@ package nl.jads.sodalite.db; import nl.jads.sodalite.dto.DataRecord; +import nl.jads.sodalite.dto.MetricRecord; import org.apache.commons.dbcp2.BasicDataSource; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.json.simple.JSONArray; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; import java.sql.Connection; import java.sql.ResultSet; @@ -23,6 +27,7 @@ public class MetricsDatabase { private MetricsDatabase() { createDataSource(); createTable(); + createRawMetricTable(); } private static Connection getConnection() throws SQLException { @@ -77,6 +82,41 @@ private static void createTable() { } } + private static void createRawMetricTable() { + Connection connection = null; + Statement stmt = null; + try { + connection = ds.getConnection(); + stmt = connection.createStatement(); + String sql = "CREATE TABLE IF NOT EXISTS RAWMETRICS " + + "(ID INT PRIMARY KEY NOT NULL," + + " LABEL varchar(255) NOT NULL," + + " METRIC varchar(255) NOT NULL," + + " VAlUETYPE varchar(255), " + + " VALUE TEXT)"; + stmt.executeUpdate(sql); + if (log.isInfoEnabled()) { + log.info("Metrics table was created successfully"); + } + } catch (SQLException e) { + e.printStackTrace(); + log.error(e.getMessage()); + } finally { + if (stmt != null) { + try { + stmt.close(); + } catch (SQLException ignored) { + } + } + if (connection != null) { + try { + connection.close(); + } catch (SQLException ignored) { + } + } + } + } + /** * Adding a monitoring data record * @@ -96,7 +136,42 @@ public void addDataRecord(DataRecord dataRecord) { System.out.println(sql); stmt.executeUpdate(sql); if (log.isInfoEnabled()) { - log.info("Metrics table was created successfully"); + log.info("Add data to the metrics table was created successfully"); + } + } catch (SQLException e) { + e.printStackTrace(); + log.error(e.getMessage()); + } finally { + if (stmt != null) { + try { + stmt.close(); + } catch (SQLException ignored) { + } + } + if (connection != null) { + try { + connection.close(); + } catch (SQLException ignored) { + } + } + } + } + + public void addMetricRecord(MetricRecord metricRecord) { + Connection connection = null; + Statement stmt = null; + try { + connection = ds.getConnection(); + stmt = connection.createStatement(); + String sql = + String.format("INSERT INTO RAWMETRICS (ID, LABEL, METRIC, VALUETYPE, " + + "VALUE) VALUES ( %d,'%s','%s', '%s', '%s');", + System.currentTimeMillis(), metricRecord.getLabel(), metricRecord.getName(), + metricRecord.getValueType(), metricRecord.getValue().toJSONString()); + System.out.println(sql); + stmt.executeUpdate(sql); + if (log.isInfoEnabled()) { + log.info("Add data to the raw metrics table was created successfully"); } } catch (SQLException e) { e.printStackTrace(); @@ -163,4 +238,55 @@ public List getDataRecord(String label) { } return dataRecords; } + + /** + * Get the records of monitoring data per node + * + * @param label the label of a node + * @return a record of monitoring data + */ + public List getMetricRecord(String label) { + List dataRecords = new ArrayList<>(); + Connection connection = null; + Statement stmt = null; + try { + connection = ds.getConnection(); + stmt = connection.createStatement(); + ResultSet rs = + stmt.executeQuery(String.format("SELECT * FROM RAWMETRICS WHERE LABEL='%s';", label)); + + while (rs.next()) { + MetricRecord dataRecord = new MetricRecord(); + dataRecord.setLabel(label); + dataRecord.setLabel(rs.getString("label")); + dataRecord.setName(rs.getString("metric")); + dataRecord.setValueType(rs.getString("valuetype")); + JSONParser parser = new JSONParser(); + try { + dataRecord.setValue((JSONArray) parser.parse(rs.getString("value"))); + } catch (ParseException e) { + e.printStackTrace(); + } + dataRecords.add(dataRecord); + } + rs.close(); + } catch (SQLException e) { + e.printStackTrace(); + log.error(e.getMessage()); + } finally { + if (stmt != null) { + try { + stmt.close(); + } catch (SQLException ignored) { + } + } + if (connection != null) { + try { + connection.close(); + } catch (SQLException ignored) { + } + } + } + return dataRecords; + } } diff --git a/rule-based/src/main/java/nl/jads/sodalite/dto/MetricRecord.java b/rule-based/src/main/java/nl/jads/sodalite/dto/MetricRecord.java new file mode 100644 index 0000000..f7febb2 --- /dev/null +++ b/rule-based/src/main/java/nl/jads/sodalite/dto/MetricRecord.java @@ -0,0 +1,42 @@ +package nl.jads.sodalite.dto; + +import org.json.simple.JSONArray; + +public class MetricRecord { + private String name; + private String valueType; + private JSONArray value; + private String label; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public JSONArray getValue() { + return value; + } + + public void setValue(JSONArray value) { + this.value = value; + } + + public String getValueType() { + return valueType; + } + + public void setValueType(String valueType) { + this.valueType = valueType; + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } +} diff --git a/rule-based/src/main/java/nl/jads/sodalite/scheduler/MonitoringTimerTask.java b/rule-based/src/main/java/nl/jads/sodalite/scheduler/MonitoringTimerTask.java index da66d41..a57fcf0 100644 --- a/rule-based/src/main/java/nl/jads/sodalite/scheduler/MonitoringTimerTask.java +++ b/rule-based/src/main/java/nl/jads/sodalite/scheduler/MonitoringTimerTask.java @@ -1,18 +1,36 @@ package nl.jads.sodalite.scheduler; +import nl.jads.sodalite.db.MetricsDatabase; +import nl.jads.sodalite.dto.MetricRecord; +import nl.jads.sodalite.utils.PrometheusClient; +import org.json.simple.parser.ParseException; + import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneId; +import java.util.List; import java.util.TimerTask; -public class MonitoringTimerTask extends TimerTask { +public class MonitoringTimerTask extends TimerTask { + MetricsDatabase database = MetricsDatabase.getInstance(); + PrometheusClient prometheusClient = new PrometheusClient(); + @Override public void run() { -// System.out.println("Data Collected at: " -// + LocalDateTime.ofInstant(Instant.ofEpochMilli(scheduledExecutionTime()), -// ZoneId.systemDefault())); try { - Thread.sleep(100 * 3); + List metricRecords = + prometheusClient.readMetric("http_requests_total"); + for (MetricRecord mr : metricRecords) { + database.addMetricRecord(mr); + } + } catch (ParseException e) { + e.printStackTrace(); + } + System.out.println("Data Collected at: " + + LocalDateTime.ofInstant(Instant.ofEpochMilli(scheduledExecutionTime()), + ZoneId.systemDefault())); + try { + Thread.sleep(1000 * 60); } catch (InterruptedException e) { e.printStackTrace(); } diff --git a/rule-based/src/main/java/nl/jads/sodalite/utils/PrometheusClient.java b/rule-based/src/main/java/nl/jads/sodalite/utils/PrometheusClient.java new file mode 100644 index 0000000..20405d0 --- /dev/null +++ b/rule-based/src/main/java/nl/jads/sodalite/utils/PrometheusClient.java @@ -0,0 +1,67 @@ +package nl.jads.sodalite.utils; + +import com.sun.jersey.api.json.JSONConfiguration; +import nl.jads.sodalite.dto.MetricRecord; +import org.glassfish.jersey.client.ClientConfig; +import org.glassfish.jersey.client.ClientProperties; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Invocation; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public class PrometheusClient { + private String baseRestUri; + + public PrometheusClient() { + baseRestUri = System.getenv("prometheusrest"); + if (baseRestUri == null || "".equals(baseRestUri.trim())) { + baseRestUri = "http://154.48.185.213:9090/"; + } + } + + public List readMetric(String query) throws ParseException { + ClientConfig config = new ClientConfig(); + config.property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, Boolean.TRUE); + config.property(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE); + Client client = ClientBuilder.newClient(config); + WebTarget webTarget = client.target(baseRestUri).path("api/v1/query").queryParam("query", query); + Invocation.Builder invocationBuilder + = webTarget.request(MediaType.APPLICATION_JSON); + String response + = invocationBuilder.get(String.class); + JSONParser jsonParser = new JSONParser(); + + JSONObject result = (JSONObject) jsonParser.parse(response); + List metricRecords = new ArrayList<>(); + if ("success".equalsIgnoreCase(String.valueOf(result.get("status")))) { + System.out.println("Successful collected data: " + query); + JSONObject dataObject = ((JSONObject) result.get("data")); + String resultType = String.valueOf(dataObject.get("resultType")); + JSONArray jsonArray = (JSONArray) dataObject.get("result"); + for (Iterator it = jsonArray.iterator(); it.hasNext(); ) { + MetricRecord metricRecord = new MetricRecord(); + JSONObject metric = (JSONObject) it.next(); + String mName = String.valueOf(((JSONObject) metric.get("metric")).get("__name__")); + String label = String.valueOf(((JSONObject) metric.get("metric")).get("instance")); + JSONArray mValue = (JSONArray) metric.get("value"); + metricRecord.setValueType(resultType); + metricRecord.setName(mName); + metricRecord.setValue(mValue); + metricRecord.setLabel(label); + metricRecords.add(metricRecord); + } + } else { + System.out.println("Error collecting data: " + query); + } + return metricRecords; + } +} diff --git a/rule-based/src/test/java/Slimclient.java b/rule-based/src/test/java/Slimclient.java index 19b8e97..fb8eea3 100644 --- a/rule-based/src/test/java/Slimclient.java +++ b/rule-based/src/test/java/Slimclient.java @@ -1,6 +1,12 @@ +import nl.jads.sodalite.db.MetricsDatabase; +import nl.jads.sodalite.dto.MetricRecord; +import nl.jads.sodalite.utils.PrometheusClient; +import org.apache.commons.math3.geometry.euclidean.twod.Vector2D; import org.glassfish.jersey.media.multipart.FormDataMultiPart; import org.glassfish.jersey.media.multipart.MultiPartFeature; import org.glassfish.jersey.media.multipart.file.FileDataBodyPart; +import org.json.simple.JSONArray; +import org.json.simple.parser.ParseException; import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; @@ -9,6 +15,7 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.io.File; +import java.util.List; public class Slimclient { private static final String TARGET_URL = "http://154.48.185.206:5000/deploy/a6442450-deb6-4b61-8c95-446bd095b8f0"; @@ -40,6 +47,33 @@ public Slimclient() { } public static void main(String[] args) { - new Slimclient(); +// new Slimclient(); + PrometheusClient prometheusClient = new PrometheusClient(); + try { + List metricRecords = + prometheusClient.readMetric("http_requests_total"); + + for (MetricRecord mr : metricRecords) { + System.out.println(mr.getValueType()); + System.out.println(mr.getLabel()); + System.out.println(mr.getName()); + System.out.println(mr.getValue()); + JSONArray jsonArray = mr.getValue(); + System.out.println(jsonArray.size()); + Vector2D vector2D = new Vector2D(Double.parseDouble(String.valueOf(jsonArray.get(0))), + Double.parseDouble(String.valueOf(jsonArray.get(1)))); + System.out.println(vector2D.toString()); + MetricsDatabase database = MetricsDatabase.getInstance(); + database.addMetricRecord(mr); + MetricRecord record = + database.getMetricRecord(mr.getLabel()).get(0); + System.out.println(record.getValueType()); + System.out.println(record.getLabel()); + System.out.println(record.getName()); + System.out.println(record.getValue()); + } + } catch (ParseException e) { + e.printStackTrace(); + } } }