Skip to content

Commit

Permalink
initial impl for business analytics for prometheus metrics
Browse files Browse the repository at this point in the history
  • Loading branch information
CrowleyRajapakse committed Jul 18, 2024
1 parent d9749db commit 8f84267
Show file tree
Hide file tree
Showing 19 changed files with 1,340 additions and 40 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* 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.
*/

package org.wso2.apk.enforcer.analytics.publisher.jmx;

/**
* JMX Utilities
*/
public class JMXUtils {

private static final String APK_JMX_METRICS_ENABLE = "apk.jmx.metrics.enabled";

/**
* Returns true if jmx metrics enabled as a system property, otherwise false.
*
* @return boolean
*/
public static boolean isJMXMetricsEnabled() {
return Boolean.getBoolean(APK_JMX_METRICS_ENABLE);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* 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.
*/
package org.wso2.apk.enforcer.analytics.publisher.jmx;

import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;

/**
* The ManagementFactory class is a factory class for getting managed beans for
* the Enforcer.
*/
public class MBeanManagementFactory {

/*
* If one already exists, it will return that else it will create a new one and
* return.
*
* @return A MBeanServer instance.
*/
public static MBeanServer getMBeanServer() {
MBeanServer mBeanServer;
if (MBeanServerFactory.findMBeanServer(null).size() > 0) {
mBeanServer = MBeanServerFactory.findMBeanServer(null).get(0);
} else {
mBeanServer = MBeanServerFactory.createMBeanServer();
}
return mBeanServer;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
/*
* Copyright (c) 2022, 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.
*/
package org.wso2.apk.enforcer.analytics.publisher.jmx;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.apk.enforcer.analytics.publisher.jmx.impl.ExtAuthMetrics;
import org.wso2.apk.enforcer.analytics.publisher.reporter.prometheus.APIInvocationEvent;

import javax.management.*;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
* The class which is responsible for registering MBeans.
*/
public class MBeanRegistrator {
private static final Log logger = LogFactory.getLog(MBeanRegistrator.class);
private static List<ObjectName> mBeans = new ArrayList<>();

private static final String SERVER_PACKAGE = "org.wso2.apk.enforcer.analytics";

private MBeanRegistrator() {
}

/**
* Registers an object as an MBean with the MBean server.
*
* @param mBeanInstance - The MBean to be registered as an MBean.
*/
public static void registerMBean(Object mBeanInstance, APIInvocationEvent event) throws RuntimeException, UnsupportedEncodingException {

if (JMXUtils.isJMXMetricsEnabled()) {
String className = mBeanInstance.getClass().getName();
if (className.indexOf('.') != -1) {
className = className.substring(className.lastIndexOf('.') + 1);
}

ExtAuthMetrics extAuthMetrics = (ExtAuthMetrics) mBeanInstance;
logger.info("extAuthMetrics Object data: " + extAuthMetrics.toString());
//logger.info("extAuthMetrics Object api name: " + extAuthMetrics.getApiName());

String objectName = String.format(
"%s:type=%s,apiName=%s,apiContext=%s,proxyResponseCode=%d," +
"destination=%s,apiCreatorTenantDomain=%s,platform=%s," +
"organizationId=%s,apiMethod=%s,apiVersion=%s,environmentId=%s," +
"gatewayType=%s,apiCreator=%s,responseCacheHit=%b,backendLatency=%d," +
"correlationId=%s,requestMediationLatency=%d,keyType=%s,apiId=%s," +
"applicationName=%s,targetResponseCode=%d,applicationOwner=%s," +
"userAgent=%s,userName=%s,apiResourceTemplate=%s,regionId=%s,responseLatency=%d," +
"responseMediationLatency=%d,userIp=%s,applicationId=%s,apiType=%s,xOriginalGwUrl=%s",
SERVER_PACKAGE,
className,
event.getApiName(),
event.getApiContext(),
event.getProxyResponseCode(),
URLEncoder.encode(event.getDestination(), StandardCharsets.UTF_8.toString()),
event.getApiCreatorTenantDomain(),
event.getPlatform(),
event.getOrganizationId(),
event.getApiMethod(),
event.getApiVersion(),
event.getEnvironmentId(),
event.getGatewayType(),
event.getApiCreator(),
event.isResponseCacheHit(),
event.getBackendLatency(),
event.getCorrelationId(),
event.getRequestMediationLatency(),
event.getKeyType(),
event.getApiId(),
"Resident Key Manager",
event.getTargetResponseCode(),
event.getApplicationOwner(),
event.getUserAgent(),
event.getUserName(),
event.getApiResourceTemplate(),
event.getRegionId(),
event.getResponseLatency(),
event.getResponseMediationLatency(),
event.getUserIp(),
event.getApplicationId(),
event.getApiType(),
URLEncoder.encode(event.getProperties().get("x-original-gw-url"), StandardCharsets.UTF_8.toString())
);
logger.info("Registering MBean with object name: " + objectName);
try {
MBeanServer mBeanServer = MBeanManagementFactory.getMBeanServer();
Set set = mBeanServer.queryNames(new ObjectName(objectName), null);
if (set.isEmpty()) {
try {
ObjectName name = new ObjectName(objectName);
mBeanServer.registerMBean(mBeanInstance, name);
mBeans.add(name);
logger.info("MBean registered successfully with object name: " + name);
logger.info("Mbeans: " + mBeans);
} catch (InstanceAlreadyExistsException e) {
String msg = "MBean " + objectName + " already exists";
logger.error(msg, e);
throw new RuntimeException(msg, e);
} catch (MBeanRegistrationException | NotCompliantMBeanException e) {
String msg = "Execption when registering MBean";
logger.error(msg, e);
throw new RuntimeException(msg, e);
}
} else {
String msg = "MBean " + objectName + " already exists";
logger.error(msg);
throw new RuntimeException(msg);
}
} catch (MalformedObjectNameException e) {
String msg = "Could not register " + mBeanInstance.getClass() + " MBean";
logger.error(msg, e);
throw new RuntimeException(msg, e);
}
} else {
logger.debug("JMX Metrics should be enabled to register MBean instance: {}");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*
* 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.
*/

package org.wso2.apk.enforcer.analytics.publisher.jmx.api;

/**
* MBean API for ExtAuth Service metrics.
*/
public interface ExtAuthMetricsMXBean {

/**
* Getter for total request count.
*
* @return long
*/
public long getTotalRequestCount();

/**
* Getter for average response time in milli seconds.
*
* @return double
*/
public double getAverageResponseTimeMillis();

/**
* Getter for maximum response time in milliseconds.
*
* @return double
*/
public double getMaxResponseTimeMillis();

/**
* Getter for mimnimum response time in milliseconds.
*
* @return double
*/
public double getMinResponseTimeMillis();

/**
* Resets all the metrics to their initial values.
*/
public void resetExtAuthMetrics();

/**
* Get request count in last five minutes window
*
* @return long
*/
public long getRequestCountInLastFiveMinuteWindow();

/**
* Get the start time of request count window
*
* @return
*/
public long getRequestCountWindowStartTimeMillis();

/**
* Get the number of token issuers
*
* @return
*/
public int getTokenIssuerCount();

/**
* Get the number of subscriptions
*
* @return
*/
public int getSubscriptionCount();

public int getTotalRequests();
public int getPostRequests();
public int getGetRequests();
public String getResourcePaths();
public String getApiName();
public String getApplicationId();
public int getApiMessages();
public int getSuccessRequests();
public int getFailureRequests();

}
Loading

0 comments on commit 8f84267

Please sign in to comment.