Commit 8c04d369 8c04d369291c1675db5f4eef83d80846e4e709f4 by Christian Gerdes

New version with working viewOraMon and updated viewJmxMon and working

action buttons in OraMon.jsp. 

Name of DB is now set in OraMonREST/getMetrics
Some cleanup of code
Changed the order of counters to have the most interresting first
OraMonREST/getData and getMetrics now support new style connection
strings
Added a find() method to both Registry implementations
Both getData methods (Ora and Jmx) now support to be called without
:username:password in connection string if the monitor already exists
1 parent 91783105
......@@ -33,11 +33,4 @@
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.wst.jsdt.core.jsNature</nature>
</natures>
<linkedResources>
<link>
<name>jetty/lilom.jar</name>
<type>1</type>
<locationURI>PROJECT_LOC/WebContent/WEB-INF/lib/lilom.jar</locationURI>
</link>
</linkedResources>
</projectDescription>
......
......@@ -42,12 +42,53 @@ if(request.getParameter("action") != null) {
<div style="background: Aquamarine; padding: 10px;">Info: <%= infMsg %> <form><input type="submit" value="OK"></form></div>
<% } %>
<script type="text/javascript">
function getData(type, input) {
// Update the data
var client1 = new XMLHttpRequest();
client1.onreadystatechange = dataHandler;
client1.open("GET", "/" + type + "/getData?age=14&connectionString=" + encodeURIComponent(input));
client1.setRequestHeader('Cache-Control', 'no-cache');
client1.setRequestHeader('Pragma', 'no-cache');
client1.send();
}
function getMetrics(type, input) {
// Get the metrics
var client2 = new XMLHttpRequest();
client2.onreadystatechange = metricsHandler;
client2.open("GET", "/" + type + "/getMetrics?connectionString=" + encodeURIComponent(input));
client2.setRequestHeader('Cache-Control', 'no-cache');
client2.setRequestHeader('Pragma', 'no-cache');
client2.send();
}
function metricsHandler() {
if (this.readyState == 4) {
window.alert("HTTP " + this.status + "\n\n" + this.responseText);
}
}
function dataHandler() {
if (this.readyState == 4) {
window.alert("HTTP " + this.status + "\n\n" + this.responseText);
}
}
</script>
<h1>OraMon Web 1.1 with JmxMon</h1>
<h2>Status Oracle Monitors</h2>
<p>Number of monitors: <%= se.lil.om.Registry.getList().size() %></p>
<div title="Add Monitor" style="background: WhiteSmoke; padding: 10px;">
<form>
<table>
<tr><td>Connection String:</td><td><input id="addoradata" name="data" size="70"></td><td><input type="button" value="add" onClick="getData('OraMonREST', addoradata.value)"></td></tr>
</table>
</form>
</div>
<div style="background-color: LightSteelBlue; padding: 10px;">
<table>
<tr>
......@@ -75,7 +116,9 @@ if(request.getParameter("action") != null) {
<form method="POST">
<input type="submit" name="action" value="remove" >
<input type="hidden" name="omconstr" value="<%= mon.getConString() %>">
<input type="button" value="view" onClick="window.open('/viewOraMon.html?<%= URLEncoder.encode(mon.getConString(), "UTF-8") %>')">
<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() %>')">
</form>
</td>
</tr>
......@@ -84,9 +127,16 @@ if(request.getParameter("action") != null) {
</div>
<h2>Status JMX Monitors</h2>
<p>Number of monitors: <%= se.lil.jm.Registry.getList().size() %></p>
<div title="Add Monitor" style="background: WhiteSmoke; padding: 10px;">
<form>
<table>
<tr><td>Connection String:</td><td><input id="addjmxdata" name="data" size="70"></td><td><input type="button" value="add" onClick="getData('JmxMonREST', addjmxdata.value)"></td></tr>
</table>
</form>
</div>
<div style="background-color: LightSteelBlue; padding: 10px;">
<table>
<tr>
......@@ -114,7 +164,9 @@ if(request.getParameter("action") != null) {
<form method="POST">
<input type="submit" name="action" value="remove" >
<input type="hidden" name="jmconstr" value="<%= mon.getConString() %>">
<input type="button" value="view" onClick="window.open('/viewJmxMon.html?<%= URLEncoder.encode(mon.getConString(), "UTF-8") %>')">
<input type="button" value="graph" onClick="window.open('/viewJmxMon.html?<%= URLEncoder.encode(mon.getConString(), "UTF-8") %>')">
<input type="button" value="getData" onClick="getData('JmxMonREST', '<%= mon.getConString() %>')">
<input type="button" value="getMetrics" onClick="getMetrics('JmxMonREST', '<%= mon.getConString() %>')">
</form>
</td>
</tr>
......@@ -122,18 +174,5 @@ if(request.getParameter("action") != null) {
</table>
</div>
<!--
<h2>Administration</h2>
<div title="Add Monitor" style="background: WhiteSmoke; padding: 10px;">
<form>
<table>
<tr><td>Data:</td><td><input name="data" size="50"></td></tr>
</table>
<input type="submit" name="action" value="add">
</form>
</div>
-->
</body>
</html>
\ No newline at end of file
......
......@@ -51,7 +51,7 @@
client1.send();
} else {
// Error, no monitor specified
statusP.innerHTML = "No monitor specified in URL QueryString (use ?enter uri encoded con string)";
statusP.innerHTML = "No monitor specified in URL QueryString (use ?enter%20uri%20encoded%20con%20string)";
}
}
......@@ -68,7 +68,7 @@
client2.send();
} else {
// Error, no monitor specified
statusP.innerHTML = "No monitor specified in URL QueryString (use ?enter uri encoded con string)";
statusP.innerHTML = "No monitor specified in URL QueryString (use ?enter%20uri%20encoded%20con%20string)";
}
}
......@@ -101,6 +101,7 @@
function addData(res) {
if(res.error == false && res.nvarray.length > 0) {
main_title.innerHTML = res.name + " JMX Monitor";
document.title = "JmxMon " + res.name;
if (created == false) {
createChart(res.nvarray);
}
......@@ -110,7 +111,7 @@
dataRow[0] = new Date();
dataRow[1] = res.nvarray[i].value;
ac_data[i].addRow(dataRow);
if (ac_data[i].getNumberOfRows() > 1000) ac_data[i].removeRow(0);
if (ac_data[i].getNumberOfRows() > 100) ac_data[i].removeRow(0);
ac_options.title = res.nvarray[i].name + ": " + res.nvarray[i].value;
ac_chart[i].draw(ac_data[i], ac_options);
}
......
<!DOCTYPE html>
<html>
<head>
<title>LIL JMX Monitor</title>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
</head>
<body>
<h1 id="main_title">LIL ORA Monitor</h1>
<div style="background-color: lightgrey; line-height:1em; min-height:3em;"><p id="statusP">Nothing loaded</p></div>
<div id="main_div"></div>
<script type="text/javascript">
var ac_data = [];
var ac_chart = [];
var created = false;
google.load("visualization", "1", { packages: ["corechart"] });
google.setOnLoadCallback(getData);
var ac_options = {
title: 'Current Activity',
hAxis: { title: 'Timeline', titleTextStyle: { color: '#333'}, format: 'HH:mm:ss' },
vAxis: { },
isStacked: false,
legend: { position: 'none' }
};
function createChart(nvarray) {
for(var i=0; i < nvarray.length; i++) {
ac_data[i] = new google.visualization.DataTable();
ac_data[i].addColumn('datetime', 'Time');
ac_data[i].addColumn('number', nvarray[i].name);
var newdiv = document.createElement('div');
newdiv.id = 'ac_div' + i;
main_div.appendChild(newdiv);
ac_chart[i] = new google.visualization.LineChart(newdiv);
}
created = true;
}
function getData() {
if(location.search != '')
{
// Update the data
statusP.innerHTML = "Calling getData...";
var client1 = new XMLHttpRequest();
client1.onreadystatechange = handler1;
client1.open("GET", "/OraMonREST/getData?age=14&connectionString=" + location.search.substring(1));
client1.setRequestHeader('Cache-Control', 'no-cache');
client1.setRequestHeader('Pragma', 'no-cache');
client1.send();
} else {
// Error, no monitor specified
statusP.innerHTML = "No monitor specified in URL QueryString (use ?enter%20uri%20encoded%20con%20string)";
}
}
function getMetrics() {
if(location.search != '')
{
// Get the metrics
statusP.innerHTML += "<br>Calling getMetrics...";
var client2 = new XMLHttpRequest();
client2.onreadystatechange = handler2;
client2.open("GET", "/OraMonREST/getMetrics?connectionString=" + location.search.substring(1));
client2.setRequestHeader('Cache-Control', 'no-cache');
client2.setRequestHeader('Pragma', 'no-cache');
client2.send();
} else {
// Error, no monitor specified
statusP.innerHTML = "No monitor specified in URL QueryString (use ?enter%20uri%20encoded%20con%20string)";
}
}
function handler1() {
if (this.readyState == 4) {
if ((this.status == 200 || this.status == 202) &&
this.responseText != null) {
var res = eval('(' + this.responseText + ')');
statusP.innerHTML += " Received 200 OK (ms:" + res.ms + " age:" + res.age + ")<br>" + res.msg;
getMetrics();
} else {
statusP.innerHTML += " Received responsecode " + this.status;
}
}
}
function handler2() {
if (this.readyState == 4) {
if (this.status == 200 &&
this.responseText != null) {
statusP.innerHTML += " Received 200 OK";
var res = eval('(' + this.responseText + ')');
addData(res);
} else {
statusP.innerHTML += " Received responsecode " + this.status;
}
}
}
function addData(res) {
if(res.error == false && res.nvarray.length > 0) {
main_title.innerHTML = res.name + " ORA Monitor";
document.title = "OraMon " + res.name;
if (created == false) {
createChart(res.nvarray);
}
for(var i=0; i < res.nvarray.length; i++) {
var dataRow = [];
dataRow[0] = new Date();
dataRow[1] = res.nvarray[i].value;
ac_data[i].addRow(dataRow);
if (ac_data[i].getNumberOfRows() > 100) ac_data[i].removeRow(0);
ac_options.title = res.nvarray[i].name + ": " + res.nvarray[i].value;
ac_chart[i].draw(ac_data[i], ac_options);
}
}
window.setTimeout('getData()', 15000);
}
</script>
</body>
</html>
No preview for this file type
......@@ -46,47 +46,84 @@ public class OraMonRESTgetData extends HttpServlet {
if(request.getParameterMap().containsKey("connectionString")) {
// We have a connection string, find the monitor or create it and call getData() on the monitor
// Check that we have a valid connection string (added support to handle diffrent kinds of connection strings)
String[] conStrParamArray = request.getParameter("connectionString").split(":");
Boolean serviceName = false;
if(conStrParamArray.length == 4) {
// Check if service name is used ( / instead of : )
if(conStrParamArray[1].indexOf("/") >= 0) {
serviceName = true;
OraMon monitor = null;
if(request.getParameter("connectionString").startsWith("jdbc:oracle")) {
// Full con string
String[] shortConArray = request.getParameter("connectionString").split("@");
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.\"}");
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"));
} 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;
}
}
if(conStrParamArray.length != 5 && serviceName == false) {
// Error, we need 5 parts in the connection string
response.setStatus(400);
response.getWriter().println("{\"error\":true,\"msg\":\"connectionString needs to be in format host:port:sid:username:password or host:port/servicename:username:password\"}");
return;
}
String conStr, usrStr, pwdStr;
if(serviceName) {
conStr = "jdbc:oracle:thin:@" + conStrParamArray[0] + ":" + conStrParamArray[1];
usrStr = conStrParamArray[2];
pwdStr = conStrParamArray[3];
} else {
conStr = "jdbc:oracle:thin:@" + conStrParamArray[0] + ":" + conStrParamArray[1] + ":" + conStrParamArray[2];
usrStr = conStrParamArray[3];
pwdStr = conStrParamArray[4];
// Short con string
// Check that we have a valid connection string (added support to handle diffrent kinds of connection strings)
String[] conStrParamArray = request.getParameter("connectionString").split(":");
Boolean serviceName = false;
if(conStrParamArray.length == 4) {
// Check if service name is used ( / instead of : )
if(conStrParamArray[1].indexOf("/") >= 0) {
serviceName = true;
}
}
if(conStrParamArray.length != 5 && serviceName == false) {
// Error, we need 5 parts in the connection string
response.setStatus(400);
response.getWriter().println("{\"error\":true,\"msg\":\"connectionString needs to be in format host:port:sid:username:password or host:port/servicename:username:password\"}");
return;
}
String conStr, usrStr, pwdStr;
if(serviceName) {
conStr = "jdbc:oracle:thin:@" + conStrParamArray[0] + ":" + conStrParamArray[1];
usrStr = conStrParamArray[2];
pwdStr = conStrParamArray[3];
} else {
conStr = "jdbc:oracle:thin:@" + conStrParamArray[0] + ":" + conStrParamArray[1] + ":" + conStrParamArray[2];
usrStr = conStrParamArray[3];
pwdStr = conStrParamArray[4];
}
// Try to find the monitor in our list
monitor = Registry.findOrCreate(conStr, usrStr, pwdStr);
}
// Try to find the monitor in our list
OraMon monitor = Registry.findOrCreate(conStr, usrStr, pwdStr);
// Call getData()
boolean didUpdate = monitor.getData(age);
String dbName = monitor.getDBName();
if(didUpdate) {
sb.append("{\"error\":false,\"msg\":\"Sucessfully collected data on instance '" + dbName + "'\"");
sb.append(",\"ms\":"+monitor.getLastRTms()+"}");
if(monitor != null) {
// Call getData()
boolean didUpdate = monitor.getData(age);
String dbName = monitor.getDBName();
if(didUpdate) {
sb.append("{\"error\":false,\"msg\":\"Sucessfully collected data on instance '" + 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(",\"age\":"+monitor.getAgeTs()+"}");
}
} 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(",\"age\":"+monitor.getAgeTs()+"}");
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
sb.append("{\"error\":true,\"msg\":\"Monitor not found and can't create one without :username:password '" + request.getParameter("connectionString") + "'\"");
sb.append("}");
}
} else {
......
......@@ -25,6 +25,15 @@ public class Registry {
return monitor;
}
public static synchronized OraMon find(String conStr) {
for (OraMon item : getList()) {
if(item.getConString().equals(conStr)) {
return item;
}
}
return null;
}
public static synchronized void remove(String conStr) {
OraMon mon = null;
for (OraMon item : getList()) {
......