Commit f5341f3f f5341f3f223b416b227e29cc6ae05c7900fae3a1 by Christian Gerdes

OraMon 1.1 med JmxMon

1 parent 1215b87b
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
2 <classpath> 2 <classpath>
3 <classpathentry kind="src" path="src"/> 3 <classpathentry kind="src" path="src"/>
4 <classpathentry combineaccessrules="false" kind="src" path="/LILOM Library"/> 4 <classpathentry combineaccessrules="false" kind="src" path="/LILOM Library"/>
5 <classpathentry combineaccessrules="false" kind="src" path="/LILJM Library"/>
5 <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"> 6 <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7">
6 <attributes> 7 <attributes>
7 <attribute name="owner.project.facets" value="java"/> 8 <attribute name="owner.project.facets" value="java"/>
...@@ -12,6 +13,5 @@ ...@@ -12,6 +13,5 @@
12 <classpathentry kind="lib" path="lib/javax.servlet.jar"/> 13 <classpathentry kind="lib" path="lib/javax.servlet.jar"/>
13 <classpathentry kind="lib" path="lib/javax.servlet.jsp.jar"/> 14 <classpathentry kind="lib" path="lib/javax.servlet.jsp.jar"/>
14 <classpathentry kind="lib" path="lib/javax.servlet.jsp.jstl.jar"/> 15 <classpathentry kind="lib" path="lib/javax.servlet.jsp.jstl.jar"/>
15 <classpathentry combineaccessrules="false" kind="src" path="/LILJM Library"/>
16 <classpathentry kind="output" path="build/classes"/> 16 <classpathentry kind="output" path="build/classes"/>
17 </classpath> 17 </classpath>
......
1 <%@page import="se.lil.om.Registry"%>
2 <%@page import="se.lil.om.OraMon"%> 1 <%@page import="se.lil.om.OraMon"%>
3 <%@page import="java.util.ArrayList"%> 2 <%@page import="se.lil.jm.JmxMon"%>
4 <%@page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> 3 <%@page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
5 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 4 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
6 <html> 5 <html>
...@@ -17,7 +16,7 @@ String errMsg = ""; ...@@ -17,7 +16,7 @@ String errMsg = "";
17 if(request.getParameter("action") != null) { 16 if(request.getParameter("action") != null) {
18 if(request.getParameter("action").equals("add")) { 17 if(request.getParameter("action").equals("add")) {
19 if(request.getParameter("data") != null && request.getParameter("data").length() != 0) { 18 if(request.getParameter("data") != null && request.getParameter("data").length() != 0) {
20 Registry.getList().add(new OraMon()); 19 //se.lil.om.Registry.getList().add(new OraMon());
21 } else { 20 } else {
22 error = true; 21 error = true;
23 errMsg = "Data is empty. Nothing added."; 22 errMsg = "Data is empty. Nothing added.";
...@@ -26,34 +25,36 @@ if(request.getParameter("action") != null) { ...@@ -26,34 +25,36 @@ if(request.getParameter("action") != null) {
26 } 25 }
27 %> 26 %>
28 27
29 <% ArrayList<OraMon> monList = Registry.getList(); %>
30
31 <% if(error) { %> 28 <% if(error) { %>
32 <div style="background: Salmon; padding: 10px;">Error: <%= errMsg %></div> 29 <div style="background: Salmon; padding: 10px;">Error: <%= errMsg %></div>
33 <% } %> 30 <% } %>
34 31
35 <h1>OraMon Web 1.0</h1> 32 <h1>OraMon Web 1.1 with JmxMon</h1>
36 33
37 <h2>Status</h2> 34 <h2>Status Oracle Monitors</h2>
38 35
39 <p>Number of monitors: <%= monList.size() %></p> 36 <p>Number of monitors: <%= se.lil.om.Registry.getList().size() %></p>
40 37
41 <div style="background-color: LightSteelBlue; padding: 10px;"> 38 <div style="background-color: LightSteelBlue; padding: 10px;">
42 <table> 39 <table>
43 <tr> 40 <tr>
41 <th>Name</th>
44 <th>Connection String</th> 42 <th>Connection String</th>
45 <th>Data Calls</th> 43 <th>Data Calls</th>
46 <th>Success</th> 44 <th>Success</th>
47 <th>Failed</th> 45 <th>Failed</th>
46 <th>Last Exception</th>
48 <th>Age</th> 47 <th>Age</th>
49 <th>RT</th> 48 <th>RT</th>
50 </tr> 49 </tr>
51 <% for (OraMon mon : Registry.getList()) { %> 50 <% for (OraMon mon : se.lil.om.Registry.getList()) { %>
52 <tr> 51 <tr>
52 <td><%= mon.getDBName() %></td>
53 <td><%= mon.getConString() %></td> 53 <td><%= mon.getConString() %></td>
54 <td><%= mon.getDataCalled() %></td> 54 <td><%= mon.getDataCalled() %></td>
55 <td><%= mon.getDataSucceeded() %></td> 55 <td><%= mon.getDataSucceeded() %></td>
56 <td><%= mon.getDataFailed() %></td> 56 <td><%= mon.getDataFailed() %></td>
57 <td><%= mon.getLastEx() %></td>
57 <td><%= mon.getAgeTs() %>s</td> 58 <td><%= mon.getAgeTs() %>s</td>
58 <td><%= mon.getLastRTms() %>ms</td> 59 <td><%= mon.getLastRTms() %>ms</td>
59 </tr> 60 </tr>
...@@ -61,7 +62,38 @@ if(request.getParameter("action") != null) { ...@@ -61,7 +62,38 @@ if(request.getParameter("action") != null) {
61 </table> 62 </table>
62 </div> 63 </div>
63 64
65 <h2>Status JMX Monitors</h2>
66
67 <p>Number of monitors: <%= se.lil.jm.Registry.getList().size() %></p>
64 68
69 <div style="background-color: LightSteelBlue; padding: 10px;">
70 <table>
71 <tr>
72 <th>Name</th>
73 <th>Connection String</th>
74 <th>Data Calls</th>
75 <th>Success</th>
76 <th>Failed</th>
77 <th>Last Exception</th>
78 <th>Age</th>
79 <th>RT</th>
80 </tr>
81 <% for (JmxMon mon : se.lil.jm.Registry.getList()) { %>
82 <tr>
83 <td><%= mon.getServerName() %></td>
84 <td><%= mon.getConString() %></td>
85 <td><%= mon.getDataCalled() %></td>
86 <td><%= mon.getDataSucceeded() %></td>
87 <td><%= mon.getDataFailed() %></td>
88 <td><%= mon.getLastEx() %></td>
89 <td><%= mon.getAgeTs() %>s</td>
90 <td><%= mon.getLastRTms() %>ms</td>
91 </tr>
92 <% } %>
93 </table>
94 </div>
95
96 <!--
65 <h2>Administration</h2> 97 <h2>Administration</h2>
66 98
67 <div title="Add Monitor" style="background: WhiteSmoke; padding: 10px;"> 99 <div title="Add Monitor" style="background: WhiteSmoke; padding: 10px;">
...@@ -72,5 +104,7 @@ if(request.getParameter("action") != null) { ...@@ -72,5 +104,7 @@ if(request.getParameter("action") != null) {
72 <input type="submit" name="action" value="add"> 104 <input type="submit" name="action" value="add">
73 </form> 105 </form>
74 </div> 106 </div>
107 -->
108
75 </body> 109 </body>
76 </html> 110 </html>
...\ No newline at end of file ...\ No newline at end of file
......
1 /se
2 /lilom.jar
3 /JmxMonRESTgetMetrics.class
1 /JmxMonRESTgetData.class 4 /JmxMonRESTgetData.class
2 /OraMonRESTgetData.class 5 /OraMonRESTgetData.class
3 /OraMonRESTgetMetrics.class 6 /OraMonRESTgetMetrics.class
......
No preview for this file type
...@@ -83,7 +83,13 @@ public class JmxMonRESTgetData extends HttpServlet { ...@@ -83,7 +83,13 @@ public class JmxMonRESTgetData extends HttpServlet {
83 83
84 } catch (Throwable e) { 84 } catch (Throwable e) {
85 response.setStatus(500); 85 response.setStatus(500);
86 response.getWriter().println("{\"error\":true,\"msg\":\""+e.toString().replace("\n"," ").replace("\"","\\\"").trim()+"\"}"); 86 Throwable lastCause = e.getCause();
87 Throwable thisCause = e;
88 while(lastCause != null) { thisCause = lastCause; lastCause = thisCause.getCause(); }
89 //response.getWriter().println("{\"error\":true,\"msg\":\""+e.toString().replace("\n"," ").replace("\"","\\\"").trim()+"\"}");
90 String rst = "{\"error\":true,\"msg\":\"" + e.toString() + ". Caused by: " + thisCause.toString() + "\"}";
91 rst.replace("\n"," ").replace("\"","\\\"").trim();
92 response.getWriter().println(rst);
87 e.printStackTrace(); 93 e.printStackTrace();
88 } 94 }
89 } 95 }
......
1
2
3 import java.io.IOException;
4
5 import javax.management.remote.JMXServiceURL;
6 import javax.servlet.ServletException;
7 import javax.servlet.annotation.WebServlet;
8 import javax.servlet.http.HttpServlet;
9 import javax.servlet.http.HttpServletRequest;
10 import javax.servlet.http.HttpServletResponse;
11
12 import se.lil.jm.JmxMon;
13 import se.lil.jm.Registry;
14
15 /**
16 * Servlet implementation class JmxMonRESTgetMetrics
17 */
18 @WebServlet(description = "Gets JMX Monitors metrics", urlPatterns = { "/JmxMonREST/getMetrics" })
19 public class JmxMonRESTgetMetrics extends HttpServlet {
20 private static final long serialVersionUID = 1L;
21
22 /**
23 * @see HttpServlet#HttpServlet()
24 */
25 public JmxMonRESTgetMetrics() {
26 super();
27 // TODO Auto-generated constructor stub
28 }
29
30 /**
31 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
32 */
33 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
34 response.setContentType("application/json");
35 try {
36 StringBuffer sb = new StringBuffer();
37 JmxMon mon = null;
38
39 if(request.getParameterMap().containsKey("connectionString")) {
40 // Check that we have a valid connection string
41 JMXServiceURL url;
42 try {
43 url = new JMXServiceURL(request.getParameter("connectionString"));
44 } catch (Exception e) {
45 // Error, we need a correct connection string
46 response.setStatus(400);
47 response.getWriter().println("{\"error\":true,\"msg\":\"connectionString is not a correct JMX Service URL\"}");
48 return;
49 }
50
51 // Try to find the monitor in our list
52 for (JmxMon item : Registry.getList()) {
53 if(item.getConString().equals(url.toString())) {
54 mon = item;
55 }
56 }
57
58 // If not found return error
59 if(mon == null) {
60 // Not found, create it
61 response.setStatus(HttpServletResponse.SC_NOT_FOUND);
62 response.getWriter().println("{\"error\":true,\"msg\":\"Can not find a monitor with connection string "+url.toString()+"\"}");
63 return;
64 }
65 }
66
67 // Loop over all monitors and output a Json array with the default set of metrics
68 sb.append("{\"error\":false,\"nvarray\":");
69 sb.append("[");
70
71 sb.append(",{\"name\":\"Number of processors #\",\"value\":" + mon.getNumberOfCPUs() + "}");
72 sb.append(",{\"name\":\"Process CPU Used %\",\"value\":" + mon.getCPUPercent() + "}");
73 sb.append(",{\"name\":\"Process Threads #\",\"value\":" + mon.getThreads() + "}");
74 sb.append(",{\"name\":\"Process Loaded Classes #\",\"value\":" + mon.getLoadedClassCount() + "}");
75 sb.append(",{\"name\":\"Process File Descriptors %\",\"value\":" + mon.getSystemFileDescriptorsPercentUsed() + "}");
76 sb.append(",{\"name\":\"Process Heap Committed MB\",\"value\":" + mon.getHeapCommittedMB() + "}");
77 sb.append(",{\"name\":\"Process Heap Used MB\",\"value\":" + mon.getHeapUsedMB() + "}");
78 sb.append(",{\"name\":\"Process Heap Used %\",\"value\":" + mon.getHeapUsedPercent() + "}");
79 sb.append(",{\"name\":\"OldGen Used MB\",\"value\":" + mon.getOldGenUsedMB() + "}");
80 sb.append(",{\"name\":\"OldGen Used %\",\"value\":" + mon.getOldGenUsedPercent() + "}");
81 sb.append(",{\"name\":\"OldGen After Last GC MB\",\"value\":" + mon.getOldGenAfterGCMB() + "}");
82 sb.append(",{\"name\":\"PermGen After Last GC MB\",\"value\":" + mon.getPermGenAfterGCMB() + "}");
83 sb.append(",{\"name\":\"GC Time (Overhead) %\",\"value\":" + mon.getGCOverhead() + "}");
84 sb.append(",{\"name\":\"System Load (per cpu)\",\"value\":" + mon.getAverageLoadPerCpu() + "}");
85 sb.append(",{\"name\":\"System Load (total)\",\"value\":" + mon.getAverageLoad() + "}");
86 sb.append(",{\"name\":\"System Memory %\",\"value\":" + mon.getSystemMemoryPercentUsed() + "}");
87 sb.append(",{\"name\":\"System Swap %\",\"value\":" + mon.getSystemSwapPercentUsed() + "}");
88
89 sb.append("]}");
90
91 response.getWriter().println(sb.toString());
92
93 } catch (Throwable e) {
94 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
95 response.getWriter().println("{\"error\":true,\"msg\":\""+e.toString().replace("\n"," ").trim()+"\"}");
96 e.printStackTrace();
97 }
98 }
99
100 }
...@@ -237,11 +237,11 @@ public class JmxMon { ...@@ -237,11 +237,11 @@ public class JmxMon {
237 } 237 }
238 238
239 public long getAgeTs() { 239 public long getAgeTs() {
240 if(lastFetchTSns > 0) return (System.nanoTime() - lastFetchTSns)/(1000*1000*1000); 240 return (System.nanoTime() - lastFetchTSns)/(1000*1000*1000);
241 else return 0;
242 } 241 }
243 242
244 Lock lock = new ReentrantLock(); 243 Lock lock = new ReentrantLock();
244 Throwable lastEx = null;
245 245
246 public boolean getData() throws Throwable { 246 public boolean getData() throws Throwable {
247 // Start thread safe 247 // Start thread safe
...@@ -260,8 +260,32 @@ public class JmxMon { ...@@ -260,8 +260,32 @@ public class JmxMon {
260 try { 260 try {
261 long startTSns = System.nanoTime(); 261 long startTSns = System.nanoTime();
262 getDataCalls++; 262 getDataCalls++;
263 // Check that we have a valid connection
264 if (jmxc == null || mbsc == null) open();
265 // Check if connection is valid
266 boolean stale = false;
267 try {
268 mbsc.getDefaultDomain();
269 } catch (Exception e) {
270 stale = true;
271 }
272 if(stale) {
273 // Try reconnect
274 try {
275 jmxc.close();
276 } catch (Exception e) {}
277 jmxc = null;
278 mbsc = null;
279 open();
280 mbsc.getDefaultDomain(); // This will throw an exception if we cant communicate with the server and abort this call
281 }
263 // Do the update of data 282 // Do the update of data
264 numCpus = (Integer)getAttributeValue("java.lang:type=OperatingSystem", "AvailableProcessors"); 283 Object val = getAttributeValue("java.lang:type=OperatingSystem", "AvailableProcessors");
284 if(val == null) {
285 // Something is wrong with the connection, we cant get number of cpus. Abort
286 throw new Exception("Bad JMX Connection: AvailableProcessors not found in java.lang:type=OperatingSystem MBean. JMX Connection String: " + this.url.toString());
287 }
288 numCpus = (Integer)val;
265 fetchUpdateAttribute("java.lang:type=OperatingSystem", "ProcessCpuTime"); 289 fetchUpdateAttribute("java.lang:type=OperatingSystem", "ProcessCpuTime");
266 fetchUpdateAttribute("java.lang:type=OperatingSystem", "OpenFileDescriptorCount"); 290 fetchUpdateAttribute("java.lang:type=OperatingSystem", "OpenFileDescriptorCount");
267 fetchUpdateAttribute("java.lang:type=OperatingSystem", "MaxFileDescriptorCount"); 291 fetchUpdateAttribute("java.lang:type=OperatingSystem", "MaxFileDescriptorCount");
...@@ -299,6 +323,10 @@ public class JmxMon { ...@@ -299,6 +323,10 @@ public class JmxMon {
299 } 323 }
300 return true; 324 return true;
301 } catch (Throwable e) { 325 } catch (Throwable e) {
326 Throwable lastCause = e.getCause();
327 Throwable thisCause = e;
328 while(lastCause != null) { thisCause = lastCause; lastCause = thisCause.getCause(); }
329 lastEx = thisCause;
302 throw (e); 330 throw (e);
303 } finally { 331 } finally {
304 lock.unlock(); 332 lock.unlock();
...@@ -306,6 +334,10 @@ public class JmxMon { ...@@ -306,6 +334,10 @@ public class JmxMon {
306 // End thread safe 334 // End thread safe
307 } 335 }
308 336
337 public Throwable getLastEx() {
338 return lastEx;
339 }
340
309 //NUM_CPUS 341 //NUM_CPUS
310 int numCpus = 0; 342 int numCpus = 0;
311 public long getNumberOfCPUs() { 343 public long getNumberOfCPUs() {
......
...@@ -26,7 +26,7 @@ public class TestRunner { ...@@ -26,7 +26,7 @@ public class TestRunner {
26 //JmxMon mon1 = new JmxMon("service:jmx:rmi:///jndi/iiop://u02878.ht.kap.rsv.se:17040/weblogic.management.mbeanservers.runtime"); // 10.3.6.0.161018.2 PS 26 //JmxMon mon1 = new JmxMon("service:jmx:rmi:///jndi/iiop://u02878.ht.kap.rsv.se:17040/weblogic.management.mbeanservers.runtime"); // 10.3.6.0.161018.2 PS
27 //JmxMon mon1 = new JmxMon("service:jmx:rmi:///jndi/iiop://u01891.ef.kap.rsv.se:17020/weblogic.management.mbeanservers.runtime"); // 10.3.6.0.161018.2 CMS 27 //JmxMon mon1 = new JmxMon("service:jmx:rmi:///jndi/iiop://u01891.ef.kap.rsv.se:17020/weblogic.management.mbeanservers.runtime"); // 10.3.6.0.161018.2 CMS
28 //JmxMon mon1 = new JmxMon("service:jmx:rmi:///jndi/iiop://u30450:34502/weblogic.management.mbeanservers.runtime"); // CMS 28 //JmxMon mon1 = new JmxMon("service:jmx:rmi:///jndi/iiop://u30450:34502/weblogic.management.mbeanservers.runtime"); // CMS
29 mon1.open(); 29 //mon1.open();
30 //mon2.open(); 30 //mon2.open();
31 jmxList.add(mon1); 31 jmxList.add(mon1);
32 //jmxList.add(mon2); 32 //jmxList.add(mon2);
......
...@@ -93,7 +93,7 @@ public class OraMon { ...@@ -93,7 +93,7 @@ public class OraMon {
93 } 93 }
94 } 94 }
95 95
96 public String getDBName() throws Throwable { 96 public String getDBName() {
97 return this.dbName; 97 return this.dbName;
98 } 98 }
99 99
...@@ -178,6 +178,7 @@ public class OraMon { ...@@ -178,6 +178,7 @@ public class OraMon {
178 } 178 }
179 179
180 Lock lock = new ReentrantLock(); 180 Lock lock = new ReentrantLock();
181 Throwable lastEx = null;
181 182
182 public boolean getData() throws Throwable { 183 public boolean getData() throws Throwable {
183 // Start thread safe 184 // Start thread safe
...@@ -248,12 +249,20 @@ public class OraMon { ...@@ -248,12 +249,20 @@ public class OraMon {
248 lastRTns = lastFetchTSns - startTSns; 249 lastRTns = lastFetchTSns - startTSns;
249 return true; 250 return true;
250 } catch (Throwable e) { 251 } catch (Throwable e) {
252 Throwable lastCause = e.getCause();
253 Throwable thisCause = e;
254 while(lastCause != null) { thisCause = lastCause; lastCause = thisCause.getCause(); }
255 lastEx = thisCause;
251 throw (e); 256 throw (e);
252 } finally { 257 } finally {
253 lock.unlock(); 258 lock.unlock();
254 } 259 }
255 // End thread safe 260 // End thread safe
256 } 261 }
262
263 public Throwable getLastEx() {
264 return lastEx;
265 }
257 266
258 public OraMon() { 267 public OraMon() {
259 // TODO Auto-generated constructor stub 268 // TODO Auto-generated constructor stub
......