OraMon 1.1 med JmxMon
Showing
12 changed files
with
200 additions
and
16 deletions
| ... | @@ -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 | ... | ... |
No preview for this file type
No preview for this file type
No preview for this file type
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 | } | ... | ... |
JavaMonWeb/src/JmxMonRESTgetMetrics.java
0 → 100644
| 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,6 +249,10 @@ public class OraMon { | ... | @@ -248,6 +249,10 @@ 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(); |
| ... | @@ -255,6 +260,10 @@ public class OraMon { | ... | @@ -255,6 +260,10 @@ public class OraMon { |
| 255 | // End thread safe | 260 | // End thread safe |
| 256 | } | 261 | } |
| 257 | 262 | ||
| 263 | public Throwable getLastEx() { | ||
| 264 | return lastEx; | ||
| 265 | } | ||
| 266 | |||
| 258 | public OraMon() { | 267 | public OraMon() { |
| 259 | // TODO Auto-generated constructor stub | 268 | // TODO Auto-generated constructor stub |
| 260 | } | 269 | } | ... | ... |
-
Please register or sign in to post a comment