Commit 21aac603 21aac6038a239c9b8422c7d264a911b9bf70be20 by Christian Gerdes

Partially working PDB support. Some bugs left to fix.

1 parent 431a092d
......@@ -43,21 +43,25 @@ if(request.getParameter("action") != null) {
<% } %>
<script type="text/javascript">
function getData(type, input) {
function getData(type, input, pdb) {
// Update the data
var pdbAdd = "";
if(pdb != "" && pdb != null) pdbAdd = "&pdbName=" + pdb;
var client1 = new XMLHttpRequest();
client1.onreadystatechange = dataHandler;
client1.open("GET", "/" + type + "/getData?age=14&connectionString=" + encodeURIComponent(input));
client1.open("GET", "/" + type + "/getData?age=14" + pdbAdd + "&connectionString=" + encodeURIComponent(input));
client1.setRequestHeader('Cache-Control', 'no-cache');
client1.setRequestHeader('Pragma', 'no-cache');
client1.send();
}
function getMetrics(type, input) {
function getMetrics(type, input, pdb) {
// Get the metrics
var pdbAdd = "";
if(pdb != "" && pdb != null) pdbAdd = "pdbName=" + pdb + "&";
var client2 = new XMLHttpRequest();
client2.onreadystatechange = metricsHandler;
client2.open("GET", "/" + type + "/getMetrics?connectionString=" + encodeURIComponent(input));
client2.open("GET", "/" + type + "/getMetrics?" + pdbAdd + "connectionString=" + encodeURIComponent(input));
client2.setRequestHeader('Cache-Control', 'no-cache');
client2.setRequestHeader('Pragma', 'no-cache');
client2.send();
......@@ -117,8 +121,9 @@ function dataHandler() {
<input type="submit" name="action" value="remove" >
<input type="hidden" name="omconstr" value="<%= mon.getConString() %>">
<input type="button" value="graph" onClick="window.open('/viewOraMon.html?<%= URLEncoder.encode(mon.getConString(), "UTF-8") %>')">
<input id="getDataButton" type="button" value="getData" onClick="getData('OraMonREST', '<%= mon.getConString() %>')">
<input id="getMetricsButton" type="button" value="getMetrics" onClick="getMetrics('OraMonREST', '<%= mon.getConString() %>')">
<input id="getDataButton" type="button" value="getData" onClick="getData('OraMonREST', '<%= mon.getConString() %>',this.form.pdbName.value)">
<input id="getMetricsButton" type="button" value="getMetrics" onClick="getMetrics('OraMonREST', '<%= mon.getConString() %>',this.form.pdbName.value)">
<input id="pdbName" name="pdbName" size="10">
</form>
</td>
</tr>
......
No preview for this file type
......@@ -124,10 +124,16 @@ public class OraMonRESTgetData extends HttpServlet {
monitor = Registry.findOrCreate(conStr, usrStr, pwdStr);
}
String pdbName = null;
if(request.getParameterMap().containsKey("pdbName")) {
String temp = request.getParameter("pdbName");
if (!temp.isEmpty()) pdbName = temp;
}
if(monitor != null) {
// Call getData()
boolean didUpdate = monitor.getData(age);
String dbName = monitor.getFriendlyName();
boolean didUpdate = monitor.getData(age,pdbName);
String dbName = monitor.getFriendlyName(pdbName);
if(didUpdate) {
sb.append("{\"error\":false,\"msg\":\"Sucessfully collected data on '" + dbName + "'\"");
sb.append(",\"ms\":"+monitor.getLastRTms()+"}");
......
import java.io.IOException;
import java.util.ArrayList;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
......@@ -32,13 +31,13 @@ public class OraMonRESTgetMetrics extends HttpServlet {
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("application/json");
OraMon monitor = null;
try {
StringBuffer sb = new StringBuffer();
ArrayList<OraMon> list = Registry.getList();
if(request.getParameterMap().containsKey("connectionString")) {
// We have a connection string, find the monitor and report only on that monitor
OraMon monitor = null;
if(request.getParameter("connectionString").startsWith("jdbc:oracle")) {
// Full con string
String[] shortConArray = request.getParameter("connectionString").split("@");
......@@ -107,59 +106,60 @@ public class OraMonRESTgetMetrics extends HttpServlet {
conStr = "jdbc:oracle:thin:@" + conStrParamArray[0] + ":" + conStrParamArray[1] + ":" + conStrParamArray[2];
}
monitor = Registry.find(conStr);
}
}
if(monitor == null) {
// Not found, create it
// Not found, response with 404
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
response.getWriter().println("{\"error\":true,\"msg\":\"Can not find a monitor with connection string "+request.getParameter("connectionString")+"\"}");
return;
}
}
// Set this monitor to the only one on the list
list = new ArrayList<OraMon>();
list.add(monitor);
String pdbName = null;
if(request.getParameterMap().containsKey("pdbName")) {
String temp = request.getParameter("pdbName");
if (!temp.isEmpty()) pdbName = temp;
}
// Loop over all monitors and output a Json array with the default set of metrics
for (OraMon item : list) {
sb.append("{\"name\":\"" + item.getFriendlyName() + "\",\"error\":false,\"nvarray\":");
// Write out the monitors data
sb.append("{\"name\":\"" + monitor.getFriendlyName(pdbName) + "\",\"error\":false,\"nvarray\":");
sb.append("[");
sb.append("{\"name\":\"Cpu Usage (%)\",\"value\":" + item.getCPUPercent() + "}");
sb.append(",{\"name\":\"Logical Reads (#/s)\",\"value\":" + item.getLogicalReadsPerSecond() + "}");
sb.append(",{\"name\":\"Executes (#/s)\",\"value\":" + item.getPerSecondValue("execute count") + "}");
sb.append(",{\"name\":\"User Calls (#/s)\",\"value\":" + item.getPerSecondValue("user calls") + "}");
sb.append(",{\"name\":\"Cache Hit Ratio (%)\",\"value\":" + item.getCacheHitRatioPercent() + "}");
sb.append(",{\"name\":\"Redo Size (#/s)\",\"value\":" + item.getPerSecondValue("redo size") + "}");
sb.append("{\"name\":\"Cpu Usage (%)\",\"value\":" + monitor.getCPUPercent(pdbName) + "}");
sb.append(",{\"name\":\"Logical Reads (#/s)\",\"value\":" + monitor.getLogicalReadsPerSecond(pdbName) + "}");
sb.append(",{\"name\":\"Executes (#/s)\",\"value\":" + monitor.getPerSecondValue("execute count",pdbName) + "}");
sb.append(",{\"name\":\"User Calls (#/s)\",\"value\":" + monitor.getPerSecondValue("user calls",pdbName) + "}");
sb.append(",{\"name\":\"Cache Hit Ratio (%)\",\"value\":" + monitor.getCacheHitRatioPercent(pdbName) + "}");
sb.append(",{\"name\":\"Redo Size (#/s)\",\"value\":" + monitor.getPerSecondValue("redo size",pdbName) + "}");
sb.append(",{\"name\":\"OS Busy (%)\",\"value\":" + item.getOsBusyPercent() + "}");
sb.append(",{\"name\":\"OS Load (#)\",\"value\":" + item.getOsLoad() + "}");
sb.append(",{\"name\":\"OS Page In (KB/s)\",\"value\":" + item.getPerSecondValue("VM_IN_BYTES", OraMon.OSSTAT)/1024 + "}");
sb.append(",{\"name\":\"OS Page Out (KB/s)\",\"value\":" + item.getPerSecondValue("VM_OUT_BYTES", OraMon.OSSTAT)/1024 + "}");
sb.append(",{\"name\":\"OS Load per Cpu (#)\",\"value\":" + item.getOsLoadPerCPU() + "}");
sb.append(",{\"name\":\"OS Busy (%)\",\"value\":" + monitor.getOsBusyPercent() + "}");
sb.append(",{\"name\":\"OS Load (#)\",\"value\":" + monitor.getOsLoad() + "}");
sb.append(",{\"name\":\"OS Page In (KB/s)\",\"value\":" + monitor.getPerSecondValue("VM_IN_BYTES", OraMon.OSSTAT)/1024 + "}");
sb.append(",{\"name\":\"OS Page Out (KB/s)\",\"value\":" + monitor.getPerSecondValue("VM_OUT_BYTES", OraMon.OSSTAT)/1024 + "}");
sb.append(",{\"name\":\"OS Load per Cpu (#)\",\"value\":" + monitor.getOsLoadPerCPU() + "}");
sb.append(",{\"name\":\"Consistent Gets (#/s)\",\"value\":" + item.getPerSecondValue("consistent gets") + "}");
sb.append(",{\"name\":\"DB Block Gets (#/s)\",\"value\":" + item.getPerSecondValue("db block gets") + "}");
sb.append(",{\"name\":\"Consistent Gets (#/s)\",\"value\":" + monitor.getPerSecondValue("consistent gets",pdbName) + "}");
sb.append(",{\"name\":\"DB Block Gets (#/s)\",\"value\":" + monitor.getPerSecondValue("db block gets",pdbName) + "}");
sb.append(",{\"name\":\"Buffer Cache Hit Ratio (%)\",\"value\":" + item.getBufferCacheHitRatioPercent() + "}");
sb.append(",{\"name\":\"DB Block Changes (#/s)\",\"value\":" + item.getPerSecondValue("db block changes") + "}");
sb.append(",{\"name\":\"Buffer Cache Hit Ratio (%)\",\"value\":" + monitor.getBufferCacheHitRatioPercent(pdbName) + "}");
sb.append(",{\"name\":\"DB Block Changes (#/s)\",\"value\":" + monitor.getPerSecondValue("db block changes",pdbName) + "}");
sb.append(",{\"name\":\"Physical Reads (#/s)\",\"value\":" + item.getPerSecondValue("physical reads") + "}");
sb.append(",{\"name\":\"Physical Writes (#/s)\",\"value\":" + item.getPerSecondValue("physical writes") + "}");
sb.append(",{\"name\":\"Redo Writes (#/s)\",\"value\":" + item.getPerSecondValue("redo writes") + "}");
sb.append(",{\"name\":\"Non-idle Wait Time (ms/s)\",\"value\":" + item.getPerSecondValue("non-idle wait time") + "}");
sb.append(",{\"name\":\"File I/O Wait Time (ms/s)\",\"value\":" + item.getPerSecondValue("file io wait time") + "}");
sb.append(",{\"name\":\"Physical Reads (#/s)\",\"value\":" + monitor.getPerSecondValue("physical reads",pdbName) + "}");
sb.append(",{\"name\":\"Physical Writes (#/s)\",\"value\":" + monitor.getPerSecondValue("physical writes",pdbName) + "}");
sb.append(",{\"name\":\"Redo Writes (#/s)\",\"value\":" + monitor.getPerSecondValue("redo writes",pdbName) + "}");
sb.append(",{\"name\":\"Non-idle Wait Time (ms/s)\",\"value\":" + monitor.getPerSecondValue("non-idle wait time",pdbName) + "}");
sb.append(",{\"name\":\"File I/O Wait Time (ms/s)\",\"value\":" + monitor.getPerSecondValue("file io wait time",pdbName) + "}");
sb.append(",{\"name\":\"User Commits (#/s)\",\"value\":" + monitor.getPerSecondValue("user commits",pdbName) + "}");
sb.append(",{\"name\":\"User Rollbacks (#/s)\",\"value\":" + monitor.getPerSecondValue("user rollbacks",pdbName) + "}");
sb.append(",{\"name\":\"Parse Count Total (#/s)\",\"value\":" + monitor.getPerSecondValue("parse count (total)",pdbName) + "}");
sb.append(",{\"name\":\"Parse Count Hard (#/s)\",\"value\":" + monitor.getPerSecondValue("parse count (hard)",pdbName) + "}");
sb.append(",{\"name\":\"Cpu Usage xNIWT (%)\",\"value\":" + monitor.getCPUPercent(true,pdbName) + "}");
sb.append(",{\"name\":\"Cpu Time (us/s)\",\"value\":" + monitor.getCPUTimePerSecond(pdbName) + "}");
sb.append(",{\"name\":\"Cpus (#)\",\"value\":" + monitor.getNumberOfCPUs() + "}");
sb.append(",{\"name\":\"User Commits (#/s)\",\"value\":" + item.getPerSecondValue("user commits") + "}");
sb.append(",{\"name\":\"User Rollbacks (#/s)\",\"value\":" + item.getPerSecondValue("user rollbacks") + "}");
sb.append(",{\"name\":\"Parse Count Total (#/s)\",\"value\":" + item.getPerSecondValue("parse count (total)") + "}");
sb.append(",{\"name\":\"Parse Count Hard (#/s)\",\"value\":" + item.getPerSecondValue("parse count (hard)") + "}");
sb.append(",{\"name\":\"Cpu Usage xNIWT (%)\",\"value\":" + item.getCPUPercent(true) + "}");
sb.append(",{\"name\":\"Cpu Time (us/s)\",\"value\":" + item.getCPUTimePerSecond() + "}");
sb.append(",{\"name\":\"Cpus (#)\",\"value\":" + item.getNumberOfCPUs() + "}");
}
sb.append("]}");
response.getWriter().println(sb.toString());
......
......@@ -55,4 +55,8 @@ DA1K001: 435343.22211814864
DA1K002: 9.075934239850135
TOTAL : 435352.2980523885
Här känns alla värden rätt.
\ No newline at end of file
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.
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.
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
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
......
package se.lil.om;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Properties;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
......@@ -29,10 +28,21 @@ public class OraMon {
boolean getPdbs = false;
Collector colPdbSysStat = null;
Collector colPdbCPU = null;
HashSet<String> pdbSet = null;
public static final String strCpuTime = " cputime";
public static final String strNiwTime = " niwtime";
public static final String strSeparator = " ";
public int getNumPdbs() {
if(pdbSet != null) return pdbSet.size();
else return 0;
}
public String[] getPdbArray() {
if(pdbSet != null) return (String[]) pdbSet.toArray();
else return null;
}
public int getDataCalled() {
return getDataCalls;
}
......@@ -150,6 +160,10 @@ public class OraMon {
return getPerSecondValue(name, table, null);
}
public double getPerSecondValue(String name, String pdbName) throws Throwable {
return getPerSecondValue(name, SYSSTAT, pdbName);
}
public double getPerSecondValue(String name, int table, String pdbName) throws Throwable {
switch (table) {
case OSSTAT:
......@@ -170,11 +184,20 @@ public class OraMon {
}
public String getFriendlyName() {
return getFriendlyName(null);
}
public String getFriendlyName(String pdbName) {
// Returns a friendly name of the database, either the service name from con string or the database name from the instance
getServiceName();
if(pdbName != null) {
if(this.serviceName != null) return this.serviceName + ":" + pdbName;
else return this.dbName + ":" + pdbName;
} else {
if(this.serviceName != null) return this.serviceName;
else return this.dbName;
}
}
public double getOsBusyPercent() throws Throwable {
double idle = getPerSecondValue("IDLE_TIME", OSSTAT);
......@@ -374,8 +397,12 @@ public class OraMon {
if(colPdbCPU == null) colPdbCPU = new Collector();
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'");
while(rset.next()) {
colPdbCPU.updateValue(rset.getTimestamp(1), rset.getString(2) + strNiwTime, rset.getLong(3));
colPdbCPU.updateValue(rset.getTimestamp(1), rset.getString(2) + strCpuTime, rset.getLong(4));
Timestamp ts = rset.getTimestamp(1);
String name = rset.getString(2);
colPdbCPU.updateValue(ts, name + strNiwTime, rset.getLong(3));
colPdbCPU.updateValue(ts, name + strCpuTime, rset.getLong(4));
if(pdbSet == null) pdbSet = new HashSet<String>();
pdbSet.add(name);
}
rset.close();
......