Commit 5791fcf8 5791fcf89475b719072dd502953a59222e94d735 by Christian Gerdes
2 parents 19f030f3 21aac603
......@@ -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
No preview for this file type
......@@ -53,27 +53,44 @@ public class OraMonRESTgetData extends HttpServlet {
if(shortConArray.length != 2) {
// Error, wrong format of string
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
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.\"}");
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.\"}");
return;
}
String[] shortConArray2 = shortConArray[1].split(":");
if(shortConArray2[0].startsWith("//") && shortConArray2.length == 4) {
// We have new style and username and password, we can try to create the monitor if it doesnt exist
monitor = Registry.findOrCreate(shortConArray[0] + "@" + shortConArray2[0] + ":" + shortConArray2[1], shortConArray2[2], shortConArray2[3]);
} else if(!shortConArray2[0].startsWith("//") && shortConArray2.length == 5) {
// We have old style with sid with :username:password, try to find or create it
monitor = Registry.findOrCreate(shortConArray[0] + "@" + shortConArray2[0] + ":" + shortConArray2[1] + ":" + shortConArray2[2], shortConArray2[3], shortConArray2[4]);
} else if(shortConArray2[0].startsWith("//") && shortConArray2.length == 2) {
// We have new style but only have the connection string, try to find it (we cant create one without username/password)
monitor = Registry.find(request.getParameter("connectionString"));
} else if(!shortConArray2[0].startsWith("//") && shortConArray2.length == 3) {
// We have old style sid and no :username:password
monitor = Registry.find(request.getParameter("connectionString"));
if(shortConArray2[0].startsWith("(")) {
// TNS Format
if(shortConArray2.length == 3) {
// We have a TNS connection string and username + password
monitor = Registry.findOrCreate(shortConArray[0] + "@" + shortConArray2[0], shortConArray2[1], shortConArray2[2]);
} else if (shortConArray2.length == 1) {
// We only have the TNS connection string, no username or password
monitor = Registry.find(shortConArray[0] + "@" + shortConArray2[0]);
} else {
// We have something else, not implemented
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
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.\"}");
return;
}
} else {
// Wrong format
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
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.\"}");
return;
// JDBC Format
if(shortConArray2[0].startsWith("//") && shortConArray2.length == 4) {
// We have new style and username and password, we can try to create the monitor if it doesnt exist
monitor = Registry.findOrCreate(shortConArray[0] + "@" + shortConArray2[0] + ":" + shortConArray2[1], shortConArray2[2], shortConArray2[3]);
} else if(!shortConArray2[0].startsWith("//") && shortConArray2.length == 5) {
// We have old style with sid with :username:password, try to find or create it
monitor = Registry.findOrCreate(shortConArray[0] + "@" + shortConArray2[0] + ":" + shortConArray2[1] + ":" + shortConArray2[2], shortConArray2[3], shortConArray2[4]);
} else if(shortConArray2[0].startsWith("//") && shortConArray2.length == 2) {
// We have new style but only have the connection string, try to find it (we cant create one without username/password)
monitor = Registry.find(request.getParameter("connectionString"));
} else if(!shortConArray2[0].startsWith("//") && shortConArray2.length == 3) {
// We have old style sid and no :username:password
monitor = Registry.find(request.getParameter("connectionString"));
} else {
// Wrong format
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
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.\"}");
return;
}
}
} else {
// Short con string
......@@ -94,7 +111,7 @@ public class OraMonRESTgetData extends HttpServlet {
}
String conStr, usrStr, pwdStr;
if(serviceName) {
conStr = "jdbc:oracle:thin:@" + conStrParamArray[0] + ":" + conStrParamArray[1];
conStr = "jdbc:oracle:thin:@//" + conStrParamArray[0] + ":" + conStrParamArray[1];
usrStr = conStrParamArray[2];
pwdStr = conStrParamArray[3];
} else {
......@@ -107,17 +124,23 @@ 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.getDBName();
boolean didUpdate = monitor.getData(age,pdbName);
String dbName = monitor.getFriendlyName(pdbName);
if(didUpdate) {
sb.append("{\"error\":false,\"msg\":\"Sucessfully collected data on instance '" + dbName + "'\"");
sb.append("{\"error\":false,\"msg\":\"Sucessfully collected data on '" + dbName + "'\"");
sb.append(",\"ms\":"+monitor.getLastRTms()+"}");
} else {
response.setStatus(HttpServletResponse.SC_ACCEPTED);
sb.append("{\"error\":false");
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.\"");
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.\"");
sb.append(",\"age\":"+monitor.getAgeTs()+"}");
}
} else {
......
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 preview for this file type
No preview for this file type
# Notes
## PDB logic
Bytt approuch och tagit bort allt som tidigare fanns i PDB branchen och har mergat den med master (då den innehöll TNS koden).
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.
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.
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.
Idag ser tex ett anrop ut så här:
GET /OraMonREST/getData?age=14&connectionString=jdbc%3Aoracle%3Athin%3A%40%2F%2Fu03634.kap.rsv.se%3A1526%2FDB1K12
I detta kan vi lägga till en parameter, forPDB=DA1K001 tex och då returneras endast värden för den PDB'n.
På så sätt kommer anrop till flera olika PDB att hämtas från samma CDB data cache.
Anropet till CDB'n skulle kunna returnera en lista på alla PDBer också.
Ännu snyggare vore om en CDB kunde bryta ner graferna per PDB också ;)
SQL satser
select cdb from v$database;
Returnerar YES om databasen är en CDB (dvs Oracle 12 med CDB påslaget). Returnerar YES även på en PDB.
Views for PDB's
V_$CON_SYSSTAT
V_$CON_SYSTEM_WAIT_CLASS
V_$CON_SYSTEM_EVENT
V_$CON_SYS_TIME_MODEL
Can be checked with a select like
select view_name from all_views where view_name like 'V_$CON_%';
Slå samman con_id med statname
select systimestamp, name || con_id, value from V$CON_SYSSTAT;
2018-03-28
Första versionen med PDB stöd. Behövs mer tester.
PDB CPU: 11.056953715796771
CDB CPU: 11.204673034978592
DA1K001: 11.084891829252536
DA1K002: 55.75905904774211
TOTAL : 66.84395087699465
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.
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.
Det är bara DA1K001 som jobbar. Nedan från samma mätning fast Logical IO per Second istället:
PDB LIO: 433961.7046663872
CDB LIO: 433532.02901594585
DA1K001: 435343.22211814864
DA1K002: 9.075934239850135
TOTAL : 435352.2980523885
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
......@@ -83,4 +83,17 @@ class Collector {
else
return 0;
}
public double getSeconds(String name) throws Throwable {
LongDelta myDelta = null;
for(int x = 0; x<list.size() && myDelta == null; x++) {
if(name.equals(list.get(x).name)) {
myDelta = list.get(x);
}
}
if(myDelta != null)
return myDelta.getSeconds();
else
return 0;
}
}
\ No newline at end of file
......
......@@ -34,7 +34,7 @@ class LongDelta {
update(value, timestamp, false);
}
public void update(Long value, Timestamp timestamp, boolean convert) {
public void update(long value, Timestamp timestamp, boolean convert) {
if(convert) value = value/1000;
if(urProt) {
if(this.curValue != null && this.curValue > value) {
......
......@@ -11,13 +11,69 @@ public class TestRunner {
/**
* @param args
*/
public static void main(String[] args) throws Throwable{
public static void main(String[] args) throws Throwable {
//runner1();
//test1();
//testTns();
testPDB();
}
public static void testPDB() throws Throwable {
OraMon cdb = new OraMon("jdbc:oracle:thin:@//u03634.kap.rsv.se:1526/DB1K12","dbsnmp","dbsnmp"); // CDB
OraMon pdb = new OraMon("jdbc:oracle:thin:@//u03634.kap.rsv.se:1526/DA1K001","dbsnmp","dbsnmp"); // PDB
int times = 5;
while(times-- > 0) {
cdb.getData(0, "DA1K001");
pdb.getData();
System.out.println("PDB CPU: " + pdb.getCPUPercent());
System.out.println("CDB CPU: " + cdb.getCPUPercent());
System.out.println("DA1K001: " + cdb.getCPUPercent(false, "DA1K001"));
System.out.println("DA1K002: " + cdb.getCPUPercent(false, "DA1K002"));
System.out.println("TOTAL : " + (cdb.getCPUPercent(false, "DA1K001") + cdb.getCPUPercent(false, "DA1K002")));
System.out.println("PDB LIO: " + pdb.getLogicalReadsPerSecond());
System.out.println("CDB LIO: " + cdb.getLogicalReadsPerSecond());
System.out.println("DA1K001: " + cdb.getLogicalReadsPerSecond("DA1K001"));
System.out.println("DA1K002: " + cdb.getLogicalReadsPerSecond("DA1K002"));
System.out.println("TOTAL : " + (cdb.getLogicalReadsPerSecond("DA1K001") + cdb.getLogicalReadsPerSecond("DA1K002")));
System.out.println("Sleeping 15s\n");
Thread.sleep(60000);
}
cdb.close();
pdb.close();
}
public static void test1() throws Throwable {
OraMon mon = new OraMon("jdbc:oracle:thin:@//u02822.kap.rsv.se:1526/DB1K06","dbsnmp","dbsnmp"); // CDB
System.out.println("getData returned: " + mon.getData());
System.out.println("getDatabaseName: " + mon.getDBName());
}
public static void testTns() throws Throwable {
//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
OraMon mon = new OraMon("jdbc:oracle:thin:@//u00153.kap.rsv.se:1526/DB1K01","dbsnmp","dbsnmp");
System.out.println("getData returned: " + mon.getData());
System.out.println("getDatabaseName: " + mon.getDBName());
System.out.println("getServiceName: " + mon.getServiceName());
System.out.println("getFriendlyName: " + mon.getFriendlyName());
System.out.println("getConString: " + mon.getConString());
System.out.println("getNumberOfCPUs: " + mon.getNumberOfCPUs());
}
public static void runner1() throws Throwable {
// TODO Auto-generated method stub
//ArrayList<OraMon> oraList = new ArrayList<OraMon>();
ArrayList<OraMon> oraList = Registry.getList();
OraMon mon1 = new OraMon("jdbc:oracle:thin:@uvp3dbkappkg:1550:VP1K03","dbsnmp","dbsnmp"); // SID eller Service Name format
//OraMon mon1 = new OraMon("jdbc:oracle:thin:@uvp3dbkappkg:1550:VP1K03","dbsnmp","dbsnmp"); // SID eller Service Name format
//OraMon mon1 = new OraMon("jdbc:oracle:thin:@//u00154.kap.rsv.se:1526/DB1K01","dbsnmp","dbsnmp");
//OraMon mon1 = new OraMon("jdbc:oracle:thin:@//u03634.kap.rsv.se:1526/DA1K001","dbsnmp","dbsnmp"); // PDB, CDB är DB1K12
//OraMon mon1 = new OraMon("jdbc:oracle:thin:@//u03634.kap.rsv.se:1526/DA1K002","dbsnmp","dbsnmp"); // Andra PDB på CDB DB1K12
OraMon mon1 = new OraMon("jdbc:oracle:thin:@//u03634.kap.rsv.se:1526/DB1K12","dbsnmp","dbsnmp"); // PDB, CDB är DB1K12
//OraMon mon2 = new OraMon("jdbc:oracle:thin:@host:port:sid","user","pass"); // SID format
mon1.open();
//mon2.open();
......