Version 1.3 with a new method in JavaMonWeb for OraMon getPrometheus()
Showing
5 changed files
with
245 additions
and
1 deletions
| ... | @@ -78,6 +78,18 @@ function getMetrics(type, input, pdb) { | ... | @@ -78,6 +78,18 @@ function getMetrics(type, input, pdb) { |
| 78 | client2.send(); | 78 | client2.send(); |
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | function getPrometheus(type, input, pdb) { | ||
| 82 | // Get the metrics | ||
| 83 | var pdbAdd = ""; | ||
| 84 | if(pdb != "" && pdb != null) pdbAdd = "pdbName=" + pdb + "&"; | ||
| 85 | var client2 = new XMLHttpRequest(); | ||
| 86 | client2.onreadystatechange = metricsHandler; | ||
| 87 | client2.open("GET", "" + type + "/getPrometheus?" + pdbAdd + "connectionString=" + encodeURIComponent(input)); | ||
| 88 | client2.setRequestHeader('Cache-Control', 'no-cache'); | ||
| 89 | client2.setRequestHeader('Pragma', 'no-cache'); | ||
| 90 | client2.send(); | ||
| 91 | } | ||
| 92 | |||
| 81 | function showGraph(type, input, pdb) { | 93 | function showGraph(type, input, pdb) { |
| 82 | // Get the metrics | 94 | // Get the metrics |
| 83 | var pdbAdd = ""; | 95 | var pdbAdd = ""; |
| ... | @@ -98,7 +110,7 @@ function dataHandler() { | ... | @@ -98,7 +110,7 @@ function dataHandler() { |
| 98 | } | 110 | } |
| 99 | </script> | 111 | </script> |
| 100 | 112 | ||
| 101 | <h1>OraMon Web 1.2</h1> | 113 | <h1>OraMon Web 1.3</h1> |
| 102 | 114 | ||
| 103 | <h2>Status Oracle Monitors</h2> | 115 | <h2>Status Oracle Monitors</h2> |
| 104 | <p>Number of monitors: <%= se.lil.om.Registry.getList().size() %></p> | 116 | <p>Number of monitors: <%= se.lil.om.Registry.getList().size() %></p> |
| ... | @@ -151,6 +163,7 @@ function dataHandler() { | ... | @@ -151,6 +163,7 @@ function dataHandler() { |
| 151 | <input type="button" value="graph" onClick="showGraph('viewOraMon','<%= URLEncoder.encode(mon.getConString(), "UTF-8") %>',this.form.pdbName.value)"> | 163 | <input type="button" value="graph" onClick="showGraph('viewOraMon','<%= URLEncoder.encode(mon.getConString(), "UTF-8") %>',this.form.pdbName.value)"> |
| 152 | <input id="getDataButton" type="button" value="getData" onClick="getData('OraMonREST', '<%= mon.getConString() %>',this.form.pdbName.value)"> | 164 | <input id="getDataButton" type="button" value="getData" onClick="getData('OraMonREST', '<%= mon.getConString() %>',this.form.pdbName.value)"> |
| 153 | <input id="getMetricsButton" type="button" value="getMetrics" onClick="getMetrics('OraMonREST', '<%= mon.getConString() %>',this.form.pdbName.value)"> | 165 | <input id="getMetricsButton" type="button" value="getMetrics" onClick="getMetrics('OraMonREST', '<%= mon.getConString() %>',this.form.pdbName.value)"> |
| 166 | <input id="getPrometheusButton" type="button" value="getPrometheus" onClick="getPrometheus('OraMonREST', '<%= mon.getConString() %>',this.form.pdbName.value)"> | ||
| 154 | <input id="pdbName" name="pdbName" size="10"> | 167 | <input id="pdbName" name="pdbName" size="10"> |
| 155 | </form> | 168 | </form> |
| 156 | </td> | 169 | </td> | ... | ... |
This file is too large to display.
No preview for this file type
JavaMonWeb/src/OraMonRESTgetPrometheus.java
0 → 100644
| 1 | |||
| 2 | |||
| 3 | import java.io.IOException; | ||
| 4 | import java.util.logging.Level; | ||
| 5 | import java.util.logging.Logger; | ||
| 6 | |||
| 7 | import javax.servlet.ServletException; | ||
| 8 | import javax.servlet.annotation.WebServlet; | ||
| 9 | import javax.servlet.http.HttpServlet; | ||
| 10 | import javax.servlet.http.HttpServletRequest; | ||
| 11 | import javax.servlet.http.HttpServletResponse; | ||
| 12 | |||
| 13 | import se.lil.om.OraMon; | ||
| 14 | import se.lil.om.Registry; | ||
| 15 | |||
| 16 | /** | ||
| 17 | * Servlet implementation class OraMonRESTgetPrometheus | ||
| 18 | */ | ||
| 19 | @WebServlet(description = "Calls getData() and getMetrics() and reports in Prometheus format", urlPatterns = { "/OraMonREST/getPrometheus" }) | ||
| 20 | public class OraMonRESTgetPrometheus extends HttpServlet { | ||
| 21 | private static final long serialVersionUID = 1L; | ||
| 22 | private final static Logger LOGGER = Logger.getLogger(OraMonRESTgetPrometheus.class.getName()); | ||
| 23 | /** | ||
| 24 | * @see HttpServlet#HttpServlet() | ||
| 25 | */ | ||
| 26 | public OraMonRESTgetPrometheus() { | ||
| 27 | super(); | ||
| 28 | // TODO Auto-generated constructor stub | ||
| 29 | } | ||
| 30 | |||
| 31 | /** | ||
| 32 | * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) | ||
| 33 | */ | ||
| 34 | protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { | ||
| 35 | response.setContentType("application/json"); | ||
| 36 | try { | ||
| 37 | StringBuffer sb = new StringBuffer(); | ||
| 38 | int age = 0; | ||
| 39 | if(request.getParameterMap().containsKey("age")) { | ||
| 40 | try { | ||
| 41 | age = Integer.parseInt(request.getParameter("age")); | ||
| 42 | } catch (Exception e) { | ||
| 43 | response.setStatus(400); | ||
| 44 | response.getWriter().println("{\"error\":true,\"msg\":\"The specified age parameter is not a valid integer number\"}"); | ||
| 45 | return; | ||
| 46 | } | ||
| 47 | } | ||
| 48 | |||
| 49 | if(request.getParameterMap().containsKey("connectionString")) { | ||
| 50 | // We have a connection string, find the monitor or create it and call getData() on the monitor | ||
| 51 | OraMon monitor = null; | ||
| 52 | if(request.getParameter("connectionString").startsWith("jdbc:oracle")) { | ||
| 53 | // Full con string | ||
| 54 | String[] shortConArray = request.getParameter("connectionString").split("@"); | ||
| 55 | if(shortConArray.length != 2) { | ||
| 56 | // Error, wrong format of string | ||
| 57 | response.setStatus(HttpServletResponse.SC_BAD_REQUEST); | ||
| 58 | response.getWriter().println("{\"error\":true,\"msg\":\"connectionString needs to be in format jdbc:oracle:thin:@//host:port/servicename or jdbc:oracle:thin:@(<TNS Connection String>) with optional :username:password at the end.\"}"); | ||
| 59 | return; | ||
| 60 | } | ||
| 61 | String[] shortConArray2 = shortConArray[1].split(":"); | ||
| 62 | if(shortConArray2[0].startsWith("(")) { | ||
| 63 | // TNS Format | ||
| 64 | if(shortConArray2.length == 3) { | ||
| 65 | // We have a TNS connection string and username + password | ||
| 66 | monitor = Registry.findOrCreate(shortConArray[0] + "@" + shortConArray2[0], shortConArray2[1], shortConArray2[2]); | ||
| 67 | } else if (shortConArray2.length == 1) { | ||
| 68 | // We only have the TNS connection string, no username or password | ||
| 69 | monitor = Registry.find(shortConArray[0] + "@" + shortConArray2[0]); | ||
| 70 | } else { | ||
| 71 | // We have something else, not implemented | ||
| 72 | response.setStatus(HttpServletResponse.SC_BAD_REQUEST); | ||
| 73 | response.getWriter().println("{\"error\":true,\"msg\":\"connectionString needs to be in format jdbc:oracle:thin:@(<TNS Connection String>) with optional :username:password at the end.\"}"); | ||
| 74 | return; | ||
| 75 | } | ||
| 76 | } else { | ||
| 77 | // JDBC Format | ||
| 78 | if(shortConArray2[0].startsWith("//") && shortConArray2.length == 4) { | ||
| 79 | // We have new style and username and password, we can try to create the monitor if it doesnt exist | ||
| 80 | monitor = Registry.findOrCreate(shortConArray[0] + "@" + shortConArray2[0] + ":" + shortConArray2[1], shortConArray2[2], shortConArray2[3]); | ||
| 81 | } else if(!shortConArray2[0].startsWith("//") && shortConArray2.length == 5) { | ||
| 82 | // We have old style with sid with :username:password, try to find or create it | ||
| 83 | monitor = Registry.findOrCreate(shortConArray[0] + "@" + shortConArray2[0] + ":" + shortConArray2[1] + ":" + shortConArray2[2], shortConArray2[3], shortConArray2[4]); | ||
| 84 | } else if(shortConArray2[0].startsWith("//") && shortConArray2.length == 2) { | ||
| 85 | // We have new style but only have the connection string, try to find it (we cant create one without username/password) | ||
| 86 | monitor = Registry.find(request.getParameter("connectionString")); | ||
| 87 | } else if(!shortConArray2[0].startsWith("//") && shortConArray2.length == 3) { | ||
| 88 | // We have old style sid and no :username:password | ||
| 89 | monitor = Registry.find(request.getParameter("connectionString")); | ||
| 90 | } else { | ||
| 91 | // Wrong format | ||
| 92 | response.setStatus(HttpServletResponse.SC_BAD_REQUEST); | ||
| 93 | response.getWriter().println("{\"error\":true,\"msg\":\"connectionString needs to be in format jdbc:oracle:thin:@//host:port/servicename with optional :username:password at the end.\"}"); | ||
| 94 | return; | ||
| 95 | } | ||
| 96 | } | ||
| 97 | } else { | ||
| 98 | // Short con string | ||
| 99 | // Check that we have a valid connection string (added support to handle diffrent kinds of connection strings) | ||
| 100 | String[] conStrParamArray = request.getParameter("connectionString").split(":"); | ||
| 101 | Boolean serviceName = false; | ||
| 102 | if(conStrParamArray.length == 4) { | ||
| 103 | // Check if service name is used ( / instead of : ) | ||
| 104 | if(conStrParamArray[1].indexOf("/") >= 0) { | ||
| 105 | serviceName = true; | ||
| 106 | } | ||
| 107 | } | ||
| 108 | if(conStrParamArray.length != 5 && serviceName == false) { | ||
| 109 | // Error, we need 5 parts in the connection string | ||
| 110 | response.setStatus(400); | ||
| 111 | response.getWriter().println("{\"error\":true,\"msg\":\"connectionString needs to be in format host:port:sid:username:password or host:port/servicename:username:password\"}"); | ||
| 112 | return; | ||
| 113 | } | ||
| 114 | String conStr, usrStr, pwdStr; | ||
| 115 | if(serviceName) { | ||
| 116 | conStr = "jdbc:oracle:thin:@//" + conStrParamArray[0] + ":" + conStrParamArray[1]; | ||
| 117 | usrStr = conStrParamArray[2]; | ||
| 118 | pwdStr = conStrParamArray[3]; | ||
| 119 | } else { | ||
| 120 | conStr = "jdbc:oracle:thin:@" + conStrParamArray[0] + ":" + conStrParamArray[1] + ":" + conStrParamArray[2]; | ||
| 121 | usrStr = conStrParamArray[3]; | ||
| 122 | pwdStr = conStrParamArray[4]; | ||
| 123 | } | ||
| 124 | |||
| 125 | // Try to find the monitor in our list | ||
| 126 | monitor = Registry.findOrCreate(conStr, usrStr, pwdStr); | ||
| 127 | } | ||
| 128 | |||
| 129 | String pdbName = null; | ||
| 130 | if(request.getParameterMap().containsKey("pdbName")) { | ||
| 131 | String temp = request.getParameter("pdbName"); | ||
| 132 | if (!temp.isEmpty()) pdbName = temp; | ||
| 133 | } | ||
| 134 | |||
| 135 | if(monitor != null) { | ||
| 136 | if(request.getParameterMap().containsKey("block")) { | ||
| 137 | // Call setBlocked() | ||
| 138 | boolean blockedState = false; | ||
| 139 | try { | ||
| 140 | blockedState = Boolean.parseBoolean(request.getParameter("block")); | ||
| 141 | } catch (Exception e) { | ||
| 142 | response.setStatus(400); | ||
| 143 | response.getWriter().println("{\"error\":true,\"msg\":\"The specified block parameter is not a valid boolean\"}"); | ||
| 144 | return; | ||
| 145 | } | ||
| 146 | monitor.setBlockedState(blockedState); | ||
| 147 | if(blockedState == monitor.getBlockedState()) { | ||
| 148 | response.setStatus(200); | ||
| 149 | response.getWriter().println("{\"error\":false,\"msg\":\"The blocked state is now set to "+blockedState+"\"}"); | ||
| 150 | return; | ||
| 151 | } else { | ||
| 152 | response.setStatus(500); | ||
| 153 | response.getWriter().println("{\"error\":true,\"msg\":\"The blocked state could not be set to "+blockedState+"\"}"); | ||
| 154 | return; | ||
| 155 | } | ||
| 156 | } else { | ||
| 157 | // Call getData() | ||
| 158 | monitor.getData(age,pdbName); | ||
| 159 | String fName = monitor.getFriendlyName(pdbName); | ||
| 160 | String dbName = monitor.getDBName(); | ||
| 161 | |||
| 162 | // Now return the metrics in Prometheus format | ||
| 163 | |||
| 164 | sb.append("Cpu Usage (%){pdb=\""+fName+"\", cdb=\""+dbName+"\"} " + monitor.getCPUPercent(pdbName) + "\n"); | ||
| 165 | sb.append("Logical Reads (#/s){pdb=\""+fName+"\", cdb=\""+dbName+"\"} " + monitor.getLogicalReadsPerSecond(pdbName) + "\n"); | ||
| 166 | sb.append("Executes (#/s){pdb=\""+fName+"\", cdb=\""+dbName+"\"} " + monitor.getPerSecondValue("execute count",pdbName) + "\n"); | ||
| 167 | sb.append("User Calls (#/s){pdb=\""+fName+"\", cdb=\""+dbName+"\"} " + monitor.getPerSecondValue("user calls",pdbName) + "\n"); | ||
| 168 | sb.append("Cache Hit Ratio (%){pdb=\""+fName+"\", cdb=\""+dbName+"\"} " + monitor.getCacheHitRatioPercent(pdbName) + "\n"); | ||
| 169 | sb.append("Redo Size (#/s){pdb=\""+fName+"\", cdb=\""+dbName+"\"} " + monitor.getPerSecondValue("redo size",pdbName) + "\n"); | ||
| 170 | |||
| 171 | sb.append("OS Busy (%){pdb=\""+fName+"\", cdb=\""+dbName+"\"} " + monitor.getOsBusyPercent() + "}"); | ||
| 172 | sb.append("OS Load (#){pdb=\""+fName+"\", cdb=\""+dbName+"\"} " + monitor.getOsLoad() + "}"); | ||
| 173 | sb.append("OS Page In (KB/s){pdb=\""+fName+"\", cdb=\""+dbName+"\"} " + monitor.getPerSecondValue("VM_IN_BYTES", OraMon.OSSTAT)/1024 + "\n"); | ||
| 174 | sb.append("OS Page Out (KB/s){pdb=\""+fName+"\", cdb=\""+dbName+"\"} " + monitor.getPerSecondValue("VM_OUT_BYTES", OraMon.OSSTAT)/1024 + "\n"); | ||
| 175 | sb.append("OS Load per Cpu (#){pdb=\""+fName+"\", cdb=\""+dbName+"\"} " + monitor.getOsLoadPerCPU() + "\n"); | ||
| 176 | |||
| 177 | sb.append("Consistent Gets (#/s){pdb=\""+fName+"\", cdb=\""+dbName+"\"} " + monitor.getPerSecondValue("consistent gets",pdbName) + "\n"); | ||
| 178 | sb.append("DB Block Gets (#/s){pdb=\""+fName+"\", cdb=\""+dbName+"\"} " + monitor.getPerSecondValue("db block gets",pdbName) + "\n"); | ||
| 179 | |||
| 180 | sb.append("Buffer Cache Hit Ratio (%){pdb=\""+fName+"\", cdb=\""+dbName+"\"} " + monitor.getBufferCacheHitRatioPercent(pdbName) + "\n"); | ||
| 181 | sb.append("DB Block Changes (#/s){pdb=\""+fName+"\", cdb=\""+dbName+"\"} " + monitor.getPerSecondValue("db block changes",pdbName) + "\n"); | ||
| 182 | |||
| 183 | sb.append("Physical Reads (#/s){pdb=\""+fName+"\", cdb=\""+dbName+"\"} " + monitor.getPerSecondValue("physical reads",pdbName) + "\n"); | ||
| 184 | sb.append("Physical Writes (#/s){pdb=\""+fName+"\", cdb=\""+dbName+"\"} " + monitor.getPerSecondValue("physical writes",pdbName) + "\n"); | ||
| 185 | sb.append("Redo Writes (#/s){pdb=\""+fName+"\", cdb=\""+dbName+"\"} " + monitor.getPerSecondValue("redo writes",pdbName) + "\n"); | ||
| 186 | sb.append("Non-idle Wait Time (ms/s){pdb=\""+fName+"\", cdb=\""+dbName+"\"} " + monitor.getPerSecondValue("non-idle wait time",pdbName) + "\n"); | ||
| 187 | sb.append("File I/O Wait Time (ms/s){pdb=\""+fName+"\", cdb=\""+dbName+"\"} " + monitor.getPerSecondValue("file io wait time",pdbName) + "\n"); | ||
| 188 | |||
| 189 | sb.append("User Commits (#/s){pdb=\""+fName+"\", cdb=\""+dbName+"\"} " + monitor.getPerSecondValue("user commits",pdbName) + "\n"); | ||
| 190 | sb.append("User Rollbacks (#/s){pdb=\""+fName+"\", cdb=\""+dbName+"\"} " + monitor.getPerSecondValue("user rollbacks",pdbName) + "\n"); | ||
| 191 | sb.append("Parse Count Total (#/s){pdb=\""+fName+"\", cdb=\""+dbName+"\"} " + monitor.getPerSecondValue("parse count (total)",pdbName) + "\n"); | ||
| 192 | sb.append("Parse Count Hard (#/s){pdb=\""+fName+"\", cdb=\""+dbName+"\"} " + monitor.getPerSecondValue("parse count (hard)",pdbName) + "\n"); | ||
| 193 | sb.append("Cpu Usage xNIWT (%){pdb=\""+fName+"\", cdb=\""+dbName+"\"} " + monitor.getCPUPercent(true,pdbName) + "\n"); | ||
| 194 | sb.append("Cpu Time (us/s){pdb=\""+fName+"\", cdb=\""+dbName+"\"} " + monitor.getCPUTimePerSecond(pdbName) + "\n"); | ||
| 195 | sb.append("Cpus (#){pdb=\""+fName+"\", cdb=\""+dbName+"\"} " + monitor.getNumberOfCPUs() + "\n"); | ||
| 196 | |||
| 197 | sb.append("OraMon Response Time{pdb=\""+fName+"\", cdb=\""+dbName+"\"} " + monitor.getLastRTms() + "\n"); | ||
| 198 | sb.append("OraMon Blocked{pdb=\""+fName+"\", cdb=\""+dbName+"\"} " + monitor.getBlockedState() + "\n"); | ||
| 199 | sb.append("OraMon Age{pdb=\""+fName+"\", cdb=\""+dbName+"\"} " + monitor.getAgeTs() + "\n"); | ||
| 200 | |||
| 201 | } | ||
| 202 | } else { | ||
| 203 | response.setStatus(HttpServletResponse.SC_NOT_FOUND); | ||
| 204 | sb.append("{\"error\":true,\"msg\":\"Monitor not found and can't create one without :username:password '" + request.getParameter("connectionString") + "'\""); | ||
| 205 | sb.append("}"); | ||
| 206 | } | ||
| 207 | |||
| 208 | } else { | ||
| 209 | // No input, just return the list of monitors | ||
| 210 | sb.append("{\"count\":" + Registry.getList().size() + "}"); | ||
| 211 | } | ||
| 212 | |||
| 213 | response.getWriter().println(sb.toString()); | ||
| 214 | |||
| 215 | } catch (Throwable e) { | ||
| 216 | response.setStatus(500); | ||
| 217 | response.getWriter().println("{\"error\":true,\"msg\":\""+e.toString().replace("\n"," ").replace("\"","\\\"").trim()+"\"}"); | ||
| 218 | LOGGER.log(Level.SEVERE, e.toString()); | ||
| 219 | e.printStackTrace(); | ||
| 220 | } | ||
| 221 | } | ||
| 222 | |||
| 223 | /** | ||
| 224 | * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) | ||
| 225 | */ | ||
| 226 | protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { | ||
| 227 | // TODO Auto-generated method stub | ||
| 228 | } | ||
| 229 | |||
| 230 | } |
-
Please register or sign in to post a comment