Commit a24e03a8 authored by Dele Olajide's avatar Dele Olajide

jmxweb plugin - add support for automated and scheduled monitor reports via email

parent d643c5f0
......@@ -42,6 +42,12 @@
<h1>
</h1>
<p><b>0.0.5</b> -- June 20 2016</p>
<ul>
<li>Added support for periodic monitor reports by email</li>
</ul>
<p><b>0.0.4</b> -- May 10 2016</p>
<ul>
......
......@@ -4,9 +4,9 @@
<class>com.ifsoft.jmxweb.plugin.JmxWebPlugin</class>
<name>JmxWeb Plugin</name>
<description>JmxWeb plugin is web based platform for managing and monitoring openfire via JMX.</description>
<version>0.0.4</version>
<version>0.0.5</version>
<licenseType>Apache 2.0</licenseType>
<date>05/10/2016</date>
<date>06/20/2016</date>
<minServerVersion>4.0.1</minServerVersion>
<author>igniterealtime.org</author>
</plugin>
\ No newline at end of file
......@@ -99,6 +99,12 @@ It also includes the mbeans from the java-monitor probe for openfire.
<li>xmpp.jmx.enabled (true or false)</li>
<li>xmpp.jmx.secure (true or false)</li>
</ul>
<p>If you want your admin users to recieve periodic summary emails of JMX, configure Opefire email service and add the following to System Properties via the Web Admin Console.</p>
<ul>
<li>jmxweb.email.monitoring (true or false)</li>
<li>jmxweb.crontrigger.schedule (a <a href="http://www.quartz-scheduler.org/documentation/quartz-2.x/tutorials/tutorial-lesson-06.html">cron-trigger expression</a>. The default setting is "0 0 0/12 * * ?" which means run report daily, twice a day at 12 midnight and 12 noon.)</li>
</ul>
<p><img src="http://community.igniterealtime.org/servlet/JiveServlet/downloadImage/38-1735-33840/Image2.jpg" style="width: 620px; height: 349px;" __jive_id="33840" /></p>
<h2>How to use</h2>
<p><span>To access hawtio, point your browser at </span><a href="http://your-server:7070/hawtio" rel="nofollow" target="_blank">http://your-server:7070/hawtio</a></p>
......
package com.ifsoft.jmxweb.plugin;
import org.jivesoftware.util.*;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.quartz.CronScheduleBuilder.cronSchedule;
import static org.quartz.JobBuilder.newJob;
import static org.quartz.TriggerBuilder.newTrigger;
import org.jivesoftware.openfire.user.UserManager;
import org.jivesoftware.util.EmailService;
import com.ifsoft.jmxweb.plugin.EmailSenderUtility;
public class EmailScheduler implements Job {
private static Logger Log = LoggerFactory.getLogger("JmxWebPlugin:EmailScheduler");
public Scheduler scheduler=null;
public void startMonitoring() {
try {
String schedule = JiveGlobals.getProperty("jmxweb.crontrigger.schedule", "0 0 0/12 * * ?");
scheduler = StdSchedulerFactory.getDefaultScheduler();
scheduler.start();
JobDetail job = newJob(EmailScheduler.class)
.withIdentity("job1", "group1")
.build();
CronTrigger trigger = newTrigger()
.withIdentity("trigger1", "group1")
.withSchedule(cronSchedule(schedule))
.build();
scheduler.scheduleJob(job, trigger);
} catch (SchedulerException se) {
Log.error("EmailScheduler", se);
}
}
public void stopMonitoring() {
try {
Log.info("Email Monitoring Stopped");
scheduler.shutdown(true);
} catch (SchedulerException se) {
Log.error("stopMonitoring", se);
}
}
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
Log.info( "Email Monitoring Running");
try {
/*EmailService.getInstance().sendMessage(user.getName(), user.getEmail(), "Openfire",
"no_reply@" + violationNotificationFrom.getDomain(), subject, body, null);*/
EmailSenderUtility emailSenderUtility = new EmailSenderUtility();
emailSenderUtility.sendEmail();
}
catch (Throwable e) {
Log.error("Failed to send email...", e);
}
}
}
\ No newline at end of file
package com.ifsoft.jmxweb.plugin;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.PdfPTable;
import com.owlike.genson.Genson;
import javax.activation.DataHandler;
import javax.mail.*;
import javax.mail.internet.*;
import javax.mail.util.ByteArrayDataSource;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Date;
import java.security.Security;
import org.jivesoftware.openfire.admin.DefaultAdminProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xmpp.packet.JID;
import org.jivesoftware.openfire.user.User;
import org.jivesoftware.openfire.user.UserManager;
import org.jivesoftware.util.*;
/**
* This class creates a pdf attachment to be sent via email.
* **/
public class EmailSenderUtility{
private static Logger Log = LoggerFactory.getLogger("JmxWebPlugin:EmailSenderUtility");
private static final String SSL_FACTORY = "org.jivesoftware.util.SimpleSSLSocketFactory";
public void sendEmail() {
ByteArrayOutputStream outputStream = null;
try {
String host = JiveGlobals.getProperty("mail.smtp.host", "localhost");
String port = JiveGlobals.getProperty("mail.smtp.port", "25");
String username = JiveGlobals.getProperty("mail.smtp.username");
String password = JiveGlobals.getProperty("mail.smtp.password");
String debugEnabled = JiveGlobals.getProperty("mail.debug");
boolean sslEnabled = JiveGlobals.getBooleanProperty("mail.smtp.ssl", true);
Properties props = new Properties();
props.put("mail.smtp.host", host);
props.put("mail.smtp.auth", port);
props.setProperty("mail.smtp.sendpartial", "true");
props.setProperty("mail.debug", debugEnabled);
if (sslEnabled) {
// Register with security provider.
Security.setProperty("ssl.SocketFactory.provider", SSL_FACTORY);
props.setProperty("mail.smtp.socketFactory.class", SSL_FACTORY);
props.setProperty("mail.smtp.socketFactory.fallback", "true");
}
if (username != null) {
props.put("mail.smtp.auth", "true");
}
Session session = Session.getInstance(props);
outputStream = new ByteArrayOutputStream();
createPdfAttachment(outputStream);
byte[] bytes = outputStream.toByteArray();
ByteArrayDataSource dataSource = new ByteArrayDataSource(bytes, "application/pdf");
MimeBodyPart pdfBodyPart = new MimeBodyPart();
pdfBodyPart.setDataHandler(new DataHandler(dataSource));
pdfBodyPart.setFileName("ResultSummary.pdf");
MimeMultipart multipart= new MimeMultipart();
multipart.addBodyPart(pdfBodyPart);
MimeMessage msg = new MimeMessage(session);
DefaultAdminProvider defaultAdminProvider= new DefaultAdminProvider();
java.util.List<JID> adminList=defaultAdminProvider.getAdmins();
java.util.List<String> adminListEmails=new ArrayList<String>();
UserManager manager = UserManager.getInstance();
Log.info("Number of Admins " +adminList.size());
for(int i = 0; i < adminList.size(); i++) {
User user;
try {
user = manager.getUser(adminList.get(i).getNode().toString());
Log.info("Admin Emails: " +user.getEmail());
adminListEmails.add(user.getEmail());
}
catch (Exception ex) {
continue;
}
}
// java.util.List<String> recipientsList=Arrays.asList("", "", "");
InternetAddress[] recipients = new InternetAddress[adminListEmails.size()];
for (int i = 0; i < adminListEmails.size(); i++) {
recipients[i] = new InternetAddress(adminListEmails.get(i).toString());
}
msg.setFrom(new InternetAddress("no-reply@openfire.org", "Openfire Admin"));
msg.setRecipients(javax.mail.Message.RecipientType.TO,recipients);
msg.setSubject("MONITORING REPORT - " + new SimpleDateFormat("MM/dd/yyyy HH:mm:ss").format(new Date()));
msg.setContent(multipart);
if (username != null)
{
URLName url = new URLName("smtp", host, Integer.parseInt(port), "", username, password);
Transport transport = new com.sun.mail.smtp.SMTPTransport(session, url);
transport.connect(host, Integer.parseInt(port), username, password);
transport.sendMessage(msg, msg.getRecipients(MimeMessage.RecipientType.TO));
} else Transport.send(msg);
} catch (Exception e) {
e.printStackTrace();
System.out.println("Could not send email");
}
}
public void createPdfAttachment(OutputStream outputStream) throws Exception {
Document document = new Document();
PdfWriter.getInstance(document, outputStream);
document.open();
document.addTitle("Monitoring Report");
document.addSubject("PDF Document");
document.addKeywords("iText, email");
document.addAuthor("JMX");
document.addCreator("JMX");
Timestamp stamp = new Timestamp(System.currentTimeMillis());
Date date = new Date(stamp.getTime());
//Make the Get call to get the data from Jolokia endpoint.
HttpClient httpClient = new HttpClient();
String monData = httpClient.getMemoryData();
Log.info("Monitoring Data JSON:"+monData);
//Converting json string to java object for easy manipulation.
Map outNode = new Genson().deserialize(monData, Map.class);
Map requestNode = (Map) outNode.get("request");
Map valueNode = (Map) outNode.get("value");
HashMap<String,String> monitoringData = new HashMap<String,String>();
monitoringData.put("Current Date",date.toString());
monitoringData.put("Report Date",outNode.get("timestamp").toString());
monitoringData.put("Maximum Heap Memory",valueNode.get("max").toString());
monitoringData.put("Committed Heap Memory",valueNode.get("committed").toString());
monitoringData.put("Init Heap Memory",valueNode.get("init").toString());
monitoringData.put("Used Heap Memory",valueNode.get("used").toString());
Font boldFont = new Font(Font.FontFamily.TIMES_ROMAN, 18, Font.BOLD);
PdfPTable table = new PdfPTable(2);
table.setSpacingBefore(5);
table.addCell(new Phrase("Monitor", boldFont ));
table.addCell(new Phrase("Value", boldFont ));
for (Map.Entry<String, String> entry : monitoringData.entrySet()) {
table.addCell(entry.getKey());
System.out.println(entry.getKey());
if (entry.getValue()!="" && entry.getValue()!=null)
{
table.addCell(entry.getValue());
System.out.println(entry.getValue());
}
else{
table.addCell("NOT AVAILABLE");
}
}
table.setHorizontalAlignment(Element.ALIGN_CENTER);
document.add(table);
document.close();
}
}
package com.ifsoft.jmxweb.plugin;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.*;
import org.jivesoftware.util.*;
import org.jivesoftware.openfire.XMPPServer;
public class HttpClient {
private static Logger Log = LoggerFactory.getLogger("JmxWebPlugin:HttpClient");
// http://localhost:7070/jolokia/read/java.lang:type=Memory/HeapMemoryUsage
StringBuilder resultString = new StringBuilder("");
String line="";
public String getMemoryData(){
try {
String port = JiveGlobals.getProperty("httpbind.port.plain", "7070");
String host = XMPPServer.getInstance().getServerInfo().getHostname();
String username = JiveGlobals.getProperty("jmxweb.admin.username", "admin");
String password = JiveGlobals.getProperty("jmxweb.admin.password", "admin");
URL url = new URL("http://" + username + ":" + password + "@" + host + ":" + port + "/jolokia/read/java.lang:type=Memory/HeapMemoryUsage");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/json");
if (conn.getResponseCode() != 200) {
throw new RuntimeException("HTTP Call Failed : HTTP error code : " + conn.getResponseCode());
}
BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
while ((line = br.readLine()) != null) {
resultString.append(line);
}
Log.info("Memory data: "+ resultString.toString());
conn.disconnect();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return resultString.toString();
}
}
......@@ -49,10 +49,12 @@ import com.javamonitor.openfire.mbeans.CoreThreadPool;
import com.javamonitor.openfire.mbeans.DatabasePool;
import com.javamonitor.openfire.mbeans.Openfire;
import com.javamonitor.openfire.mbeans.PacketCounter;
import com.ifsoft.jmxweb.plugin.EmailScheduler;
import org.apache.tomcat.InstanceManager;
import org.apache.tomcat.SimpleInstanceManager;
public class JmxWebPlugin implements Plugin {
private static Logger Log = LoggerFactory.getLogger("JmxWebPlugin");
......@@ -68,6 +70,7 @@ public class JmxWebPlugin implements Plugin {
private CoreThreadPool client = null;
private final static String OBJECTNAME_DATABASEPOOL = NAMEBASE + "type=databasepool";
private DatabasePool database = null;
private EmailScheduler emailScheduler = null;
public void initializePlugin(PluginManager manager, File pluginDirectory) {
......@@ -77,7 +80,6 @@ public class JmxWebPlugin implements Plugin {
openfire = new Openfire();
openfire.start();
JmxHelper.register(openfire, OBJECTNAME_OPENFIRE);
Log.info( "["+ NAME + "] .. started openfire server detector.");
} catch (Exception e) {
Log.debug("cannot start openfire server detector: " + e.getMessage(), e);
......@@ -153,6 +155,15 @@ public class JmxWebPlugin implements Plugin {
catch (Exception e) {
Log.error("Error initializing JmxWeb Plugin", e);
}
if (JiveGlobals.getBooleanProperty("jmxweb.email.monitoring", true))
{
Log.info( "["+ NAME + "] starting email monitoring");
emailScheduler = new EmailScheduler();
emailScheduler.startMonitoring();
Log.info( "["+ NAME + "] started monitoring");
}
}
public void destroyPlugin() {
......@@ -178,6 +189,10 @@ public class JmxWebPlugin implements Plugin {
JmxHelper.unregister(OBJECTNAME_OPENFIRE);
}
if (emailScheduler != null)
{
emailScheduler.stopMonitoring();
}
Log.info("["+ NAME + "] plugin fully destroyed.");
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment