Hi all,
Is there a way to develop a code to monitor the different servers that we see in the administrative console.
I want to write a bean shell code which checks and sends an email if the usage is beyond 80%.
Thanks in advance
Hi all,
Is there a way to develop a code to monitor the different servers that we see in the administrative console.
I want to write a bean shell code which checks and sends an email if the usage is beyond 80%.
Thanks in advance
If the application is deployed on Unix, it is much easier to implement this at the server level using a simple shell script. The script can be scheduled using crontab to run at regular intervals.
It can monitor server resource usage (CPU, memory, or disk), and if the usage exceeds 80%, it can automatically trigger an email notification to the SailPoint operations team.
if you want to write a rule or task, then you have to see the APi’s. But recommended approach will be to do this at the server-side.
which APIs does sailpoint have if we want to acheive this via Rule?
I am not sure, I have not used it, or worked upon it. generally we do it via server end cron jobs, you will have to explore it. What api available for this.
Just tried and tested this code for you. Use below Code and add your logic.
import sailpoint.api.SailPointContext;
import sailpoint.api.SailPointFactory;
import sailpoint.object.Server;
import java.util.List;
SailPointContext context = SailPointFactory.getCurrentContext();
List servers = context.getObjects(Server.class);
for (Server server : servers) {
return server;
}
Hi @rishavghoshacc - as @naveenkumar3 suggested, probably something better to do at the server level.
If you do need to implement this within IIQ, can use the following code to achieve this using a Run Rule task polling periodically.
double threshold = 80.0;
String templateName = "High CPU Alert";
List recipients = new ArrayList();
Map configMap = Util.otom(config);
if (configMap != null) {
String thresholdText = Util.otos(configMap.get("threshold"));
if (!Util.isNullOrEmpty(thresholdText)) {
threshold = Double.parseDouble(thresholdText);
}
String templateText = Util.otos(configMap.get("templateName"));
if (!Util.isNullOrEmpty(templateText)) {
templateName = templateText;
}
recipients.addAll(Util.otol(configMap.get("recipients")));
}
if (Util.isEmpty(recipients)) {
log.warn("No recipients configured.");
return "Success";
}
EmailTemplate template = context.getObjectByName(EmailTemplate.class, templateName);
if (template == null) {
log.error("Could not find email template: " + templateName);
return "Failure";
}
List serverNames = new ArrayList();
QueryOptions serverQO = new QueryOptions();
serverQO.addOrdering("name", true);
Iterator serverIt = context.search(Server.class, serverQO);
while (serverIt.hasNext()) {
Server server = (Server) serverIt.next();
String serverName = (server == null) ? null : Util.otos(server.getName());
if (!Util.isNullOrEmpty(serverName)) {
serverNames.add(serverName);
}
}
if (Util.isEmpty(serverNames)) {
log.warn("No Server objects found.");
return "Success";
}
List violations = new ArrayList();
StringBuilder violationSummary = new StringBuilder();
int statsFound = 0;
Iterator hostIt = serverNames.iterator();
while (hostIt.hasNext()) {
String hostName = Util.otos(hostIt.next());
if (Util.isNullOrEmpty(hostName)) {
continue;
}
QueryOptions statQO = new QueryOptions();
statQO.addFilter(Filter.eq("monitoringStatistic.name", "cpu"));
statQO.addFilter(Filter.eq("host.name", hostName));
statQO.addOrdering("created", false);
statQO.setResultLimit(1);
Iterator statIt = context.search(ServerStatistic.class, statQO);
if (!statIt.hasNext()) {
continue;
}
ServerStatistic stat = (ServerStatistic) statIt.next();
statsFound++;
String cpuText = Util.otos(stat.getValue());
if (Util.isNullOrEmpty(cpuText)) {
continue;
}
double cpuValue = 0.0;
try {
cpuValue = Double.parseDouble(cpuText);
} catch (Exception e) {
log.warn("Unable to parse CPU value for host " + hostName + ": " + cpuText);
continue;
}
if (cpuValue >= threshold) {
Map violation = new HashMap();
violation.put("hostName", hostName);
violation.put("cpuValue", String.valueOf(cpuValue));
violation.put("collectedAt", stat.getCreated());
violations.add(violation);
violationSummary.append(hostName)
.append(" - ")
.append(cpuValue)
.append("% at ")
.append(stat.getCreated())
.append("\n");
}
}
if (!violations.isEmpty()) {
Map args = new HashMap();
args.put("threshold", String.valueOf(threshold));
args.put("serverCount", String.valueOf(serverNames.size()));
args.put("statCount", String.valueOf(statsFound));
args.put("violationCount", String.valueOf(violations.size()));
args.put("violations", violations);
args.put("violationSummary", violationSummary.toString());
args.put("evaluatedAt", new Date());
EmailTemplate tpl = (EmailTemplate) template.deepCopy(context);
EmailOptions ops = new EmailOptions(recipients, args);
context.sendEmailNotification(tpl, ops);
log.warn("Sent CPU summary alert for " + violations.size() + " host(s).");
} else {
log.debug("No CPU threshold violations found.");
}
if (taskResult != null) {
try {
taskResult.setAttribute("cpuThreshold", String.valueOf(threshold));
taskResult.setAttribute("cpuServerCount", String.valueOf(serverNames.size()));
taskResult.setAttribute("cpuStatsFound", String.valueOf(statsFound));
taskResult.setAttribute("cpuViolationCount", String.valueOf(violations.size()));
taskResult.setAttribute("cpuViolationSummary", violationSummary.toString());
} catch (Exception e) {
log.debug("Unable to update taskResult", e);
}
}
@rishavghoshacc You should not have this kind of server monitoring within IIQ, because if there are some memory issues or server not available then your rule will not run and you will not be alerted.
We had this implemented using monitoring agents running on the servers directly reviewing all the necessary details and emitting real time metrics to a monitoring tool and then enable alerts there: pagerduty or email or sms alerts, etc.
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE Rule PUBLIC "sailpoint.dtd" "sailpoint.dtd">
<Rule language="beanshell" name="Rule-MonitorServerHealth" significantModified="1776831771912">
<Description>.</Description>
<Source>
import sailpoint.tools.GeneralException;
import sailpoint.tools.Util;
import sailpoint.object.EmailTemplate;
import sailpoint.object.EmailOptions;
import sailpoint.object.Server;
import sailpoint.object.QueryOptions;
import sailpoint.object.Filter;
import java.util.Iterator;
try {
List listOfServers = context.getObjects(Server.class);
float cpuThreshold = 8;
float memoryThreshold = 30;
QueryOptions qo = new QueryOptions();
qo.addFilter(Filter.eq("inactive", false));
Iterator itr = context.search(Server.class, qo);
String resultServerStatus = "";
String listOfMisbehavingServers = "";
int flag = 0;
while(itr.hasNext())
{
Server serV = itr.next();
float currentCpuUsage = Float.parseFloat(serV.getAttribute("cpuUsage"));
float currentMemoryUsage = Float.parseFloat(serV.getAttribute("memoryUsagePercentage"));
if((currentCpuUsage>=cpuThreshold) || (currentMemoryUsage>=memoryThreshold))
{
flag = 1;
listOfMisbehavingServers = listOfMisbehavingServers + serV.getName() + ":\n"+"CPU USAGE: "+serV.getAttribute("cpuUsage")+"%\nMEMORY USAGE: "+serV.getAttribute("memoryUsagePercentage")+"%\n";
}
}
} catch (Exception e) {
e.printStackTrace();
throw new GeneralException("Error during create operation: " + e.getMessage(), e);
}
</Source>
</Rule>
I did a DevDays video several years ago with a widget that reports out the same details as the environment monitoring in the Admin console. The code is posted on our public repository.