/////////////////////////////////////////////////////////////////////////////// /* display.js COPYRIGHT --------- Copyright (C) 2014-2023 Mark G.Daniel This program, comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under the conditions of the GNU GENERAL PUBLIC LICENSE, version 3, or any later version. http://www.gnu.org/licenses/gpl.txt VERSION ------- 03-OCT-2018 MGD bugfix; mdsiDisplaySummary() ensure mdsi_ClusterData exists 05-FEB-2014 MGD initial */ /////////////////////////////////////////////////////////////////////////////// ///////////////////////////// // client "debugging" data // ///////////////////////////// /////////////////////////////////////////////////////////////////////////////// function mdsiInsightClick () { var div = $byId('insight'); if (mdsi_InsightDisplay) { mdsi_InsightDisplay = false; div.style.display = 'none'; } else { mdsi_InsightDisplay = true; div.style.display = 'block'; } acmeAdjustSize(); } /////////////////////////////////////////////////////////////////////////////// var mdsi_InsightTimeStamp = -1; function mdsiDisplayInsight (data) { var ins = $byId('insight'); var stamp = new Date(); stamp = stamp.getTime() / 1000; if (stamp - mdsi_InsightTimeStamp >= 1) { var html = ''; html += acmeIpcSummary(); html += 'Store size: ' + mdsiStoreSize() + '\n'; html += JSON.stringify(mdsi_StaticData,null,3); // html += JSON.stringify(mdsi_DynamicStore,null,3); ins.innerHTML = html; mdsi_InsightTimeStamp = stamp; ins.setAttribute('ondblclick', 'mdsiInsightClick()'); } ins.innerHTML += '\n' + JSON.stringify(data,null,3); acmeAdjustSize(); } /////////////////////////////////////////////////////////////////////////////// ////////////////////////// // display summary data // ////////////////////////// /////////////////////////////////////////////////////////////////////////////// function mdsiSummaryDatum (datum,requests) { var value = mdsiGetData(datum); return mdsiWithCommas(value) + mdsiSpacedPercent(value,requests); } /////////////////////////////////////////////////////////////////////////////// function mdsiStatusValue (code,requests) { var value = mdsiGetData().statusCodes[code]; return mdsiWithCommas(value) + mdsiSpacedPercent(value,requests); } /////////////////////////////////////////////////////////////////////////////// function mdsiDisplaySummary () { if (!mdsi_DynamicData) return; $byId('sumNodeName').innerHTML = mdsi_StaticData.nodeName; $byId('sumNodeName').setAttribute('onclick', 'mdsiInsightClick()'); var sumService = location.hostname; if (location.port.length) sumService += ':' + location.port; $byId('sumService').innerHTML = sumService; $byId('sumVMStime').innerHTML = mdsiGetData('vmsTime'); var html = ''; html += mdsi_StaticData.hwName + ' with ' + mdsi_StaticData.cpuAvail + (mdsi_StaticData.cpuAvail > 1 ? ' CPUs and ' : ' CPU and ') + mdsiValue(mdsi_StaticData.memSize) + 'B, running ' + mdsi_StaticData.archName + ' VMS ' + mdsi_StaticData.vmsVersion + '
Boot ' + mdsi_StaticData.bootTime + ' up ' + mdsiGetData('upTime'); html += '
Processes:' + mdsiGetData('procTot') + ' Interactive:' + mdsiGetData('procInt') + ' Batch:' + mdsiGetData('procBat') + ' Network:' + mdsiGetData('procNet'); var diskCount; if (diskCount = mdsiGetData('diskCount')) html += '  Disks:' + mdsiGetData('diskCount') + '/' + diskCount; var opcomCount; if (opcomCount = mdsiGetData('opcomCount')) html += '
OPCOM: ' + opcomCount + ' at ' + mdsiGetData('opcomTime'); var opcomAudit; if (opcomAudit = mdsiGetData('opcomAudit')) html += '  Audit: ' + opcomAudit; if (mdsi_StaticData.clusterMember) { html += '
Cluster nodes:' + mdsiGetData('clusterNodes') + ' votes:' + mdsiGetData('clusterVotes') + ' expected:' + mdsiGetData('clusterEVotes') + ' quorum:' + mdsiGetData('clusterQuorum'); if (mdsi_ClusterDisplay && mdsi_ClusterData && mdsi_ClusterData.summary) html += '
' + mdsi_ClusterData.summary; } html += '
MonDeSi v' + $ExeVersion + ' under ' + mdsi_StaticData.HTTPd; html += ' collecting for ' + mdsiCollectFor(); $byId('sumSystem').innerHTML = html; } /////////////////////////////////////////////////////////////////////////////// function mdsiDisplaySynopsis () { if (!mdsi_DynamicData) return; if (!mdsi_SynopsisDisplay) return; $byId('closedNodeName').innerHTML = mdsi_StaticData.nodeName; $byId('closedService').innerHTML = location.hostname + location.port; $byId('closedVMStime').innerHTML = mdsiGetData('vmsTime'); var html = '  –  '; html += 'cpu:' + mdsiGetData('cpuBusy') + '/' + mdsiGetData('cpuSEK') + '%  '; var memPercent = (mdsiGetData('memInUse') * 100) / mdsi_StaticData.memSize; html += 'mem:' + mdsiValue(mdsiGetData('memInUse')) + ' (' + memPercent.toFixed(0) + '%)  '; var pflPercent = (mdsiGetData('pageFileUsed') * 100) / mdsiGetData('pageFileSize') html += 'pgfl:' + mdsiValue(mdsiGetData('pageFileUsed')) + ' (' + pflPercent.toFixed(0) + '%)  '; html += 'net:' + mdsiValue(mdsiGetData('netPerSec')) + '  '; html += 'disk:' + mdsiValue(mdsiGetData('fcpRW')) + '  '; html += 'prc:' + mdsiGetData('procTot'); $byId('closedSynopsis').innerHTML = html; } /////////////////////////////////////////////////////////////////////////////// function mdsiDisplayModes () { $byId('modeTOT').innerHTML = mdsiGetData('cpuBusy') + '%'; $byId('modeINT').innerHTML = mdsiGetData('modeINT') + '%'; $byId('modeMPS').innerHTML = mdsiGetData('modeMPS') + '%'; $byId('modeKER').innerHTML = mdsiGetData('modeKER') + '%'; $byId('modeEXE').innerHTML = mdsiGetData('modeEXE') + '%'; $byId('modeSUP').innerHTML = mdsiGetData('modeSUP') + '%'; $byId('modeUSE').innerHTML = mdsiGetData('modeUSE') + '%'; } /////////// // OPCOM // /////////// /////////////////////////////////////////////////////////////////////////////// function mdsiOpcomClick () { var div = $byId('opcom'); if (mdsi_OpcomDisplay) { mdsi_OpcomDisplay = false; div.style.display = 'none'; $byId('checkboxAudit').disabled = true; } else { mdsi_OpcomDisplay = true; div.style.display = 'block'; if (mdsiGetData('opcomAudit')) $byId('checkboxAudit').disabled = false; } if ($WebSocket) acmeIpcSend(mdsiTheseData()); acmeAdjustSize(); } /////////////////////////////////////////////////////////////////////////////// function mdsiAuditClick () { mdsi_OpcomAudit = !mdsi_OpcomAudit; if ($WebSocket) acmeIpcSend(mdsiTheseData()); acmeAdjustSize(); } /////////////////////////////////////////////////////////////////////////////// function mdsiDisplayOpcom () { var opcom = $byId('opcom'); var opcomBuffer = mdsiGetData('opcomBuffer',mdsi_OpcomData); if (opcomBuffer) opcom.innerText = opcomBuffer; acmeAdjustSize(); } /////////////////////////////////////////////////////////////////////////////// /////////////////////// // display disk data // /////////////////////// /////////////////////////////////////////////////////////////////////////////// /* Add the per-disk sections into the disk section. */ function mdsiBuildDisk () { if (!mdsi_StaticData) { setTimeout(mdsiBuildDisk, 100); return; } if (!mdsi_StaticData.diskCount) return; $byId('checkboxDisk').disabled = false; var cnt = mdsi_StaticData.diskCount; var html = ''; for (var idx = 0; idx < cnt; idx++) html += '
\n'; $byId('perDiskBar').innerHTML = html; html = ''; for (idx = 0; idx < cnt; idx++) { html += '
'; html += '
\n'; html += '
\n'; html += '
\n'; html += '
'; } $byId('perDiskHist').innerHTML = html; for (idx = 0; idx < cnt; idx++) { mdsiToolTipDiskIOPsInit('perDiskHistIOPs'+idx); mdsiToolTipDiskQlenInit('perDiskHistQlen'+idx); mdsiToolTipDiskDeltaInit('perDiskHistDelta'+idx); } } /////////////////////////////////////////////////////////////////////////////// /* Flip between the disk queue length, IOPs and usage delta graphs. */ function mdsiDiskHistClick (obj) { if (mdsi_DiskDeltaDisplay || mdsi_DiskQlenDisplay) return; if (obj.id.substr(0,15) == 'perDiskHistIOPs') { var dnum = obj.id.substr(15); $byId(obj.id).style.display = 'none'; $byId('perDiskHistQlen'+dnum).style.display = 'inline-block'; } else if (obj.id.substr(0,15) == 'perDiskHistQlen') { var dnum = obj.id.substr(15); $byId(obj.id).style.display = 'none'; $byId('perDiskHistDelta'+dnum).style.display = 'inline-block'; } else if (obj.id.substr(0,16) == 'perDiskHistDelta') { var dnum = obj.id.substr(16); $byId(obj.id).style.display = 'none'; $byId('perDiskHistIOPs'+dnum).style.display = 'inline-block'; } } /////////////////////////////////////////////////////////////////////////////// ////////////////////////// // display process data // ////////////////////////// /////////////////////////////////////////////////////////////////////////////// /* */ function mdsiDisplayTopProcess (reset) { if (reset) { $byId('procCOM').innerHTML = $byId('procCOMO').innerHTML = $byId('procCUR').innerHTML = $byId('procHIB').innerHTML = $byId('procHIBO').innerHTML = $byId('procLEF').innerHTML = $byId('procLEFO').innerHTML = $byId('procMWAIT').innerHTML = $byId('procSUSP').innerHTML = $byId('procSUSPO').innerHTML = $byId('procPFW').innerHTML = $byId('procSwapped').innerHTML = $byId('procWaiting').innerHTML = '0'; $byId('topCPU').innerHTML = $byId('topSEK').innerHTML = $byId('topFLTS').innerHTML = $byId('topBIO').innerHTML = ''; $byId('topDIO').innerHTML = '




'; return; } if (!mdsi_TopProcessData) return; $byId('procCOM').innerHTML = mdsi_TopProcessData.COM; $byId('procCOMO').innerHTML = mdsi_TopProcessData.COMO; $byId('procCUR').innerHTML = mdsi_TopProcessData.CUR; $byId('procHIB').innerHTML = mdsi_TopProcessData.HIB; $byId('procHIBO').innerHTML = mdsi_TopProcessData.HIBO; $byId('procLEF').innerHTML = mdsi_TopProcessData.LEF; $byId('procLEFO').innerHTML = mdsi_TopProcessData.LEFO; $byId('procMWAIT').innerHTML = mdsi_TopProcessData.MWAIT; $byId('procSUSP').innerHTML = mdsi_TopProcessData.SUSP; $byId('procSUSPO').innerHTML = mdsi_TopProcessData.SUSPO; $byId('procPFW').innerHTML = mdsi_TopProcessData.PFW; $byId('procSwapped').innerHTML = mdsi_TopProcessData.swapped; $byId('procWaiting').innerHTML = mdsi_TopProcessData.waiting; var tops = [ "cpu", "sek", "flts", "bio", "dio" ]; for (var cnt = 0; cnt < tops.length; cnt++) { var html = ''; var procTop = mdsi_TopProcessData.top[tops[cnt]]; for (var idx = 0; idx < procTop.length; idx++) html += '' + procTop[idx] + '\n'; while (idx++ < 5) html += '\n'; tops[cnt] = html; } $byId('topCPU').innerHTML = tops[0]; $byId('topSEK').innerHTML = tops[1]; $byId('topFLTS').innerHTML = tops[2]; $byId('topBIO').innerHTML = tops[3]; $byId('topDIO').innerHTML = tops[4]; acmeAdjustSize(); } /////////////////////////////////////////////////////////////////////////////// /* A top process PID (or anything in the process data) has been clicked. Extract the leading PID in that string and inform the collection script to start collecting that process' data. Is also called if the returned data PID is zero (process doesn't or no longer exist). See mdsiDisplayPerProcess(). */ function mdsiTopPidClick (that) { var pertab = $byId('perTab'); if (mdsi_AccessData.process != 2) { mdsi_PerProcessPid = 0; pertab.style.display = 'none'; mdsiPerHistoryClick(false); mdsiAlert('Per-process access forbidden.'); } else if (that && that.innerHTML) { mdsi_PerProcessPid = that.innerHTML.substr(0,8); pertab.ondblclick = mdsiTopPidClick; // non-WebSocket defers displaying per-process until it receives data if ($WebSocket) pertab.style.display = 'block'; } else { mdsi_PerProcessPid = 0; pertab.style.display = 'none'; mdsiPerHistoryClick(false); } if (mdsi_PerProcessPid != mdsi_PrevPerProcessPid) { mdsi_PrevPerProcessPid = mdsi_PerProcessPid; acmeIpcSend(mdsiTheseData()); acmeAdjustSize(); } } /////////////////////////////////////////////////////////////////////////////// /* Display the per-process data returned from the collection script. Note if the process does not / no longer exists the per-process display is disabled. */ function mdsiDisplayPerProcess (that) { if (!mdsi_PerProcessPid) return; if (!mdsi_PerProcessData) return; if (parseInt(mdsi_PerProcessData.PID,16) == 0) { mdsi_PerProcessPid = 0; $byId('perPID').style.color = 'red'; return; } $byId('perPID').style.color = 'inherit'; // non-WebSocket defers displaying per-process until it receives data var pertab = $byId('perTab'); if (pertab.style.display != 'block') pertab.style.display = 'block'; $byId('perPID').innerHTML = mdsi_PerProcessData.PID + ' (' + mdsi_PerProcessData.creator + ')'; $byId('perUSER').innerHTML = mdsi_PerProcessData.userName + ' ' + mdsi_PerProcessData.UIC; $byId('perPRCN').innerHTML = mdsi_PerProcessData.prcNam; $byId('perIMAG').innerHTML = mdsi_PerProcessData.imagName; $byId('perPRI').innerHTML = mdsi_PerProcessData.priority; $byId('perLGIN').innerHTML = mdsi_PerProcessData.login; $byId('perCNCT').innerHTML = mdsi_PerProcessData.connect; $byId('perSTA').innerHTML = mdsi_PerProcessData.state; $byId('perTERM').innerHTML = mdsi_PerProcessData.terminal; $byId('perCPU').innerHTML = mdsi_PerProcessData.CPU; $byId('perWSET').innerHTML = mdsi_PerProcessData.WSET; $byId('perPGS').innerHTML = mdsi_PerProcessData.PGS; $byId('perPGFL').innerHTML = mdsiPerProcessAlert('PGFL'); $byId('perAST').innerHTML = mdsiPerProcessAlert('AST'); $byId('perBIO').innerHTML = mdsiPerProcessAlert('BIO'); $byId('perDIO').innerHTML = mdsiPerProcessAlert('DIO'); $byId('perENQ').innerHTML = mdsiPerProcessAlert('ENQ'); $byId('perVIRT').innerHTML = mdsiPerProcessAlert('VIRT'); $byId('perFIL').innerHTML = mdsiPerProcessAlert('FIL'); $byId('perBYT').innerHTML = mdsiPerProcessAlert('BYT'); $byId('perPRC').innerHTML = mdsiPerProcessAlert('PRC'); $byId('perTQ').innerHTML = mdsiPerProcessAlert('TQ'); $byId('perKTH').innerHTML = mdsi_PerProcessData.KTH; $byId('perFLTCNT').innerHTML = mdsi_PerProcessData.pageFlts; $byId('perBIOCNT').innerHTML = mdsi_PerProcessData.bufIO; $byId('perDIOCNT').innerHTML = mdsi_PerProcessData.dirIO; $byId('perVOLUME').innerHTML = mdsi_PerProcessData.volumes; mdsiGraphPerProcess(); } /////////////////////////////////////////////////////////////////////////////// /* Per-process quotas are provided with a leading exclamation mark if the remaining quota is less than MONDESI_PROC_ALERT logical name value. */ function mdsiPerProcessAlert (datum) { datum = mdsi_PerProcessData[datum]; if (datum.substr(0,1) == '!') return '' + datum.substr(1) + ''; else return datum; } /////////////////////////////////////////////////////////////////////////////// /* The per-process history checkbox has been clicked. */ function mdsiPerHistoryClick (state) { var cbx = $byId('checkboxPerHistory'); var perdiv = $byId('perHistoryDiv'); if (typeof state != 'undefined') mdsi_PerHistoryDisplay = !state; if (mdsi_PerHistoryDisplay) { mdsi_PerHistoryDisplay = false; cbx.checked = false; perdiv.style.display = 'none'; } else { mdsi_PerHistoryDisplay = true; cbx.checked = true; perdiv.style.display = 'block'; } acmeAdjustSize(); } /////////////////////////////////////////////////////////////////////////////// /* Return how long MonDeSi has been collecting for. */ var mdsi_CollectLastFor = '', mdsi_CollectStartTime = new Date(); function mdsiCollectFor (zero) { if (typeof zero != 'undefined' && zero) mdsi_CollectStartTime = new Date(); if (!mdsi_CollectDisplay) return mdsi_CollectLastFor; var now = new Date(); var then = mdsi_CollectStartTime; var diff = (Math.abs((now.getTime() - then.getTime()) / 1000)).toFixed(0); var secs = Math.floor(diff % 60).toFixed(0); diff /= 60; var mins = Math.floor(diff % 60).toFixed(0); diff /= 60; var hours = Math.floor(diff % 24).toFixed(0); diff /= 24; var days = Math.floor(diff).toFixed(0); if (hours < 10) hours = '0' + hours; if (mins < 10) mins = '0' + mins; if (secs < 10) secs = '0' + secs; mdsi_CollectLastFor = ''; if (parseInt(days) > 0) mdsi_CollectLastFor = days + ' '; mdsi_CollectLastFor += hours + ':' + mins + ':' + secs; return mdsi_CollectLastFor; } /////////////////////////////////////////////////////////////////////////////// /* The "mem"ory history or "pgfl" history graph has been clicked. Switch between them. */ function memPgflClick (that) { if (that.id == 'memHist') { that.style.display = 'none'; $byId('pgflHist').style.display = 'inline-block'; } else { that.style.display = 'none'; $byId('memHist').style.display = 'inline-block'; } } /////////////////////////////////////////////////////////////////////////////// /* The "network" history or "datagram" history graph has been clicked. Switch between them. */ function netDgramClick (that) { if (that.id == 'netHist') { that.style.display = 'none'; $byId('netDgramHist').style.display = 'inline-block'; } else { that.style.display = 'none'; $byId('netHist').style.display = 'inline-block'; } } /////////////////////////////////////////////////////////////////////////////// /* The per-process "wset" working set history or "pgfl" pagefile history graph has been clicked. Switch between them. */ function perWsetPgflClick (that) { if (that.id == 'perWsetHist') { that.style.display = 'none'; $byId('perPgflHist').style.display = 'inline-block'; } else { that.style.display = 'none'; $byId('perWsetHist').style.display = 'inline-block'; } } ///////////////////////////////////////////////////////////////////////////////