Skip to content

Commit

Permalink
Adding base work for system metrics
Browse files Browse the repository at this point in the history
  • Loading branch information
jvalkeal committed Dec 28, 2011
1 parent 48ea6f8 commit 906e656
Show file tree
Hide file tree
Showing 6 changed files with 282 additions and 6 deletions.
2 changes: 1 addition & 1 deletion dojo-release-1.5.0-src/hyperic/data/ResourceTree.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ dojo.declare("hyperic.data.ResourceTree", dijit.Tree, {
return "hypericIconMetric";
}

if(item.system){
if(item.track){
return "hypericIconMetric";
}

Expand Down
2 changes: 1 addition & 1 deletion dojo-release-1.5.0-src/hyperic/data/TreeDndSource.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ dojo.declare("hyperic.data.TreeDndSource", dijit.tree.dndSource, {
var dragItem = dragTreeNode.item; //get the store item bound to the dragged treenode

// define which nodes become dnd items
if(dragItem.mid || dragItem.eid || dragItem.system || dragItem.pid){
if(dragItem.mid || dragItem.eid || dragItem.track || dragItem.pid){
this.inherited(arguments);
}
}
Expand Down
2 changes: 2 additions & 0 deletions dojo-release-1.5.0-src/hyperic/dnd/Source.js
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,8 @@ dojo.declare("hyperic.dnd.Source",[dojo.dnd.Source],{
if(item.pid && item.parent) w.setTracksByScope([item.pid], "tavail/" + item.parent + "/");
else if(item.pid) w.setTracksByScope([item.pid], "tavail/");

if(item.scope && item.track) w.setTracksByScope([item.track], item.scope);

w._buildContextMenu();

item['wmwidget'] = w;
Expand Down
6 changes: 3 additions & 3 deletions dojo-release-1.5.0-src/hyperic/tests/data/system
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{ id: '/dojo-release-1.5.0-src/hyperic/tests/data/system', name:'System', children: [

{ id: '/dojo-release-1.5.0-src/hyperic/tests/data/system/sysloadavg', name: 'System Load Average', children: [
{id: '/dojo-release-1.5.0-src/hyperic/tests/data/system/stats/loadAvg1', system:'loadAvg1', name: '1min'},
{id: '/dojo-release-1.5.0-src/hyperic/tests/data/system/stats/loadAvg5', name: '5min'},
{id: '/dojo-release-1.5.0-src/hyperic/tests/data/system/stats/loadAvg15', name: '15min'}
{id: '/dojo-release-1.5.0-src/hyperic/tests/data/system/stats/loadAvg1', scope:'system/stats/', track:'loadAvg1', name: '1min'},
{id: '/dojo-release-1.5.0-src/hyperic/tests/data/system/stats/loadAvg5', scope:'system/stats/', track:'loadAvg5', name: '5min'},
{id: '/dojo-release-1.5.0-src/hyperic/tests/data/system/stats/loadAvg15', scope:'system/stats/', track:'loadAvg15', name: '15min'}
]
},

Expand Down
137 changes: 136 additions & 1 deletion wallmount/app/MetricstoreController.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ import org.hyperic.util.pager.PageControl
import org.hyperic.hq.measurement.server.session.Measurement
import org.hyperic.hq.appdef.shared.AppdefEntityConstants
import org.hyperic.hq.appdef.shared.AppdefUtil
import org.hyperic.hq.common.Humidor
import org.hyperic.util.PrintfFormat
import java.text.DateFormat

/**
* Controller to handle metric requests from wallmount metric store.
Expand All @@ -53,6 +56,21 @@ import org.hyperic.hq.appdef.shared.AppdefUtil
*/
class MetricstoreController extends BaseJSONController {

/**
* Local static cache which spans to all instances of
* this controller.
*
* cache(system) contains timestamp and a map(value)
* which contains actual cached key/value pairs.
*/
private static def cache = [system:[time:0,value:[:]]]

/**
* Static lock to prevent simultaneous requests to
* update cache at the same time.
*/
private static Object systemCacheLock = new Object()

/**
* Returns requested metrics.
*/
Expand Down Expand Up @@ -199,11 +217,29 @@ class MetricstoreController extends BaseJSONController {


array.put(id: aeid, last: last, alerts:alertCount, escalations:escCount)
} else if(scopes[0] == 'system') {
// need to sync through static lock.
// only first request within time window
// will actually update cached values
synchronized(systemCacheLock) {
updateSystemStatsCache()
}
array.put(id: scopes[-1], last: cache.system.value[scope])
}

render(inline:"${array}", contentType:'text/json-comment-filtered')
}

protected void updateSystemStatsCache() {
// is cache older than 25 sec?
long time = now()
if(cache.system.time < time-25000) {
def stats = getSystemStats()
cache.system.value = stats
cache.system.time = time
}
}

/**
*
*/
Expand Down Expand Up @@ -258,6 +294,105 @@ class MetricstoreController extends BaseJSONController {

resEscCount
}

/**
* Returns a map of system statistics.
*/
private Map getSystemStats() {
def s = Humidor.instance.sigar
def loadAvgFmt = new PrintfFormat('%.2f')
def dateFormat = DateFormat.getDateTimeInstance()

def cpu = s.cpuPerc
def sysMem = s.mem
def sysSwap = s.swap
def pid = s.pid
def procFds = 'unknown'
def procMem = s.getProcMem(pid)
def procCpu = s.getProcCpu(pid)
def procTime = s.getProcTime(pid)
def NA = 'N/A' //XXX localeBundle?
def loadAvg1 = NA
def loadAvg5 = NA
def loadAvg15 = NA
def runtime = Runtime.runtime

try {
procFds = s.getProcFd(pid).total
} catch(Exception e) {
}

try {
def loadAvg = s.loadAverage
loadAvg1 = loadAvgFmt.sprintf(loadAvg[0])
loadAvg5 = loadAvgFmt.sprintf(loadAvg[1])
loadAvg15 = loadAvgFmt.sprintf(loadAvg[2])
} catch(Exception e) {
//SigarNotImplementedException on Windows
}

//e.g. Linux
def free;
def used;
if ((sysMem.free != sysMem.actualFree ||
(sysMem.used != sysMem.actualUsed))) {
free = sysMem.actualFree
used = sysMem.actualUsed
} else {
free = sysMem.free
used = sysMem.used
}

[
'system/syscpu/sysUserCpu': (int)(cpu.user * 100),
'system/syscpu/sysSysCpu': (int)(cpu.sys * 100),
'system/syscpu/sysNiceCpu': (int)(cpu.nice * 100),
'system/syscpu/sysIdleCpu': (int)(cpu.idle * 100),
'system/syscpu/sysWaitCpu': (int)(cpu.wait * 100),
'system/syscpu/sysPercCpu': (int)(100 - cpu.idle * 100),
'system/sysloadavg/loadAvg1': loadAvg1,
'system/sysloadavg/loadAvg5': loadAvg5,
'system/sysloadavg/loadAvg15': loadAvg15,
'system/sysmem/totalMem': sysMem.total,
'system/sysmem/usedMem': used,
'system/sysmem/freeMem': free,
'system/sysswap/totalSwap': sysSwap.total,
'system/sysswap/usedSwap': sysSwap.used,
'system/sysswap/freeSwap': sysSwap.free,
'system/proc/procOpenFds': procFds,
'system/proc/procMemSize': procMem.size,
'system/proc/procMemRes': procMem.resident,
'system/proc/procMemShare': procMem.share,
'system/jvm/jvmTotalMem': runtime.totalMemory(),
'system/jvm/jvmFreeMem': runtime.freeMemory(),
'system/jvm/jvmMaxMem': runtime.maxMemory(),
'system/hq/numPlatforms': resourceHelper.find(count:'platforms'),
'system/hq/numCpus': resourceHelper.find(count:'cpus'),
'system/hq/numAgents': agentHelper.find(count:'agents'),
'system/hq/numActiveAgents': agentHelper.find(count:'activeAgents'),
'system/hq/numServers': resourceHelper.find(count:'servers'),
'system/hq/numServices': resourceHelper.find(count:'services'),
'system/hq/numApplications': resourceHelper.find(count:'applications'),
'system/hq/numRoles': resourceHelper.find(count:'roles'),
'system/hq/numUsers': resourceHelper.find(count:'users'),
'system/hq/numAlertDefs': resourceHelper.find(count:'alertDefs'),
'system/hq/numResources': resourceHelper.find(count:'resources'),
'system/hq/numResourceTypes': resourceHelper.find(count:'resourceTypes'),
'system/hq/numGroups': resourceHelper.find(count:'groups'),
'system/hq/numEsc': resourceHelper.find(count:'escalations'),
'system/hq/numActiveEsc': resourceHelper.find(count:'activeEscalations'),
'system/hq/metricsPerMinute': metricsPerMinute
]
}

private getMetricsPerMinute() {
def vals = measurementManager.findMetricCountSummaries()
def total = 0.0


for (v in vals) {
total = total + (float)v.total / (float)v.interval
}
(int)total
}

}
139 changes: 139 additions & 0 deletions wallmount/app/ResourcetreeController.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ class ResourcetreeController extends BaseJSONController {
if(paths[1] == 'platform') allPlatforms()
if(paths[1] == 'group') allGroups()
if(paths[1] == 'rtype') allResourceTypes()
if(paths[1] == 'system') allSystem()
} else if(paths.size() == 3) {
if(paths[1] == 'platform') {
byPlatform(paths[2] as int)
Expand Down Expand Up @@ -354,6 +355,7 @@ class ResourcetreeController extends BaseJSONController {
roots.put($ref : baseUrl + '/platform', name: 'Platforms', children: true);
roots.put($ref : baseUrl + '/group', name: 'Groups', children: true);
roots.put($ref : baseUrl + '/rtype', name: 'Resource Types', children: true);
roots.put($ref : baseUrl + '/system', name: 'System', children: true);
def ret = roots.toString()
render(inline:"${ret}", contentType:'text/json-comment-filtered')
}
Expand Down Expand Up @@ -566,6 +568,143 @@ class ResourcetreeController extends BaseJSONController {
root.put("children",rootChilds);
renderJSONObj(root);
}

def allSystem() {
JSONObject root = new JSONObject()
root.put("id", baseUrl + '/system')
root.put("name","System")

JSONArray rootChilds = new JSONArray()

// System Load Average
JSONObject obj = new JSONObject()
obj.put("id", baseUrl + '/system/sysloadavg')
obj.put("name","System Load Average")
JSONArray childs = new JSONArray()
childs.put(id: baseUrl + '/system/sysloadavg/loadAvg1',
name: 'System Load 1min',
scope: 'system/sysloadavg/',
track: 'loadAvg1')
childs.put(id: baseUrl + '/system/sysloadavg/loadAvg5',
name: 'System Load 5min',
scope: 'system/sysloadavg/',
track: 'loadAvg5')
childs.put(id: baseUrl + '/system/sysloadavg/loadAvg15',
name: 'System Load 15min',
scope: 'system/sysloadavg/',
track: 'loadAvg15')
obj.put("children",childs);
rootChilds.put(obj)

// System CPU
obj = new JSONObject()
obj.put("id", baseUrl + '/system/syscpu')
obj.put("name","System CPU")
childs = new JSONArray()
childs.put(id: baseUrl + '/system/syscpu/sysUserCpu',
name: 'System CPU User',
format: 'percent',
scope: 'system/syscpu/',
track: 'sysUserCpu')
childs.put(id: baseUrl + '/system/syscpu/sysSysCpu',
name: 'System CPU System',
format: 'percent',
scope: 'system/syscpu/',
track: 'sysSysCpu')
childs.put(id: baseUrl + '/system/syscpu/sysNiceCpu',
name: 'System CPU Nice',
format: 'percent',
scope: 'system/syscpu/',
track: 'sysNiceCpu')
childs.put(id: baseUrl + '/system/syscpu/sysIdleCpu',
name: 'System CPU Idle',
format: 'percent',
scope: 'system/syscpu/',
track: 'sysIdleCpu')
childs.put(id: baseUrl + '/system/syscpu/sysWaitCpu',
name: 'System CPU Wait',
format: 'percent',
scope: 'system/syscpu/',
track: 'sysWaitCpu')
obj.put("children",childs);
rootChilds.put(obj)

// Hyperic stats
obj = new JSONObject()
obj.put("id", baseUrl + '/system/hq')
obj.put("name","Hyperic Stats")
childs = new JSONArray()
childs.put(id: baseUrl + '/system/hq/numPlatforms',
name: 'HQ Num of Platforms',
scope: 'system/hq/',
track: 'numPlatforms')
childs.put(id: baseUrl + '/system/hq/numCpus',
name: 'HQ Num of Cpus',
scope: 'system/hq/',
track: 'numCpus')
childs.put(id: baseUrl + '/system/hq/numAgents',
name: 'HQ Num of Agents',
scope: 'system/hq/',
track: 'numAgents')
childs.put(id: baseUrl + '/system/hq/numActiveAgents',
name: 'HQ Num of Active Agents',
scope: 'system/hq/',
track: 'numActiveAgents')
childs.put(id: baseUrl + '/system/hq/numServers',
name: 'HQ Num of Servers',
scope: 'system/hq/',
track: 'numServers')
childs.put(id: baseUrl + '/system/hq/numServices',
name: 'HQ Num of Services',
scope: 'system/hq/',
track: 'numServices')
childs.put(id: baseUrl + '/system/hq/numApplications',
name: 'HQ Num of Applications',
scope: 'system/hq/',
track: 'numApplications')
childs.put(id: baseUrl + '/system/hq/numRoles',
name: 'HQ Num of Roles',
scope: 'system/hq/',
track: 'numRoles')
childs.put(id: baseUrl + '/system/hq/numUsers',
name: 'HQ Num of Users',
scope: 'system/hq/',
track: 'numUsers')
childs.put(id: baseUrl + '/system/hq/numAlertDefs',
name: 'HQ Num of Alert Definitions',
scope: 'system/hq/',
track: 'numAlertDefs')
childs.put(id: baseUrl + '/system/hq/numResources',
name: 'HQ Num of Resources',
scope: 'system/hq/',
track: 'numResources')
childs.put(id: baseUrl + '/system/hq/numResourceTypes',
name: 'HQ Num of Resource Types',
scope: 'system/hq/',
track: 'numResourceTypes')
childs.put(id: baseUrl + '/system/hq/numGroups',
name: 'HQ Num of Groups',
scope: 'system/hq/',
track: 'numGroups')
childs.put(id: baseUrl + '/system/hq/numEsc',
name: 'HQ Num of Escalations',
scope: 'system/hq/',
track: 'numEsc')
childs.put(id: baseUrl + '/system/hq/numActiveEsc',
name: 'HQ Num of Active Escalations',
scope: 'system/hq/',
track: 'numActiveEsc')
childs.put(id: baseUrl + '/system/hq/metricsPerMinute',
name: 'HQ Metrics Received Per Minute',
scope: 'system/hq/',
track: 'metricsPerMinute')
obj.put("children",childs);
rootChilds.put(obj)


root.put("children",rootChilds);
renderJSONObj(root);
}


}

0 comments on commit 906e656

Please sign in to comment.