Skip to content

Commit

Permalink
Merge pull request #1715 from arunans23/diagnostics
Browse files Browse the repository at this point in the history
Add custom executor and watcher for runtime diagnostic tool
  • Loading branch information
arunans23 committed Jun 14, 2024
2 parents 60de95c + 89dd7d2 commit a5db256
Show file tree
Hide file tree
Showing 6 changed files with 595 additions and 0 deletions.
66 changes: 66 additions & 0 deletions components/mediation-diagnostics/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2024 WSO2 LLC. (http://www.wso2.org) All Rights Reserved.
~
~ 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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.wso2.carbon.mediation</groupId>
<artifactId>carbon-mediation</artifactId>
<version>4.7.207-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>

<artifactId>org.wso2.carbon.mediation.diagnostics</artifactId>
<name>WSO2 Carbon Mediation - Mediation Diagnostics</name>

<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>

<description>
This module is common library module used by both WSO2 MI and WSO2 APIM.
This contains custom Log Watcher and Action Executor implementation related to WSO2 Diagnostic tool.
</description>

<dependencies>
<dependency>
<groupId>org.wso2.runtime.diagnostics</groupId>
<artifactId>runtime-diagnostics-tool</artifactId>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
</plugin>
<plugin>
<groupId>de.jflex</groupId>
<artifactId>maven-jflex-plugin</artifactId>
<version>1.4.3</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<backup>false</backup>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
/*
* Copyright (c) 2024, WSO2 LLC. (http://www.wso2.org).
*
* WSO2 LLC. licenses this file to you 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.wso2.carbon.diagnostics.action.executor;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.wso2.diagnostics.actionexecutor.ActionExecutor;
import org.wso2.diagnostics.actionexecutor.ServerProcess;
import org.wso2.diagnostics.utils.JMXDataRetriever;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import static org.wso2.diagnostics.utils.JMXDataRetriever.getAttributeValue;

public class MetricsSnapshot implements ActionExecutor {
private static final Logger log = LogManager.getLogger(MetricsSnapshot.class);

private final String pid;

public MetricsSnapshot() {
this.pid = ServerProcess.getProcessId();
}

/**
* Method used to take server information.
*
* @param folderPath folder path of the dump folder
*/
@Override
public void execute(String folderPath) {

if (new File(folderPath).exists()) {

String filepath = folderPath + "/metrics-snapshot.txt";
try {
FileWriter writer = new FileWriter(filepath);
writer.write(getServerMetrics());
writer.close();
log.info("MetricsSnapshot executed successfully.");
} catch (IOException e) {
log.error("Unable to do write server information to file.");
}
}
}

/**
* Method used to get server information.
*
* @return server information
*/
public String getServerMetrics() {
String metrics = "";
metrics += "Server Metrics\n";
metrics += "==============\n";
metrics += "Memory Usage: " + JMXDataRetriever.getMemoryUsage(pid) + "%\n";
metrics += "CPU Usage: " + JMXDataRetriever.getCpuUsage(pid) + "%\n";
metrics += "\n";

metrics += "Http Listener Metrics\n";
metrics += "==============\n";
metrics += "Active Connections: " + getAttributeValue("http-listener", pid, "ActiveConnections") + "\n";
metrics += "LastSecondConnections: " + getAttributeValue("http-listener", pid, "LastSecondConnections") + "\n";
metrics += "Last5SecondConnections: " + getAttributeValue("http-listener", pid, "Last5SecondConnections") + "\n";
metrics += "Last15SecondConnections: " + getAttributeValue("http-listener", pid, "Last15SecondConnections") + "\n";
metrics += "LastMinuteConnections: " + getAttributeValue("http-listener", pid, "LastMinuteConnections") + "\n";
metrics += "LastSecondRequests: " + getAttributeValue("http-listener", pid, "LastSecondRequests") + "\n";
metrics += "Last15SecondRequests: " + getAttributeValue("http-listener", pid, "Last15SecondRequests") + "\n";
metrics += "LastMinuteRequests: " + getAttributeValue("http-listener", pid, "LastMinuteRequests") + "\n";

metrics += "\n";
metrics += "Https Listener Metrics\n";
metrics += "==============\n";
metrics += "Active Connections: " + getAttributeValue("https-listener", pid, "ActiveConnections") + "\n";
metrics += "LastSecondConnections: " + getAttributeValue("https-listener", pid, "LastSecondConnections") + "\n";
metrics += "Last5SecondConnections: " + getAttributeValue("https-listener", pid, "Last5SecondConnections") + "\n";
metrics += "Last15SecondConnections: " + getAttributeValue("https-listener", pid, "Last15SecondConnections") + "\n";
metrics += "LastMinuteConnections: " + getAttributeValue("https-listener", pid, "LastMinuteConnections") + "\n";
metrics += "LastSecondRequests: " + getAttributeValue("https-listener", pid, "LastSecondRequests") + "\n";
metrics += "Last15SecondRequests: " + getAttributeValue("https-listener", pid, "Last15SecondRequests") + "\n";
metrics += "LastMinuteRequests: " + getAttributeValue("https-listener", pid, "LastMinuteRequests") + "\n";

metrics += "\n";
metrics += "Http Sender Metrics\n";
metrics += "==============\n";
metrics += "Active Connections: " + getAttributeValue("http-sender", pid, "ActiveConnections") + "\n";
metrics += "LastSecondConnections: " + getAttributeValue("http-sender", pid, "LastSecondConnections") + "\n";
metrics += "Last5SecondConnections: " + getAttributeValue("http-sender", pid, "Last5SecondConnections") + "\n";
metrics += "Last15SecondConnections: " + getAttributeValue("http-sender", pid, "Last15SecondConnections") + "\n";
metrics += "LastMinuteConnections: " + getAttributeValue("http-sender", pid, "LastMinuteConnections") + "\n";
metrics += "LastSecondRequests: " + getAttributeValue("http-sender", pid, "LastSecondRequests") + "\n";
metrics += "Last15SecondRequests: " + getAttributeValue("http-sender", pid, "Last15SecondRequests") + "\n";
metrics += "LastMinuteRequests: " + getAttributeValue("http-sender", pid, "LastMinuteRequests") + "\n";

metrics += "\n";
metrics += "Https Sender Metrics\n";
metrics += "==============\n";
metrics += "Active Connections: " + getAttributeValue("https-sender", pid, "ActiveConnections") + "\n";
metrics += "LastSecondConnections: " + getAttributeValue("https-sender", pid, "LastSecondConnections") + "\n";
metrics += "Last5SecondConnections: " + getAttributeValue("https-sender", pid, "Last5SecondConnections") + "\n";
metrics += "Last15SecondConnections: " + getAttributeValue("https-sender", pid, "Last15SecondConnections") + "\n";
metrics += "LastMinuteConnections: " + getAttributeValue("https-sender", pid, "LastMinuteConnections") + "\n";
metrics += "LastSecondRequests: " + getAttributeValue("https-sender", pid, "LastSecondRequests") + "\n";
metrics += "Last15SecondRequests: " + getAttributeValue("https-sender", pid, "Last15SecondRequests") + "\n";
metrics += "LastMinuteRequests: " + getAttributeValue("https-sender", pid, "LastMinuteRequests") + "\n";
metrics += "\n";

metrics += "Http Listener RequestMap\n";
metrics += "==============\n";
metrics += JMXDataRetriever.getAttributeValue("http-listener", pid, "RequestSizesMap");
metrics += "\n";

metrics += "Http Listener ResponseMap\n";
metrics += "==============\n";
metrics += JMXDataRetriever.getAttributeValue("http-listener", pid, "ResponseSizesMap");
metrics += "\n";

metrics += "Https Listener RequestMap\n";
metrics += "==============\n";
metrics += JMXDataRetriever.getAttributeValue("https-listener", pid, "RequestSizesMap");
metrics += "\n";

metrics += "Https Listener ResponseMap\n";
metrics += "==============\n";
metrics += JMXDataRetriever.getAttributeValue("https-listener", pid, "ResponseSizesMap");
metrics += "\n";

metrics += "Http Sender RequestMap\n";
metrics += "==============\n";
metrics += JMXDataRetriever.getAttributeValue("http-sender", pid, "RequestSizesMap");
metrics += "\n";

metrics += "Http Sender ResponseMap\n";
metrics += "==============\n";
metrics += JMXDataRetriever.getAttributeValue("http-sender", pid, "ResponseSizesMap");
metrics += "\n";

metrics += "Https Sender RequestMap\n";
metrics += "==============\n";
metrics += JMXDataRetriever.getAttributeValue("https-sender", pid, "RequestSizesMap");
metrics += "\n";

metrics += "Https Sender ResponseMap\n";
metrics += "==============\n";
metrics += JMXDataRetriever.getAttributeValue("https-sender", pid, "ResponseSizesMap");
metrics += "\n";

return metrics;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
/*
* Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com).
*
* WSO2 LLC. licenses this file to you 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.wso2.carbon.diagnostics.trafficanalyzer;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.ArrayList;
import java.util.List;

/**
* This class is responsible for calculating the Simple Moving Average of a given data set.
*/
public class SimpleMovingAverage {

private final Logger log = LogManager.getLogger(SimpleMovingAverage.class);

private final int windowSize;
private double ma; // Exponential Moving Average

private double currentThreshold;
private final List<Integer> tempList;

public SimpleMovingAverage(int windowSize) {

this.windowSize = windowSize;
this.ma = Double.NaN;
this.currentThreshold = Double.NaN;
this.tempList = new ArrayList<>();
}

public double update(int newDataPoint) {

if (log.isDebugEnabled()) {
log.debug("Updating Simple Moving Average with new data point: " + newDataPoint);
}
addDataToList(newDataPoint);
List<Integer> tempList = getTempList();
Double ma = findAverage(tempList);
setMa(ma);
return ma;
}

private double findAverage(List<Integer> list) {

int sum = 0;
for (int i : list) {
sum += i;
}
double average = (double) sum / list.size();
if (log.isDebugEnabled()) {
log.debug("Simple Moving Average: " + average);
}
return average;
}

public void addDataToList(int newData) {

updateThresholdStd();
if (tempList.size() < windowSize) {
tempList.add(newData);
} else {
tempList.remove(0);
tempList.add(newData);
}
}

// Update the threshold using the standard deviation
private void updateThresholdStd() {

double sumSquaredDiff = 0.0;
double k = 2;
for (int value : tempList) {
double diff = value - ma;
sumSquaredDiff += diff * diff;
}
double std = Math.sqrt(sumSquaredDiff / tempList.size());
currentThreshold = ma + k * std;
if (log.isDebugEnabled()) {
log.debug("Updating Moving Average Threshold: " + currentThreshold);
}
}

public List<Integer> getTempList() {

return tempList;
}


public void setMa(double ma) {

this.ma = ma;
}

public double getCurrentThreshold() {

return currentThreshold;
}
}
Loading

0 comments on commit a5db256

Please sign in to comment.