Commit 5791fcf8 5791fcf89475b719072dd502953a59222e94d735 by Christian Gerdes
2 parents 19f030f3 21aac603
...@@ -43,21 +43,25 @@ if(request.getParameter("action") != null) { ...@@ -43,21 +43,25 @@ if(request.getParameter("action") != null) {
43 <% } %> 43 <% } %>
44 44
45 <script type="text/javascript"> 45 <script type="text/javascript">
46 function getData(type, input) { 46 function getData(type, input, pdb) {
47 // Update the data 47 // Update the data
48 var pdbAdd = "";
49 if(pdb != "" && pdb != null) pdbAdd = "&pdbName=" + pdb;
48 var client1 = new XMLHttpRequest(); 50 var client1 = new XMLHttpRequest();
49 client1.onreadystatechange = dataHandler; 51 client1.onreadystatechange = dataHandler;
50 client1.open("GET", "/" + type + "/getData?age=14&connectionString=" + encodeURIComponent(input)); 52 client1.open("GET", "/" + type + "/getData?age=14" + pdbAdd + "&connectionString=" + encodeURIComponent(input));
51 client1.setRequestHeader('Cache-Control', 'no-cache'); 53 client1.setRequestHeader('Cache-Control', 'no-cache');
52 client1.setRequestHeader('Pragma', 'no-cache'); 54 client1.setRequestHeader('Pragma', 'no-cache');
53 client1.send(); 55 client1.send();
54 } 56 }
55 57
56 function getMetrics(type, input) { 58 function getMetrics(type, input, pdb) {
57 // Get the metrics 59 // Get the metrics
60 var pdbAdd = "";
61 if(pdb != "" && pdb != null) pdbAdd = "pdbName=" + pdb + "&";
58 var client2 = new XMLHttpRequest(); 62 var client2 = new XMLHttpRequest();
59 client2.onreadystatechange = metricsHandler; 63 client2.onreadystatechange = metricsHandler;
60 client2.open("GET", "/" + type + "/getMetrics?connectionString=" + encodeURIComponent(input)); 64 client2.open("GET", "/" + type + "/getMetrics?" + pdbAdd + "connectionString=" + encodeURIComponent(input));
61 client2.setRequestHeader('Cache-Control', 'no-cache'); 65 client2.setRequestHeader('Cache-Control', 'no-cache');
62 client2.setRequestHeader('Pragma', 'no-cache'); 66 client2.setRequestHeader('Pragma', 'no-cache');
63 client2.send(); 67 client2.send();
...@@ -117,8 +121,9 @@ function dataHandler() { ...@@ -117,8 +121,9 @@ function dataHandler() {
117 <input type="submit" name="action" value="remove" > 121 <input type="submit" name="action" value="remove" >
118 <input type="hidden" name="omconstr" value="<%= mon.getConString() %>"> 122 <input type="hidden" name="omconstr" value="<%= mon.getConString() %>">
119 <input type="button" value="graph" onClick="window.open('/viewOraMon.html?<%= URLEncoder.encode(mon.getConString(), "UTF-8") %>')"> 123 <input type="button" value="graph" onClick="window.open('/viewOraMon.html?<%= URLEncoder.encode(mon.getConString(), "UTF-8") %>')">
120 <input id="getDataButton" type="button" value="getData" onClick="getData('OraMonREST', '<%= mon.getConString() %>')"> 124 <input id="getDataButton" type="button" value="getData" onClick="getData('OraMonREST', '<%= mon.getConString() %>',this.form.pdbName.value)">
121 <input id="getMetricsButton" type="button" value="getMetrics" onClick="getMetrics('OraMonREST', '<%= mon.getConString() %>')"> 125 <input id="getMetricsButton" type="button" value="getMetrics" onClick="getMetrics('OraMonREST', '<%= mon.getConString() %>',this.form.pdbName.value)">
126 <input id="pdbName" name="pdbName" size="10">
122 </form> 127 </form>
123 </td> 128 </td>
124 </tr> 129 </tr>
......
No preview for this file type
No preview for this file type
...@@ -53,27 +53,44 @@ public class OraMonRESTgetData extends HttpServlet { ...@@ -53,27 +53,44 @@ public class OraMonRESTgetData extends HttpServlet {
53 if(shortConArray.length != 2) { 53 if(shortConArray.length != 2) {
54 // Error, wrong format of string 54 // Error, wrong format of string
55 response.setStatus(HttpServletResponse.SC_BAD_REQUEST); 55 response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
56 response.getWriter().println("{\"error\":true,\"msg\":\"connectionString needs to be in format jdbc:oracle:thin:@//host:port/sid with optional :username:password at the end.\"}"); 56 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.\"}");
57 return; 57 return;
58 } 58 }
59 String[] shortConArray2 = shortConArray[1].split(":"); 59 String[] shortConArray2 = shortConArray[1].split(":");
60 if(shortConArray2[0].startsWith("//") && shortConArray2.length == 4) { 60 if(shortConArray2[0].startsWith("(")) {
61 // We have new style and username and password, we can try to create the monitor if it doesnt exist 61 // TNS Format
62 monitor = Registry.findOrCreate(shortConArray[0] + "@" + shortConArray2[0] + ":" + shortConArray2[1], shortConArray2[2], shortConArray2[3]); 62 if(shortConArray2.length == 3) {
63 } else if(!shortConArray2[0].startsWith("//") && shortConArray2.length == 5) { 63 // We have a TNS connection string and username + password
64 // We have old style with sid with :username:password, try to find or create it 64 monitor = Registry.findOrCreate(shortConArray[0] + "@" + shortConArray2[0], shortConArray2[1], shortConArray2[2]);
65 monitor = Registry.findOrCreate(shortConArray[0] + "@" + shortConArray2[0] + ":" + shortConArray2[1] + ":" + shortConArray2[2], shortConArray2[3], shortConArray2[4]); 65 } else if (shortConArray2.length == 1) {
66 } else if(shortConArray2[0].startsWith("//") && shortConArray2.length == 2) { 66 // We only have the TNS connection string, no username or password
67 // We have new style but only have the connection string, try to find it (we cant create one without username/password) 67 monitor = Registry.find(shortConArray[0] + "@" + shortConArray2[0]);
68 monitor = Registry.find(request.getParameter("connectionString")); 68 } else {
69 } else if(!shortConArray2[0].startsWith("//") && shortConArray2.length == 3) { 69 // We have something else, not implemented
70 // We have old style sid and no :username:password 70 response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
71 monitor = Registry.find(request.getParameter("connectionString")); 71 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.\"}");
72 return;
73 }
72 } else { 74 } else {
73 // Wrong format 75 // JDBC Format
74 response.setStatus(HttpServletResponse.SC_BAD_REQUEST); 76 if(shortConArray2[0].startsWith("//") && shortConArray2.length == 4) {
75 response.getWriter().println("{\"error\":true,\"msg\":\"connectionString needs to be in format jdbc:oracle:thin:@//host:port/sid with optional :username:password at the end.\"}"); 77 // We have new style and username and password, we can try to create the monitor if it doesnt exist
76 return; 78 monitor = Registry.findOrCreate(shortConArray[0] + "@" + shortConArray2[0] + ":" + shortConArray2[1], shortConArray2[2], shortConArray2[3]);
79 } else if(!shortConArray2[0].startsWith("//") && shortConArray2.length == 5) {
80 // We have old style with sid with :username:password, try to find or create it
81 monitor = Registry.findOrCreate(shortConArray[0] + "@" + shortConArray2[0] + ":" + shortConArray2[1] + ":" + shortConArray2[2], shortConArray2[3], shortConArray2[4]);
82 } else if(shortConArray2[0].startsWith("//") && shortConArray2.length == 2) {
83 // We have new style but only have the connection string, try to find it (we cant create one without username/password)
84 monitor = Registry.find(request.getParameter("connectionString"));
85 } else if(!shortConArray2[0].startsWith("//") && shortConArray2.length == 3) {
86 // We have old style sid and no :username:password
87 monitor = Registry.find(request.getParameter("connectionString"));
88 } else {
89 // Wrong format
90 response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
91 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.\"}");
92 return;
93 }
77 } 94 }
78 } else { 95 } else {
79 // Short con string 96 // Short con string
...@@ -94,7 +111,7 @@ public class OraMonRESTgetData extends HttpServlet { ...@@ -94,7 +111,7 @@ public class OraMonRESTgetData extends HttpServlet {
94 } 111 }
95 String conStr, usrStr, pwdStr; 112 String conStr, usrStr, pwdStr;
96 if(serviceName) { 113 if(serviceName) {
97 conStr = "jdbc:oracle:thin:@" + conStrParamArray[0] + ":" + conStrParamArray[1]; 114 conStr = "jdbc:oracle:thin:@//" + conStrParamArray[0] + ":" + conStrParamArray[1];
98 usrStr = conStrParamArray[2]; 115 usrStr = conStrParamArray[2];
99 pwdStr = conStrParamArray[3]; 116 pwdStr = conStrParamArray[3];
100 } else { 117 } else {
...@@ -107,17 +124,23 @@ public class OraMonRESTgetData extends HttpServlet { ...@@ -107,17 +124,23 @@ public class OraMonRESTgetData extends HttpServlet {
107 monitor = Registry.findOrCreate(conStr, usrStr, pwdStr); 124 monitor = Registry.findOrCreate(conStr, usrStr, pwdStr);
108 } 125 }
109 126
127 String pdbName = null;
128 if(request.getParameterMap().containsKey("pdbName")) {
129 String temp = request.getParameter("pdbName");
130 if (!temp.isEmpty()) pdbName = temp;
131 }
132
110 if(monitor != null) { 133 if(monitor != null) {
111 // Call getData() 134 // Call getData()
112 boolean didUpdate = monitor.getData(age); 135 boolean didUpdate = monitor.getData(age,pdbName);
113 String dbName = monitor.getDBName(); 136 String dbName = monitor.getFriendlyName(pdbName);
114 if(didUpdate) { 137 if(didUpdate) {
115 sb.append("{\"error\":false,\"msg\":\"Sucessfully collected data on instance '" + dbName + "'\""); 138 sb.append("{\"error\":false,\"msg\":\"Sucessfully collected data on '" + dbName + "'\"");
116 sb.append(",\"ms\":"+monitor.getLastRTms()+"}"); 139 sb.append(",\"ms\":"+monitor.getLastRTms()+"}");
117 } else { 140 } else {
118 response.setStatus(HttpServletResponse.SC_ACCEPTED); 141 response.setStatus(HttpServletResponse.SC_ACCEPTED);
119 sb.append("{\"error\":false"); 142 sb.append("{\"error\":false");
120 sb.append(",\"msg\":\"Data does not need to be updated on instance '" + dbName + "' either because another thread did concurrently update the monitor and we just waited for it to complete, or because the age (if) specified was higher than the monitors data age.\""); 143 sb.append(",\"msg\":\"Data does not need to be updated on '" + dbName + "' either because another thread did concurrently update the monitor and we just waited for it to complete, or because the age (if) specified was higher than the monitors data age.\"");
121 sb.append(",\"age\":"+monitor.getAgeTs()+"}"); 144 sb.append(",\"age\":"+monitor.getAgeTs()+"}");
122 } 145 }
123 } else { 146 } else {
......
1 1
2 2
3 import java.io.IOException; 3 import java.io.IOException;
4 import java.util.ArrayList;
5 4
6 import javax.servlet.ServletException; 5 import javax.servlet.ServletException;
7 import javax.servlet.annotation.WebServlet; 6 import javax.servlet.annotation.WebServlet;
...@@ -32,44 +31,57 @@ public class OraMonRESTgetMetrics extends HttpServlet { ...@@ -32,44 +31,57 @@ public class OraMonRESTgetMetrics extends HttpServlet {
32 */ 31 */
33 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 32 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
34 response.setContentType("application/json"); 33 response.setContentType("application/json");
34 OraMon monitor = null;
35 try { 35 try {
36 StringBuffer sb = new StringBuffer(); 36 StringBuffer sb = new StringBuffer();
37 ArrayList<OraMon> list = Registry.getList();
38 37
39 if(request.getParameterMap().containsKey("connectionString")) { 38 if(request.getParameterMap().containsKey("connectionString")) {
40 // We have a connection string, find the monitor and report only on that monitor 39 // We have a connection string, find the monitor and report only on that monitor
41 OraMon monitor = null; 40
42 if(request.getParameter("connectionString").startsWith("jdbc:oracle")) { 41 if(request.getParameter("connectionString").startsWith("jdbc:oracle")) {
43 // Full con string 42 // Full con string
44 String[] shortConArray = request.getParameter("connectionString").split("@"); 43 String[] shortConArray = request.getParameter("connectionString").split("@");
45 if(shortConArray.length != 2) { 44 if(shortConArray.length != 2) {
46 // Error, wrong format of string 45 // Error, wrong format of string
47 response.setStatus(HttpServletResponse.SC_BAD_REQUEST); 46 response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
48 response.getWriter().println("{\"error\":true,\"msg\":\"connectionString needs to be in format jdbc:oracle:thin:@//host:port/sid with optional :username:password at the end.\"}"); 47 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.\"}");
49 return; 48 return;
50 } 49 }
51 String[] shortConArray2 = shortConArray[1].split(":"); 50 String[] shortConArray2 = shortConArray[1].split(":");
52 if(shortConArray2[0].startsWith("//") && (shortConArray2.length == 4 || shortConArray2.length == 2)) { 51 if(shortConArray2[0].startsWith("(")) {
53 // We seem to have a correct connection string, if :username:password exist we ignore them here 52 // TNS Format
54 monitor = Registry.find(shortConArray[0] + "@" + shortConArray2[0] + ":" + shortConArray2[1]); 53 if(shortConArray2.length >= 1) {
55 if(monitor == null) { 54 monitor = Registry.find(shortConArray[0] + "@" + shortConArray2[0]);
56 response.setStatus(HttpServletResponse.SC_NOT_FOUND); 55 if(monitor == null) {
57 response.getWriter().println("{\"error\":true,\"msg\":\"Can not find a monitor with connection string "+shortConArray[0] + "@" + shortConArray2[0] + ":" + shortConArray2[1]+"\"}"); 56 response.setStatus(HttpServletResponse.SC_NOT_FOUND);
58 return; 57 response.getWriter().println("{\"error\":true,\"msg\":\"Can not find a monitor with connection string "+shortConArray[0] + "@" + shortConArray2[0]+"\"}");
58 return;
59 }
59 } 60 }
60 } else if(!shortConArray2[0].startsWith("//") && (shortConArray2.length == 5 || shortConArray2.length == 3)) { 61 } else {
61 // We seem to have a correct connection string, if :username:password exist we ignore them here 62 // JDBC Format
62 monitor = Registry.find(shortConArray[0] + "@" + shortConArray2[0] + ":" + shortConArray2[1] + ":" + shortConArray2[2]); 63 if(shortConArray2[0].startsWith("//") && (shortConArray2.length == 4 || shortConArray2.length == 2)) {
63 if(monitor == null) { 64 // We seem to have a correct connection string, if :username:password exist we ignore them here
64 response.setStatus(HttpServletResponse.SC_NOT_FOUND); 65 monitor = Registry.find(shortConArray[0] + "@" + shortConArray2[0] + ":" + shortConArray2[1]);
65 response.getWriter().println("{\"error\":true,\"msg\":\"Can not find a monitor with connection string "+shortConArray[0] + "@" + shortConArray2[0] + ":" + shortConArray2[1] + ":" + shortConArray2[2]+"\"}"); 66 if(monitor == null) {
67 response.setStatus(HttpServletResponse.SC_NOT_FOUND);
68 response.getWriter().println("{\"error\":true,\"msg\":\"Can not find a monitor with connection string "+shortConArray[0] + "@" + shortConArray2[0] + ":" + shortConArray2[1]+"\"}");
69 return;
70 }
71 } else if(!shortConArray2[0].startsWith("//") && (shortConArray2.length == 5 || shortConArray2.length == 3)) {
72 // We seem to have a correct connection string, if :username:password exist we ignore them here
73 monitor = Registry.find(shortConArray[0] + "@" + shortConArray2[0] + ":" + shortConArray2[1] + ":" + shortConArray2[2]);
74 if(monitor == null) {
75 response.setStatus(HttpServletResponse.SC_NOT_FOUND);
76 response.getWriter().println("{\"error\":true,\"msg\":\"Can not find a monitor with connection string "+shortConArray[0] + "@" + shortConArray2[0] + ":" + shortConArray2[1] + ":" + shortConArray2[2]+"\"}");
77 return;
78 }
79 } else {
80 // Wrong format
81 response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
82 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.\"}");
66 return; 83 return;
67 } 84 }
68 } else {
69 // Wrong format
70 response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
71 response.getWriter().println("{\"error\":true,\"msg\":\"connectionString needs to be in format jdbc:oracle:thin:@//host:port/sid with optional :username:password at the end.\"}");
72 return;
73 } 85 }
74 } else { 86 } else {
75 // Check that we have a valid connection string (old style) 87 // Check that we have a valid connection string (old style)
...@@ -89,64 +101,65 @@ public class OraMonRESTgetMetrics extends HttpServlet { ...@@ -89,64 +101,65 @@ public class OraMonRESTgetMetrics extends HttpServlet {
89 } 101 }
90 String conStr; 102 String conStr;
91 if(serviceName) { 103 if(serviceName) {
92 conStr = "jdbc:oracle:thin:@" + conStrParamArray[0] + ":" + conStrParamArray[1]; 104 conStr = "jdbc:oracle:thin:@//" + conStrParamArray[0] + ":" + conStrParamArray[1];
93 } else { 105 } else {
94 conStr = "jdbc:oracle:thin:@" + conStrParamArray[0] + ":" + conStrParamArray[1] + ":" + conStrParamArray[2]; 106 conStr = "jdbc:oracle:thin:@" + conStrParamArray[0] + ":" + conStrParamArray[1] + ":" + conStrParamArray[2];
95 } 107 }
96 monitor = Registry.find(conStr); 108 monitor = Registry.find(conStr);
97 if(monitor == null) {
98 // Not found, create it
99 response.setStatus(HttpServletResponse.SC_NOT_FOUND);
100 response.getWriter().println("{\"error\":true,\"msg\":\"Can not find a monitor with connection string "+request.getParameter("connectionString")+"\"}");
101 return;
102 }
103 } 109 }
104
105 // Set this monitor to the only one on the list
106 list = new ArrayList<OraMon>();
107 list.add(monitor);
108 } 110 }
109 111
110 // Loop over all monitors and output a Json array with the default set of metrics 112 if(monitor == null) {
113 // Not found, response with 404
114 response.setStatus(HttpServletResponse.SC_NOT_FOUND);
115 response.getWriter().println("{\"error\":true,\"msg\":\"Can not find a monitor with connection string "+request.getParameter("connectionString")+"\"}");
116 return;
117 }
111 118
112 for (OraMon item : list) { 119 String pdbName = null;
113 sb.append("{\"name\":\"" + item.getDBName() + "\",\"error\":false,\"nvarray\":"); 120 if(request.getParameterMap().containsKey("pdbName")) {
114 sb.append("["); 121 String temp = request.getParameter("pdbName");
115 122 if (!temp.isEmpty()) pdbName = temp;
116
117 sb.append("{\"name\":\"Cpu Usage (%)\",\"value\":" + item.getCPUPercent() + "}");
118 sb.append(",{\"name\":\"Logical Reads (#/s)\",\"value\":" + item.getLogicalReadsPerSecond() + "}");
119 sb.append(",{\"name\":\"Executes (#/s)\",\"value\":" + item.getPerSecondValue("execute count") + "}");
120 sb.append(",{\"name\":\"User Calls (#/s)\",\"value\":" + item.getPerSecondValue("user calls") + "}");
121 sb.append(",{\"name\":\"Cache Hit Ratio (%)\",\"value\":" + item.getCacheHitRatioPercent() + "}");
122 sb.append(",{\"name\":\"Redo Size (#/s)\",\"value\":" + item.getPerSecondValue("redo size") + "}");
123
124 sb.append(",{\"name\":\"OS Busy (%)\",\"value\":" + item.getOsBusyPercent() + "}");
125 sb.append(",{\"name\":\"OS Load (#)\",\"value\":" + item.getOsLoad() + "}");
126 sb.append(",{\"name\":\"OS Page In (KB/s)\",\"value\":" + item.getPerSecondValue("VM_IN_BYTES", OraMon.OSSTAT)/1024 + "}");
127 sb.append(",{\"name\":\"OS Page Out (KB/s)\",\"value\":" + item.getPerSecondValue("VM_OUT_BYTES", OraMon.OSSTAT)/1024 + "}");
128 sb.append(",{\"name\":\"OS Load per Cpu (#)\",\"value\":" + item.getOsLoadPerCPU() + "}");
129
130 sb.append(",{\"name\":\"Consistent Gets (#/s)\",\"value\":" + item.getPerSecondValue("consistent gets") + "}");
131 sb.append(",{\"name\":\"DB Block Gets (#/s)\",\"value\":" + item.getPerSecondValue("db block gets") + "}");
132
133 sb.append(",{\"name\":\"Buffer Cache Hit Ratio (%)\",\"value\":" + item.getBufferCacheHitRatioPercent() + "}");
134 sb.append(",{\"name\":\"DB Block Changes (#/s)\",\"value\":" + item.getPerSecondValue("db block changes") + "}");
135
136 sb.append(",{\"name\":\"Physical Reads (#/s)\",\"value\":" + item.getPerSecondValue("physical reads") + "}");
137 sb.append(",{\"name\":\"Physical Writes (#/s)\",\"value\":" + item.getPerSecondValue("physical writes") + "}");
138 sb.append(",{\"name\":\"Redo Writes (#/s)\",\"value\":" + item.getPerSecondValue("redo writes") + "}");
139 sb.append(",{\"name\":\"Non-idle Wait Time (ms/s)\",\"value\":" + item.getPerSecondValue("non-idle wait time") + "}");
140 sb.append(",{\"name\":\"File I/O Wait Time (ms/s)\",\"value\":" + item.getPerSecondValue("file io wait time") + "}");
141
142 sb.append(",{\"name\":\"User Commits (#/s)\",\"value\":" + item.getPerSecondValue("user commits") + "}");
143 sb.append(",{\"name\":\"User Rollbacks (#/s)\",\"value\":" + item.getPerSecondValue("user rollbacks") + "}");
144 sb.append(",{\"name\":\"Parse Count Total (#/s)\",\"value\":" + item.getPerSecondValue("parse count (total)") + "}");
145 sb.append(",{\"name\":\"Parse Count Hard (#/s)\",\"value\":" + item.getPerSecondValue("parse count (hard)") + "}");
146 sb.append(",{\"name\":\"Cpu Usage xNIWT (%)\",\"value\":" + item.getCPUPercent(true) + "}");
147 sb.append(",{\"name\":\"Cpu Time (us/s)\",\"value\":" + item.getCPUTimePerSecond() + "}");
148 sb.append(",{\"name\":\"Cpus (#)\",\"value\":" + item.getNumberOfCPUs() + "}");
149 } 123 }
124
125 // Write out the monitors data
126 sb.append("{\"name\":\"" + monitor.getFriendlyName(pdbName) + "\",\"error\":false,\"nvarray\":");
127 sb.append("[");
128
129
130 sb.append("{\"name\":\"Cpu Usage (%)\",\"value\":" + monitor.getCPUPercent(pdbName) + "}");
131 sb.append(",{\"name\":\"Logical Reads (#/s)\",\"value\":" + monitor.getLogicalReadsPerSecond(pdbName) + "}");
132 sb.append(",{\"name\":\"Executes (#/s)\",\"value\":" + monitor.getPerSecondValue("execute count",pdbName) + "}");
133 sb.append(",{\"name\":\"User Calls (#/s)\",\"value\":" + monitor.getPerSecondValue("user calls",pdbName) + "}");
134 sb.append(",{\"name\":\"Cache Hit Ratio (%)\",\"value\":" + monitor.getCacheHitRatioPercent(pdbName) + "}");
135 sb.append(",{\"name\":\"Redo Size (#/s)\",\"value\":" + monitor.getPerSecondValue("redo size",pdbName) + "}");
136
137 sb.append(",{\"name\":\"OS Busy (%)\",\"value\":" + monitor.getOsBusyPercent() + "}");
138 sb.append(",{\"name\":\"OS Load (#)\",\"value\":" + monitor.getOsLoad() + "}");
139 sb.append(",{\"name\":\"OS Page In (KB/s)\",\"value\":" + monitor.getPerSecondValue("VM_IN_BYTES", OraMon.OSSTAT)/1024 + "}");
140 sb.append(",{\"name\":\"OS Page Out (KB/s)\",\"value\":" + monitor.getPerSecondValue("VM_OUT_BYTES", OraMon.OSSTAT)/1024 + "}");
141 sb.append(",{\"name\":\"OS Load per Cpu (#)\",\"value\":" + monitor.getOsLoadPerCPU() + "}");
142
143 sb.append(",{\"name\":\"Consistent Gets (#/s)\",\"value\":" + monitor.getPerSecondValue("consistent gets",pdbName) + "}");
144 sb.append(",{\"name\":\"DB Block Gets (#/s)\",\"value\":" + monitor.getPerSecondValue("db block gets",pdbName) + "}");
145
146 sb.append(",{\"name\":\"Buffer Cache Hit Ratio (%)\",\"value\":" + monitor.getBufferCacheHitRatioPercent(pdbName) + "}");
147 sb.append(",{\"name\":\"DB Block Changes (#/s)\",\"value\":" + monitor.getPerSecondValue("db block changes",pdbName) + "}");
148
149 sb.append(",{\"name\":\"Physical Reads (#/s)\",\"value\":" + monitor.getPerSecondValue("physical reads",pdbName) + "}");
150 sb.append(",{\"name\":\"Physical Writes (#/s)\",\"value\":" + monitor.getPerSecondValue("physical writes",pdbName) + "}");
151 sb.append(",{\"name\":\"Redo Writes (#/s)\",\"value\":" + monitor.getPerSecondValue("redo writes",pdbName) + "}");
152 sb.append(",{\"name\":\"Non-idle Wait Time (ms/s)\",\"value\":" + monitor.getPerSecondValue("non-idle wait time",pdbName) + "}");
153 sb.append(",{\"name\":\"File I/O Wait Time (ms/s)\",\"value\":" + monitor.getPerSecondValue("file io wait time",pdbName) + "}");
154
155 sb.append(",{\"name\":\"User Commits (#/s)\",\"value\":" + monitor.getPerSecondValue("user commits",pdbName) + "}");
156 sb.append(",{\"name\":\"User Rollbacks (#/s)\",\"value\":" + monitor.getPerSecondValue("user rollbacks",pdbName) + "}");
157 sb.append(",{\"name\":\"Parse Count Total (#/s)\",\"value\":" + monitor.getPerSecondValue("parse count (total)",pdbName) + "}");
158 sb.append(",{\"name\":\"Parse Count Hard (#/s)\",\"value\":" + monitor.getPerSecondValue("parse count (hard)",pdbName) + "}");
159 sb.append(",{\"name\":\"Cpu Usage xNIWT (%)\",\"value\":" + monitor.getCPUPercent(true,pdbName) + "}");
160 sb.append(",{\"name\":\"Cpu Time (us/s)\",\"value\":" + monitor.getCPUTimePerSecond(pdbName) + "}");
161 sb.append(",{\"name\":\"Cpus (#)\",\"value\":" + monitor.getNumberOfCPUs() + "}");
162
150 sb.append("]}"); 163 sb.append("]}");
151 164
152 response.getWriter().println(sb.toString()); 165 response.getWriter().println(sb.toString());
......
1 javaw.exe -Dcom.sun.management.jmxremote.ssl=false -cp "wls-12.2.1.2.0.4/wljmxclient.jar;jconsole.1.8.0_91.jar" sun.tools.jconsole.JConsole "service:jmx:rmi:///jndi/iiop://damk321s2.da.kap.rsv.se:17010/weblogic.management.mbeanservers.runtime"
...\ No newline at end of file ...\ No newline at end of file
No preview for this file type
No preview for this file type
1 # Notes
2
3 ## PDB logic
4
5 Bytt approuch och tagit bort allt som tidigare fanns i PDB branchen och har mergat den med master (då den innehöll TNS koden).
6
7 Gamla tanken var att via en PDB klura ut vad CDB databasens conn sträng är, ansluta till den, och hämta data för alla PDBer istället och cacha detta i CDB objektet.
8 Hade funkat fint, förutom att det förutsätter att CDB och PDB har samma lyssnare, vilket de inte nödvändigtvist har. Jag kan inte klura ut vad lyssnaren ska vara till CDB.
9
10 Istället får det bli en lösning där användaren alltid anger CDB databasens conn sträng, men kan med en flagga välja att få ut en PDB's info istället.
11
12 Idag ser tex ett anrop ut så här:
13
14 GET /OraMonREST/getData?age=14&connectionString=jdbc%3Aoracle%3Athin%3A%40%2F%2Fu03634.kap.rsv.se%3A1526%2FDB1K12
15
16 I detta kan vi lägga till en parameter, forPDB=DA1K001 tex och då returneras endast värden för den PDB'n.
17 På så sätt kommer anrop till flera olika PDB att hämtas från samma CDB data cache.
18 Anropet till CDB'n skulle kunna returnera en lista på alla PDBer också.
19 Ännu snyggare vore om en CDB kunde bryta ner graferna per PDB också ;)
20
21 SQL satser
22
23 select cdb from v$database;
24 Returnerar YES om databasen är en CDB (dvs Oracle 12 med CDB påslaget). Returnerar YES även på en PDB.
25
26 Views for PDB's
27
28 V_$CON_SYSSTAT
29 V_$CON_SYSTEM_WAIT_CLASS
30 V_$CON_SYSTEM_EVENT
31 V_$CON_SYS_TIME_MODEL
32
33 Can be checked with a select like
34 select view_name from all_views where view_name like 'V_$CON_%';
35
36 Slå samman con_id med statname
37 select systimestamp, name || con_id, value from V$CON_SYSSTAT;
38
39 2018-03-28
40 Första versionen med PDB stöd. Behövs mer tester.
41
42 PDB CPU: 11.056953715796771
43 CDB CPU: 11.204673034978592
44 DA1K001: 11.084891829252536
45 DA1K002: 55.75905904774211
46 TOTAL : 66.84395087699465
47
48 Exemplet ovan är med ett delta på 60 sekunder, PDB går direkt mot PDB con string, CDB direkt mot CDB och DA räknarna är från denna CDB.
49 DA1K002 är på samma CDB, och getCPUPercent() ovan returnerar av någon anledning att den tar 55% cpu när hela CDB bara tar 11.2 vilket känns fel.
50 Det är bara DA1K001 som jobbar. Nedan från samma mätning fast Logical IO per Second istället:
51
52 PDB LIO: 433961.7046663872
53 CDB LIO: 433532.02901594585
54 DA1K001: 435343.22211814864
55 DA1K002: 9.075934239850135
56 TOTAL : 435352.2980523885
57
58 Här känns alla värden rätt. Får göra klart GUI bitarna och se hur monitorerna beteer sig under längre tid.
59
60 När jag kört ett tag i graph läget nu på en PDB via CDB, ser jag även konstiga värden på mycket annat. Cache Hit Ratio på 1200%, negativa värden på flera räknare, mm.
61 GUI delarna lirar inte riktigt heller, getMetrics ger en 500 och en NullPointer (beror på att pdbName skickas alltid, null om den inte ska användas, och det funkar
62 inte i alla metoder i OraMon.java klassen). Anger man en PDB i OraMon.jsp så blir det HTTP 0 status?? på getData och getMetrics knapparna.
...\ No newline at end of file ...\ No newline at end of file
...@@ -83,4 +83,17 @@ class Collector { ...@@ -83,4 +83,17 @@ class Collector {
83 else 83 else
84 return 0; 84 return 0;
85 } 85 }
86
87 public double getSeconds(String name) throws Throwable {
88 LongDelta myDelta = null;
89 for(int x = 0; x<list.size() && myDelta == null; x++) {
90 if(name.equals(list.get(x).name)) {
91 myDelta = list.get(x);
92 }
93 }
94 if(myDelta != null)
95 return myDelta.getSeconds();
96 else
97 return 0;
98 }
86 } 99 }
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -34,7 +34,7 @@ class LongDelta { ...@@ -34,7 +34,7 @@ class LongDelta {
34 update(value, timestamp, false); 34 update(value, timestamp, false);
35 } 35 }
36 36
37 public void update(Long value, Timestamp timestamp, boolean convert) { 37 public void update(long value, Timestamp timestamp, boolean convert) {
38 if(convert) value = value/1000; 38 if(convert) value = value/1000;
39 if(urProt) { 39 if(urProt) {
40 if(this.curValue != null && this.curValue > value) { 40 if(this.curValue != null && this.curValue > value) {
......
1 package se.lil.om; 1 package se.lil.om;
2 2
3 import java.sql.*; 3 import java.sql.*;
4 import java.util.HashSet;
4 import java.util.Properties; 5 import java.util.Properties;
5 import java.util.concurrent.locks.Lock; 6 import java.util.concurrent.locks.Lock;
6 import java.util.concurrent.locks.ReentrantLock; 7 import java.util.concurrent.locks.ReentrantLock;
8 import java.util.regex.Matcher;
9 import java.util.regex.Pattern;
7 10
8 public class OraMon { 11 public class OraMon {
9 Connection conn = null; 12 Connection conn = null;
...@@ -11,6 +14,7 @@ public class OraMon { ...@@ -11,6 +14,7 @@ public class OraMon {
11 String conUser = "system"; 14 String conUser = "system";
12 String conPass = "passw0rd"; 15 String conPass = "passw0rd";
13 String dbName = null; 16 String dbName = null;
17 String serviceName = null;
14 18
15 public static final int SYSSTAT = 1; 19 public static final int SYSSTAT = 1;
16 public static final int OSSTAT = 2; 20 public static final int OSSTAT = 2;
...@@ -21,6 +25,24 @@ public class OraMon { ...@@ -21,6 +25,24 @@ public class OraMon {
21 int getDataCalls = 0; 25 int getDataCalls = 0;
22 int getDataSucess = 0; 26 int getDataSucess = 0;
23 27
28 boolean getPdbs = false;
29 Collector colPdbSysStat = null;
30 Collector colPdbCPU = null;
31 HashSet<String> pdbSet = null;
32 public static final String strCpuTime = " cputime";
33 public static final String strNiwTime = " niwtime";
34 public static final String strSeparator = " ";
35
36 public int getNumPdbs() {
37 if(pdbSet != null) return pdbSet.size();
38 else return 0;
39 }
40
41 public String[] getPdbArray() {
42 if(pdbSet != null) return (String[]) pdbSet.toArray();
43 else return null;
44 }
45
24 public int getDataCalled() { 46 public int getDataCalled() {
25 return getDataCalls; 47 return getDataCalls;
26 } 48 }
...@@ -37,6 +59,33 @@ public class OraMon { ...@@ -37,6 +59,33 @@ public class OraMon {
37 return this.conString; 59 return this.conString;
38 } 60 }
39 61
62 public String getServiceName() {
63 if(this.serviceName != null) return this.serviceName;
64 if(this.conString != null) {
65 if(this.conString.contains("SERVICE_NAME=")) {
66 //TNS format
67 Pattern pat = Pattern.compile("SERVICE_NAME=(\\w+)");
68 Matcher m = pat.matcher(this.conString);
69 if(m.find()) {
70 this.serviceName = m.group(1);
71 } else {
72 this.serviceName = null;
73 }
74 } else {
75 int last = this.conString.lastIndexOf('/');
76 if(last >=0)
77 this.serviceName = this.conString.substring(last +1);
78 else {
79 last = this.conString.lastIndexOf(':');
80 this.serviceName = this.conString.substring(last +1);
81 }
82 }
83 } else {
84 this.serviceName = null;
85 }
86 return this.serviceName;
87 }
88
40 //NUM_CPUS 89 //NUM_CPUS
41 int numCpus = 0; 90 int numCpus = 0;
42 public long getNumberOfCPUs() throws Throwable { 91 public long getNumberOfCPUs() throws Throwable {
...@@ -46,57 +95,110 @@ public class OraMon { ...@@ -46,57 +95,110 @@ public class OraMon {
46 //DB CPU 95 //DB CPU
47 LongDelta cpuTime = new LongDelta(true); 96 LongDelta cpuTime = new LongDelta(true);
48 LongDelta niwTime = new LongDelta(true); 97 LongDelta niwTime = new LongDelta(true);
49 public double getCPUPercent(boolean excludeNonIdleWaitTime) throws Throwable { 98 public double getCPUPercent(boolean excludeNonIdleWaitTime, String pdbName) throws Throwable {
50 double perSec = cpuTime.getPerSecondValue(); 99 double cpuPerSec;
100 if(pdbName == null) cpuPerSec = cpuTime.getPerSecondValue();
101 else cpuPerSec = colPdbCPU.getPerSecValue(pdbName + strCpuTime);
102
103 double niwPerSec;
104 if(pdbName == null) niwPerSec = niwTime.getPerSecondValue();
105 else niwPerSec = colPdbCPU.getPerSecValue(pdbName + strNiwTime);
106
51 if(excludeNonIdleWaitTime) { 107 if(excludeNonIdleWaitTime) {
52 double newPerSec = perSec - (niwTime.getPerSecondValue() * 1000); 108 double newPerSec = cpuPerSec - (niwPerSec * 1000);
53 if(newPerSec > 0) perSec = newPerSec; else perSec = 0; 109 if(newPerSec > 0) cpuPerSec = newPerSec; else cpuPerSec = 0;
54 } 110 }
55 double totSec = numCpus * 1000 * 1000; 111 double totSec = numCpus * 1000 * 1000;
56 double percent = (perSec / totSec) * 100; 112 double percent = (cpuPerSec / totSec) * 100;
57 if(percent > 100D) percent=100D; 113 if(percent > 100D) percent=100D;
58 if(percent < 0D) percent=0D; 114 if(percent < 0D) percent=0D;
59 return percent; 115 return percent;
60 } 116 }
117 public double getCPUPercent(boolean excludeNonIdleWaitTime) throws Throwable {
118 return getCPUPercent(excludeNonIdleWaitTime, null);
119 }
61 public double getCPUPercent() throws Throwable { 120 public double getCPUPercent() throws Throwable {
62 return getCPUPercent(false); 121 return getCPUPercent(false);
63 } 122 }
123 public double getCPUPercent(String pdbName) throws Throwable {
124 return getCPUPercent(false, pdbName);
125 }
126
64 public double getCPUAvailableSeconds() throws Throwable { 127 public double getCPUAvailableSeconds() throws Throwable {
65 return cpuTime.getSeconds()*numCpus; 128 return cpuTime.getSeconds()*numCpus;
66 } 129 }
130 public double getCPUAvailableSeconds(String pdbName) throws Throwable {
131 return colPdbCPU.getSeconds(pdbName + strCpuTime)*numCpus;
132 }
133
67 public long getCPURawValue() throws Throwable { 134 public long getCPURawValue() throws Throwable {
68 return cpuTime.getCurrentValue(); 135 return cpuTime.getCurrentValue();
69 } 136 }
70 public long getCPURawDiff() { 137 public long getCPURawValue(String pdbName) throws Throwable {
71 if(cpuTime != null && cpuTime.lastValue != null) 138 return colPdbCPU.getCurrentValue(pdbName + strCpuTime);
72 return cpuTime.curValue - cpuTime.lastValue; 139 }
73 else 140
74 return 0; 141 public long getCPURawDiff() throws Throwable {
142 return cpuTime.getDelta();
143 }
144 public long getCPURawDiff(String pdbName) throws Throwable {
145 return colPdbCPU.getDelta(pdbName + strCpuTime);
75 } 146 }
76 147
77 public double getCPUTimePerSecond() throws Throwable { 148 public double getCPUTimePerSecond() throws Throwable {
78 return cpuTime.getPerSecondValue(); 149 return cpuTime.getPerSecondValue();
79 } 150 }
151 public double getCPUTimePerSecond(String pdbName) throws Throwable {
152 return colPdbCPU.getPerSecValue(pdbName + strCpuTime);
153 }
80 154
81 public double getPerSecondValue(String name) throws Throwable { 155 public double getPerSecondValue(String name) throws Throwable {
82 return getPerSecondValue(name, SYSSTAT); 156 return getPerSecondValue(name, SYSSTAT, null);
83 } 157 }
84 158
85 public double getPerSecondValue(String name, int table) throws Throwable { 159 public double getPerSecondValue(String name, int table) throws Throwable {
160 return getPerSecondValue(name, table, null);
161 }
162
163 public double getPerSecondValue(String name, String pdbName) throws Throwable {
164 return getPerSecondValue(name, SYSSTAT, pdbName);
165 }
166
167 public double getPerSecondValue(String name, int table, String pdbName) throws Throwable {
86 switch (table) { 168 switch (table) {
87 case OSSTAT: 169 case OSSTAT:
88 return colOsStat.getPerSecValue(name); 170 return colOsStat.getPerSecValue(name);
89 case SYSSTAT: 171 case SYSSTAT:
90 return colSysStat.getPerSecValue(name); 172 if(pdbName == null)
173 return colSysStat.getPerSecValue(name);
174 else
175 return colPdbSysStat.getPerSecValue(pdbName + strSeparator + name);
91 default: 176 default:
92 return colSysStat.getPerSecValue(name); 177 return colSysStat.getPerSecValue(name);
93 } 178 }
94 } 179 }
95 180
96 public String getDBName() { 181 public String getDBName() {
182 // Returns the instance name unless we are a PDB, in that case the service name from the con string is returned instead.
97 return this.dbName; 183 return this.dbName;
98 } 184 }
99 185
186 public String getFriendlyName() {
187 return getFriendlyName(null);
188 }
189
190 public String getFriendlyName(String pdbName) {
191 // Returns a friendly name of the database, either the service name from con string or the database name from the instance
192 getServiceName();
193 if(pdbName != null) {
194 if(this.serviceName != null) return this.serviceName + ":" + pdbName;
195 else return this.dbName + ":" + pdbName;
196 } else {
197 if(this.serviceName != null) return this.serviceName;
198 else return this.dbName;
199 }
200 }
201
100 public double getOsBusyPercent() throws Throwable { 202 public double getOsBusyPercent() throws Throwable {
101 double idle = getPerSecondValue("IDLE_TIME", OSSTAT); 203 double idle = getPerSecondValue("IDLE_TIME", OSSTAT);
102 double busy = getPerSecondValue("BUSY_TIME", OSSTAT); 204 double busy = getPerSecondValue("BUSY_TIME", OSSTAT);
...@@ -124,9 +226,23 @@ public class OraMon { ...@@ -124,9 +226,23 @@ public class OraMon {
124 } 226 }
125 227
126 public double getBufferCacheHitRatioPercent() throws Throwable { 228 public double getBufferCacheHitRatioPercent() throws Throwable {
127 double conGetsCache = getPerSecondValue("consistent gets from cache"); 229 return getBufferCacheHitRatioPercent(null);
128 double dbBlocksCache = getPerSecondValue("db block gets from cache"); 230 }
129 double physReadsCache = getPerSecondValue("physical reads cache"); 231 public double getBufferCacheHitRatioPercent(String pdbName) throws Throwable {
232 double conGetsCache;
233 double dbBlocksCache;
234 double physReadsCache;
235
236 if(pdbName == null) {
237 conGetsCache = getPerSecondValue("consistent gets from cache");
238 dbBlocksCache = getPerSecondValue("db block gets from cache");
239 physReadsCache = getPerSecondValue("physical reads cache");
240 } else {
241 conGetsCache = colPdbSysStat.getPerSecValue(pdbName + strSeparator + "consistent gets from cache");
242 dbBlocksCache = colPdbSysStat.getPerSecValue(pdbName + strSeparator + "db block gets from cache");
243 physReadsCache = colPdbSysStat.getPerSecValue(pdbName + strSeparator + "physical reads cache");
244 }
245
130 if (conGetsCache + dbBlocksCache + physReadsCache == 0) { 246 if (conGetsCache + dbBlocksCache + physReadsCache == 0) {
131 return 100; 247 return 100;
132 } 248 }
...@@ -142,9 +258,23 @@ public class OraMon { ...@@ -142,9 +258,23 @@ public class OraMon {
142 } 258 }
143 259
144 public double getCacheHitRatioPercent() throws Throwable { 260 public double getCacheHitRatioPercent() throws Throwable {
145 double conGets = getPerSecondValue("consistent gets"); 261 return getCacheHitRatioPercent(null);
146 double dbBlocks = getPerSecondValue("db block gets"); 262 }
147 double physReads = getPerSecondValue("physical reads"); 263 public double getCacheHitRatioPercent(String pdbName) throws Throwable {
264 double conGets;
265 double dbBlocks;
266 double physReads;
267
268 if(pdbName == null) {
269 conGets = getPerSecondValue("consistent gets");
270 dbBlocks = getPerSecondValue("db block gets");
271 physReads = getPerSecondValue("physical reads");
272 } else {
273 conGets = colPdbSysStat.getPerSecValue(pdbName + strSeparator + "consistent gets");
274 dbBlocks = colPdbSysStat.getPerSecValue(pdbName + strSeparator + "db block gets");
275 physReads = colPdbSysStat.getPerSecValue(pdbName + strSeparator + "physical reads");
276 }
277
148 if (conGets + dbBlocks + physReads == 0) { 278 if (conGets + dbBlocks + physReads == 0) {
149 return 100; 279 return 100;
150 } 280 }
...@@ -159,7 +289,13 @@ public class OraMon { ...@@ -159,7 +289,13 @@ public class OraMon {
159 } 289 }
160 290
161 public double getLogicalReadsPerSecond() throws Throwable { 291 public double getLogicalReadsPerSecond() throws Throwable {
162 return getPerSecondValue("consistent gets") + getPerSecondValue("db block gets"); 292 return getLogicalReadsPerSecond(null);
293 }
294 public double getLogicalReadsPerSecond(String pdbName) throws Throwable {
295 if(pdbName == null)
296 return getPerSecondValue("consistent gets") + getPerSecondValue("db block gets");
297 else
298 return colPdbSysStat.getPerSecValue(pdbName + strSeparator + "consistent gets") + colPdbSysStat.getPerSecValue(pdbName + strSeparator + "db block gets");
163 } 299 }
164 300
165 long lastRTns = 0; 301 long lastRTns = 0;
...@@ -168,19 +304,31 @@ public class OraMon { ...@@ -168,19 +304,31 @@ public class OraMon {
168 } 304 }
169 305
170 long lastFetchTSns = 0; 306 long lastFetchTSns = 0;
171 public boolean getData(long ageTs) throws Throwable {
172 if ((System.nanoTime() - lastFetchTSns) > (ageTs * 1000 * 1000 * 1000)) return getData();
173 else return false;
174 }
175 307
176 public long getAgeTs() { 308 public long getAgeTs() {
177 return (System.nanoTime() - lastFetchTSns)/(1000*1000*1000); 309 return (System.nanoTime() - lastFetchTSns)/(1000*1000*1000);
178 } 310 }
179 311
312 public boolean getData() throws Throwable {
313 return getData(0, null);
314 }
315
316 public boolean getData(long ageTs) throws Throwable {
317 return getData(ageTs, null);
318 }
319
180 Lock lock = new ReentrantLock(); 320 Lock lock = new ReentrantLock();
181 Throwable lastEx = null; 321 Throwable lastEx = null;
182 322
183 public boolean getData() throws Throwable { 323 public boolean getData(long ageTs, String pdbName) throws Throwable {
324 //Check age (unless pdbName was set for the first time, in that case we need to discard the cached data)
325 if(getPdbs == false && pdbName != null) {
326 getPdbs = true;
327 }
328 else {
329 if ((System.nanoTime() - lastFetchTSns) < (ageTs * 1000 * 1000 * 1000)) return false;
330 }
331
184 // Start thread safe 332 // Start thread safe
185 // Try to get a lock 333 // Try to get a lock
186 boolean haveLock = lock.tryLock(); 334 boolean haveLock = lock.tryLock();
...@@ -194,6 +342,7 @@ public class OraMon { ...@@ -194,6 +342,7 @@ public class OraMon {
194 return false; 342 return false;
195 } 343 }
196 // We do have the lock. Do the rest in a try catch everything and if we catch anything, re throw the catch but always release the lock. 344 // We do have the lock. Do the rest in a try catch everything and if we catch anything, re throw the catch but always release the lock.
345 Statement stmt = null;
197 try { 346 try {
198 long startTSns = System.nanoTime(); 347 long startTSns = System.nanoTime();
199 getDataCalls++; 348 getDataCalls++;
...@@ -210,10 +359,10 @@ public class OraMon { ...@@ -210,10 +359,10 @@ public class OraMon {
210 if(stale) { 359 if(stale) {
211 open(); 360 open();
212 } 361 }
213 Statement stmt = conn.createStatement(); 362 stmt = conn.createStatement();
214 ResultSet rset = null; 363 ResultSet rset = null;
215 364
216 //Get the database name once 365 //Get the database name once // Currently always gets the CDB name
217 if(this.dbName == null) { 366 if(this.dbName == null) {
218 rset = stmt.executeQuery("select value from V$SYSTEM_PARAMETER where name = 'db_name'"); 367 rset = stmt.executeQuery("select value from V$SYSTEM_PARAMETER where name = 'db_name'");
219 rset.next(); 368 rset.next();
...@@ -221,28 +370,47 @@ public class OraMon { ...@@ -221,28 +370,47 @@ public class OraMon {
221 rset.close(); 370 rset.close();
222 } 371 }
223 372
373 // All other cases (CDB or an instance without containers) get the data from the database
374
224 //Get the entire V_$OSSTAT table from DB 375 //Get the entire V_$OSSTAT table from DB
225 colOsStat.update(stmt.executeQuery("select systimestamp, stat_name, value from V$OSSTAT")); 376 colOsStat.update(stmt.executeQuery("select systimestamp, stat_name, value from V$OSSTAT"));
226 377
227 //Set numCpus 378 //Set numCpus
228 this.numCpus = (int) colOsStat.getCurrentValue("NUM_CPUS"); 379 this.numCpus = (int) colOsStat.getCurrentValue("NUM_CPUS");
229 380
381 // Get OS Load
382 osLoad.update(stmt.executeQuery("select systimestamp, value from V$OSSTAT where stat_name='LOAD'"));
383
230 // Get DB CPU use time 384 // Get DB CPU use time
231 rset = stmt.executeQuery("select systimestamp, s.value as NIWT, t.value as DBCPU from V$SYSSTAT s, V$SYS_TIME_MODEL t where s.name='non-idle wait time' and t.STAT_NAME='DB CPU'"); 385 rset = stmt.executeQuery("select systimestamp, s.value as NIWT, t.value as DBCPU from V$SYSSTAT s, V$SYS_TIME_MODEL t where s.name='non-idle wait time' and t.STAT_NAME='DB CPU'");
232 rset.next(); 386 rset.next();
233 niwTime.update(rset.getLong(2), rset.getTimestamp(1)); 387 niwTime.update(rset.getLong(2), rset.getTimestamp(1));
234 cpuTime.update(rset.getLong(3), rset.getTimestamp(1)); 388 cpuTime.update(rset.getLong(3), rset.getTimestamp(1));
235 rset.close(); 389 rset.close();
236
237 // cpuTime.update(stmt.executeQuery("select systimestamp, value from V$SYS_TIME_MODEL where stat_name='DB CPU'"));
238 // niwTime.update(stmt.executeQuery("select systimestamp, value from V$SYSSTAT where name='non-idle wait time'"));
239
240 // Get OS Load
241 osLoad.update(stmt.executeQuery("select systimestamp, value from V$OSSTAT where stat_name='LOAD'"));
242 390
243 //Get the entire V_$SYSSTAT table from DB 391 //Get the entire V_$SYSSTAT table from DB
244 colSysStat.update(stmt.executeQuery("select systimestamp, name, value from V$SYSSTAT")); 392 colSysStat.update(stmt.executeQuery("select systimestamp, name, value from V$SYSSTAT"));
245 393
394 //Get PDB specific data if getPDB is set to true
395 if(getPdbs) {
396 //CPU
397 if(colPdbCPU == null) colPdbCPU = new Collector();
398 rset = stmt.executeQuery("select systimestamp, c.NAME, s.value as NIWT, t.value as DBCPU from V$CON_SYSSTAT s, V$CON_SYS_TIME_MODEL t, V$CONTAINERS c where s.CON_ID=t.CON_ID and s.CON_ID=c.CON_ID and s.name='non-idle wait time' and t.STAT_NAME='DB CPU'");
399 while(rset.next()) {
400 Timestamp ts = rset.getTimestamp(1);
401 String name = rset.getString(2);
402 colPdbCPU.updateValue(ts, name + strNiwTime, rset.getLong(3));
403 colPdbCPU.updateValue(ts, name + strCpuTime, rset.getLong(4));
404 if(pdbSet == null) pdbSet = new HashSet<String>();
405 pdbSet.add(name);
406 }
407 rset.close();
408
409 //SYSSTATS
410 if(colPdbSysStat == null) colPdbSysStat = new Collector();
411 colPdbSysStat.update(stmt.executeQuery("select systimestamp, c.NAME || '" + strSeparator + "' || s.name, s.value from V$CON_SYSSTAT s, V$CONTAINERS c where s.CON_ID=c.CON_ID"));
412 }
413
246 stmt.close(); 414 stmt.close();
247 getDataSucess++; 415 getDataSucess++;
248 lastFetchTSns = System.nanoTime(); 416 lastFetchTSns = System.nanoTime();
...@@ -253,6 +421,13 @@ public class OraMon { ...@@ -253,6 +421,13 @@ public class OraMon {
253 Throwable thisCause = e; 421 Throwable thisCause = e;
254 while(lastCause != null) { thisCause = lastCause; lastCause = thisCause.getCause(); } 422 while(lastCause != null) { thisCause = lastCause; lastCause = thisCause.getCause(); }
255 lastEx = thisCause; 423 lastEx = thisCause;
424 // Close the connection and statement to prevent memory leaks
425 try {
426 stmt.close();
427 conn.close();
428 } catch (Exception e2) {
429 // Dont care
430 }
256 throw (e); 431 throw (e);
257 } finally { 432 } finally {
258 lock.unlock(); 433 lock.unlock();
......
...@@ -11,13 +11,69 @@ public class TestRunner { ...@@ -11,13 +11,69 @@ public class TestRunner {
11 /** 11 /**
12 * @param args 12 * @param args
13 */ 13 */
14 public static void main(String[] args) throws Throwable{ 14 public static void main(String[] args) throws Throwable {
15 //runner1();
16 //test1();
17 //testTns();
18 testPDB();
19 }
20
21 public static void testPDB() throws Throwable {
22 OraMon cdb = new OraMon("jdbc:oracle:thin:@//u03634.kap.rsv.se:1526/DB1K12","dbsnmp","dbsnmp"); // CDB
23 OraMon pdb = new OraMon("jdbc:oracle:thin:@//u03634.kap.rsv.se:1526/DA1K001","dbsnmp","dbsnmp"); // PDB
24
25 int times = 5;
26 while(times-- > 0) {
27 cdb.getData(0, "DA1K001");
28 pdb.getData();
29
30 System.out.println("PDB CPU: " + pdb.getCPUPercent());
31 System.out.println("CDB CPU: " + cdb.getCPUPercent());
32 System.out.println("DA1K001: " + cdb.getCPUPercent(false, "DA1K001"));
33 System.out.println("DA1K002: " + cdb.getCPUPercent(false, "DA1K002"));
34 System.out.println("TOTAL : " + (cdb.getCPUPercent(false, "DA1K001") + cdb.getCPUPercent(false, "DA1K002")));
35
36 System.out.println("PDB LIO: " + pdb.getLogicalReadsPerSecond());
37 System.out.println("CDB LIO: " + cdb.getLogicalReadsPerSecond());
38 System.out.println("DA1K001: " + cdb.getLogicalReadsPerSecond("DA1K001"));
39 System.out.println("DA1K002: " + cdb.getLogicalReadsPerSecond("DA1K002"));
40 System.out.println("TOTAL : " + (cdb.getLogicalReadsPerSecond("DA1K001") + cdb.getLogicalReadsPerSecond("DA1K002")));
41
42 System.out.println("Sleeping 15s\n");
43 Thread.sleep(60000);
44 }
45 cdb.close();
46 pdb.close();
47 }
48
49 public static void test1() throws Throwable {
50 OraMon mon = new OraMon("jdbc:oracle:thin:@//u02822.kap.rsv.se:1526/DB1K06","dbsnmp","dbsnmp"); // CDB
51 System.out.println("getData returned: " + mon.getData());
52 System.out.println("getDatabaseName: " + mon.getDBName());
53 }
54
55 public static void testTns() throws Throwable {
56 //OraMon mon = new OraMon("jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(Host=u00153.kap.rsv.se)(Port=1526))(ADDRESS=(PROTOCOL=TCP)(Host=u00154.kap.rsv.se)(Port=1526)))(CONNECT_DATA=(SERVICE_NAME=PB1K001)))","dbsnmp","dbsnmp"); // PDB using TNS
57 OraMon mon = new OraMon("jdbc:oracle:thin:@//u00153.kap.rsv.se:1526/DB1K01","dbsnmp","dbsnmp");
58 System.out.println("getData returned: " + mon.getData());
59 System.out.println("getDatabaseName: " + mon.getDBName());
60 System.out.println("getServiceName: " + mon.getServiceName());
61 System.out.println("getFriendlyName: " + mon.getFriendlyName());
62 System.out.println("getConString: " + mon.getConString());
63 System.out.println("getNumberOfCPUs: " + mon.getNumberOfCPUs());
64 }
65
66 public static void runner1() throws Throwable {
15 // TODO Auto-generated method stub 67 // TODO Auto-generated method stub
16 68
17 //ArrayList<OraMon> oraList = new ArrayList<OraMon>(); 69 //ArrayList<OraMon> oraList = new ArrayList<OraMon>();
18 ArrayList<OraMon> oraList = Registry.getList(); 70 ArrayList<OraMon> oraList = Registry.getList();
19 71
20 OraMon mon1 = new OraMon("jdbc:oracle:thin:@uvp3dbkappkg:1550:VP1K03","dbsnmp","dbsnmp"); // SID eller Service Name format 72 //OraMon mon1 = new OraMon("jdbc:oracle:thin:@uvp3dbkappkg:1550:VP1K03","dbsnmp","dbsnmp"); // SID eller Service Name format
73 //OraMon mon1 = new OraMon("jdbc:oracle:thin:@//u00154.kap.rsv.se:1526/DB1K01","dbsnmp","dbsnmp");
74 //OraMon mon1 = new OraMon("jdbc:oracle:thin:@//u03634.kap.rsv.se:1526/DA1K001","dbsnmp","dbsnmp"); // PDB, CDB är DB1K12
75 //OraMon mon1 = new OraMon("jdbc:oracle:thin:@//u03634.kap.rsv.se:1526/DA1K002","dbsnmp","dbsnmp"); // Andra PDB på CDB DB1K12
76 OraMon mon1 = new OraMon("jdbc:oracle:thin:@//u03634.kap.rsv.se:1526/DB1K12","dbsnmp","dbsnmp"); // PDB, CDB är DB1K12
21 //OraMon mon2 = new OraMon("jdbc:oracle:thin:@host:port:sid","user","pass"); // SID format 77 //OraMon mon2 = new OraMon("jdbc:oracle:thin:@host:port:sid","user","pass"); // SID format
22 mon1.open(); 78 mon1.open();
23 //mon2.open(); 79 //mon2.open();
......