diff --git a/components/mediation-diagnostics/pom.xml b/components/mediation-diagnostics/pom.xml
new file mode 100644
index 0000000000..83e0208520
--- /dev/null
+++ b/components/mediation-diagnostics/pom.xml
@@ -0,0 +1,66 @@
+
+
+
+
+ org.wso2.carbon.mediation
+ carbon-mediation
+ 4.7.207-SNAPSHOT
+ ../../pom.xml
+
+
+ org.wso2.carbon.mediation.diagnostics
+ WSO2 Carbon Mediation - Mediation Diagnostics
+
+ 4.0.0
+ jar
+
+
+ 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.
+
+
+
+
+ org.wso2.runtime.diagnostics
+ runtime-diagnostics-tool
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ de.jflex
+ maven-jflex-plugin
+ 1.4.3
+
+
+
+ generate
+
+
+ false
+
+
+
+
+
+
+
diff --git a/components/mediation-diagnostics/src/main/java/org/wso2/carbon/diagnostics/action/executor/MetricsSnapshot.java b/components/mediation-diagnostics/src/main/java/org/wso2/carbon/diagnostics/action/executor/MetricsSnapshot.java
new file mode 100644
index 0000000000..4102585c6b
--- /dev/null
+++ b/components/mediation-diagnostics/src/main/java/org/wso2/carbon/diagnostics/action/executor/MetricsSnapshot.java
@@ -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;
+ }
+}
diff --git a/components/mediation-diagnostics/src/main/java/org/wso2/carbon/diagnostics/trafficanalyzer/SimpleMovingAverage.java b/components/mediation-diagnostics/src/main/java/org/wso2/carbon/diagnostics/trafficanalyzer/SimpleMovingAverage.java
new file mode 100644
index 0000000000..f27fa43027
--- /dev/null
+++ b/components/mediation-diagnostics/src/main/java/org/wso2/carbon/diagnostics/trafficanalyzer/SimpleMovingAverage.java
@@ -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 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 tempList = getTempList();
+ Double ma = findAverage(tempList);
+ setMa(ma);
+ return ma;
+ }
+
+ private double findAverage(List 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 getTempList() {
+
+ return tempList;
+ }
+
+
+ public void setMa(double ma) {
+
+ this.ma = ma;
+ }
+
+ public double getCurrentThreshold() {
+
+ return currentThreshold;
+ }
+}
diff --git a/components/mediation-diagnostics/src/main/java/org/wso2/carbon/diagnostics/trafficanalyzer/TrafficAnalyzer.java b/components/mediation-diagnostics/src/main/java/org/wso2/carbon/diagnostics/trafficanalyzer/TrafficAnalyzer.java
new file mode 100644
index 0000000000..3c876def40
--- /dev/null
+++ b/components/mediation-diagnostics/src/main/java/org/wso2/carbon/diagnostics/trafficanalyzer/TrafficAnalyzer.java
@@ -0,0 +1,111 @@
+/*
+ * 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 org.wso2.diagnostics.actionexecutor.ServerProcess;
+import org.wso2.diagnostics.watchers.Watcher;
+
+import java.util.Map;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+
+import static org.wso2.diagnostics.utils.CommonUtils.getBooleanValue;
+import static org.wso2.diagnostics.utils.CommonUtils.getIntegerValue;
+
+import static org.wso2.diagnostics.utils.Constants.LAST_SECOND_REQUESTS_ENABLED;
+import static org.wso2.diagnostics.utils.Constants.LAST_SECOND_REQUESTS_WINDOW_SIZE;
+import static org.wso2.diagnostics.utils.Constants.LAST_SECOND_REQUESTS_INTERVAL;
+import static org.wso2.diagnostics.utils.Constants.LAST_SECOND_REQUESTS_DELAY;
+import static org.wso2.diagnostics.utils.Constants.LAST_FIFTEEN_SECONDS_REQUESTS_ENABLED;
+import static org.wso2.diagnostics.utils.Constants.LAST_FIFTEEN_SECONDS_REQUESTS_WINDOW_SIZE;
+import static org.wso2.diagnostics.utils.Constants.LAST_FIFTEEN_SECONDS_REQUESTS_INTERVAL;
+import static org.wso2.diagnostics.utils.Constants.LAST_FIFTEEN_SECONDS_REQUESTS_DELAY;
+import static org.wso2.diagnostics.utils.Constants.LAST_MINUTE_REQUESTS_ENABLED;
+import static org.wso2.diagnostics.utils.Constants.LAST_MINUTE_REQUESTS_WINDOW_SIZE;
+import static org.wso2.diagnostics.utils.Constants.LAST_MINUTE_REQUESTS_INTERVAL;
+import static org.wso2.diagnostics.utils.Constants.LAST_MINUTE_REQUESTS_DELAY;
+import static org.wso2.diagnostics.utils.Constants.WATCHER_INITIAL_DELAY;
+
+/**
+ * This class is responsible for initialing TrafficAnalyzerRunnable threads.
+ */
+public class TrafficAnalyzer implements Watcher {
+
+ private final Logger log = LogManager.getLogger(TrafficAnalyzer.class);
+
+ ScheduledExecutorService globalExecutorService;
+ Map configMap;
+
+ public void init(Map configMap) {
+
+ this.globalExecutorService = Executors.newSingleThreadScheduledExecutor();
+ this.configMap = configMap;
+ }
+
+ public void start() {
+
+ boolean isLastSecondRequestsEnabled = getBooleanValue(configMap.get(LAST_SECOND_REQUESTS_ENABLED), false);
+ if (isLastSecondRequestsEnabled) {
+ int lastSecondRequestsWindowSize = getIntegerValue(configMap.get(LAST_SECOND_REQUESTS_WINDOW_SIZE), 300);
+ int lastSecondRequestsInterval = getIntegerValue(configMap.get(LAST_SECOND_REQUESTS_INTERVAL), 1);
+ int lastSecondRequestsDelay = getIntegerValue(configMap.get(LAST_SECOND_REQUESTS_DELAY), 60);
+ TrafficAnalyzerRunnable lastSecondRequests = new TrafficAnalyzerRunnable(ServerProcess.getProcessId(),
+ lastSecondRequestsWindowSize, lastSecondRequestsDelay, "LastSecondRequests");
+ globalExecutorService.scheduleAtFixedRate(lastSecondRequests, WATCHER_INITIAL_DELAY,
+ lastSecondRequestsInterval, java.util.concurrent.TimeUnit.SECONDS);
+ log.info("LastSecondRequests Traffic Analyzer is enabled with window size: " + lastSecondRequestsWindowSize +
+ ", interval: " + lastSecondRequestsInterval + ", delay: " + lastSecondRequestsDelay);
+ }
+
+ boolean isLastFifteenSecondsRequestsEnabled =
+ getBooleanValue(configMap.get(LAST_FIFTEEN_SECONDS_REQUESTS_ENABLED), false);
+ if (isLastFifteenSecondsRequestsEnabled) {
+ int lastFifteenSecondsRequestsWindowSize =
+ getIntegerValue(configMap.get(LAST_FIFTEEN_SECONDS_REQUESTS_WINDOW_SIZE), 100);
+ int lastFifteenSecondsRequestsInterval =
+ getIntegerValue(configMap.get(LAST_FIFTEEN_SECONDS_REQUESTS_INTERVAL), 15);
+ int lastFifteenSecondsRequestsDelay =
+ getIntegerValue(configMap.get(LAST_FIFTEEN_SECONDS_REQUESTS_DELAY), 4);
+ TrafficAnalyzerRunnable
+ lastFifteenSecondsRequests = new TrafficAnalyzerRunnable(ServerProcess.getProcessId(),
+ lastFifteenSecondsRequestsWindowSize, lastFifteenSecondsRequestsDelay, "Last15SecondRequests");
+ globalExecutorService.scheduleAtFixedRate(lastFifteenSecondsRequests, WATCHER_INITIAL_DELAY,
+ lastFifteenSecondsRequestsInterval, java.util.concurrent.TimeUnit.SECONDS);
+ log.info("LastFifteenSecondsRequests Traffic Analyzer is enabled with window size: " +
+ lastFifteenSecondsRequestsWindowSize + ", interval: " + lastFifteenSecondsRequestsInterval +
+ ", delay: " + lastFifteenSecondsRequestsDelay);
+ }
+
+ boolean isLastMinuteRequestsEnabled = getBooleanValue(configMap.get(LAST_MINUTE_REQUESTS_ENABLED), false);
+ if (isLastMinuteRequestsEnabled) {
+ int lastMinuteRequestsWindowSize = getIntegerValue(configMap.get(LAST_MINUTE_REQUESTS_WINDOW_SIZE), 100);
+ int lastMinuteRequestsInterval = getIntegerValue(configMap.get(LAST_MINUTE_REQUESTS_INTERVAL), 60);
+ int lastMinuteRequestsDelay = getIntegerValue(configMap.get(LAST_MINUTE_REQUESTS_DELAY), 1);
+ TrafficAnalyzerRunnable lastMinuteRequests = new TrafficAnalyzerRunnable(ServerProcess.getProcessId(),
+ lastMinuteRequestsWindowSize, lastMinuteRequestsDelay, "LastMinuteRequests");
+ globalExecutorService.scheduleAtFixedRate(lastMinuteRequests, WATCHER_INITIAL_DELAY,
+ lastMinuteRequestsInterval, java.util.concurrent.TimeUnit.SECONDS);
+ log.info("LastMinuteRequests Traffic Analyzer is enabled with window size: " +
+ lastMinuteRequestsWindowSize + ", interval: " + lastMinuteRequestsInterval +
+ ", delay: " + lastMinuteRequestsDelay);
+ }
+ }
+}
diff --git a/components/mediation-diagnostics/src/main/java/org/wso2/carbon/diagnostics/trafficanalyzer/TrafficAnalyzerRunnable.java b/components/mediation-diagnostics/src/main/java/org/wso2/carbon/diagnostics/trafficanalyzer/TrafficAnalyzerRunnable.java
new file mode 100644
index 0000000000..7b298abccf
--- /dev/null
+++ b/components/mediation-diagnostics/src/main/java/org/wso2/carbon/diagnostics/trafficanalyzer/TrafficAnalyzerRunnable.java
@@ -0,0 +1,129 @@
+/*
+ * 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 org.wso2.diagnostics.utils.ConfigMapHolder;
+import org.wso2.diagnostics.utils.Constants;
+import org.wso2.diagnostics.utils.JMXDataRetriever;
+
+import java.time.Duration;
+import java.time.Instant;
+
+/**
+ * This class is responsible for analyzing the traffic of the server.
+ */
+public class TrafficAnalyzerRunnable implements Runnable {
+
+ private static final Logger log = LogManager.getLogger(TrafficAnalyzerRunnable.class);
+ private final SimpleMovingAverage movingAverage;
+ int httpListenerValue = 0;
+ int httpSenderValue = 0;
+ int httpsListenerValue = 0;
+ int httpsSenderValue = 0;
+ String pid;
+ String attribute;
+ int delay;
+ int delayCounter;
+ private static Instant lastNotification;
+
+ public TrafficAnalyzerRunnable(String pid, int windowSize, int delay, String attribute) {
+
+ this.attribute = attribute;
+ this.pid = pid;
+ movingAverage = new SimpleMovingAverage(windowSize);
+ this.delay = delay;
+ delayCounter = 0;
+ }
+
+ public void run() {
+ if (log.isDebugEnabled()) {
+ log.debug("Traffic analyzer thread executing for pid: " + pid + ", attribute: " + attribute +
+ ", delay: " + delay + ", delay counter: " + delayCounter + ", last notification: " + lastNotification);
+ }
+ int newHttpListenerAttributeValue = JMXDataRetriever.getIntAttributeValue("http-listener", pid, attribute);
+ needToAlert(httpListenerValue, newHttpListenerAttributeValue, "http-listener");
+ httpListenerValue = newHttpListenerAttributeValue;
+
+ int newHttpsListenerAttributeValue = JMXDataRetriever.getIntAttributeValue("https-listener", pid, attribute);
+ needToAlert(httpsListenerValue, newHttpsListenerAttributeValue, "https-listener");
+ httpsListenerValue = newHttpsListenerAttributeValue;
+
+ int newHttpSenderAttributeValue = JMXDataRetriever.getIntAttributeValue("http-sender", pid, attribute);
+ needToAlert(httpSenderValue, newHttpSenderAttributeValue, "http-sender");
+ httpSenderValue = newHttpSenderAttributeValue;
+
+ int newHttpsSenderAttributeValue = JMXDataRetriever.getIntAttributeValue("https-sender", pid, attribute);
+ needToAlert(httpsSenderValue, newHttpsSenderAttributeValue, "https-sender");
+ httpsSenderValue = newHttpsSenderAttributeValue;
+
+ }
+
+ private void needToAlert(int oldValue, int newValue, String type) {
+
+ if (log.isDebugEnabled()) {
+ log.debug("Checking if need to alert for attribute: " + attribute + ", type: " + type +
+ ", current Threshold: " + movingAverage.getCurrentThreshold() + ", new value: " + newValue);
+ }
+ boolean doNotify = true;
+ int notifyInterval = Integer.parseInt(
+ (String) ConfigMapHolder.getInstance().getConfigMap().get(Constants.TRAFFIC_NOTIFY_INTERVAL));
+ if (lastNotification != null) {
+ Duration duration = Duration.between(lastNotification, Instant.now());
+ if (duration.getSeconds() < notifyInterval) {
+ doNotify = false;
+ }
+ }
+ if (this.detectAnomalies(newValue) && doNotify) {
+ lastNotification = Instant.now();
+ log.info("Attribute " + attribute + " of type " + type + " increased more than the threshold, old value: " +
+ oldValue + ", new value: " + newValue + ", threshold: " + movingAverage.getCurrentThreshold());
+ }
+ }
+
+ // Update EMAs for each time frame
+ public void update(int newDataPoint) {
+
+ movingAverage.update(newDataPoint);
+ }
+
+ public Double getThreshold() {
+
+ return movingAverage.getCurrentThreshold();
+ }
+
+ public Boolean detectAnomalies(int newData) {
+
+ if (newData <= 0) {
+ return Boolean.FALSE;
+ }
+ this.update(newData);
+ Double threshold = getThreshold();
+ boolean isAnomaly = newData > threshold;
+ if (isAnomaly & delayCounter == 0) {
+ delayCounter = delay;
+ return Boolean.TRUE;
+ }
+ if (delayCounter != 0) {
+ delayCounter -= 1;
+ }
+ return Boolean.FALSE;
+ }
+}
diff --git a/pom.xml b/pom.xml
index a54ee7e6bb..92736f530f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -46,6 +46,7 @@
components/mediation-initializer
components/mediation-monitor
components/mediation-config-admin
+ components/mediation-diagnostics
components/business-adaptors
components/mediation-admin
components/mediation-connector
@@ -2472,6 +2473,11 @@
bsf-all
${bsf.version}
+
+ org.wso2.runtime.diagnostics
+ runtime-diagnostics-tool
+ ${runtime.diagnostics.version}
+
@@ -2665,6 +2671,7 @@
2.1.18.wso2v1
6.3.50
+ 1.1.0