[or-cvs] r23912: {arm} Including arm cpu usage in the header panel and logs. (in arm/trunk: . src/interface)

Damian Johnson atagar1 at gmail.com
Thu Dec 9 17:25:26 UTC 2010


Author: atagar
Date: 2010-12-09 17:25:25 +0000 (Thu, 09 Dec 2010)
New Revision: 23912

Modified:
   arm/trunk/ChangeLog
   arm/trunk/README
   arm/trunk/src/interface/controller.py
   arm/trunk/src/interface/headerPanel.py
Log:
Including arm cpu usage in the header panel and logs.



Modified: arm/trunk/ChangeLog
===================================================================
--- arm/trunk/ChangeLog	2010-12-09 17:14:35 UTC (rev 23911)
+++ arm/trunk/ChangeLog	2010-12-09 17:25:25 UTC (rev 23912)
@@ -42,6 +42,8 @@
     * fix: making the interface more resilient to being resized while popups are visible
     * fix: log panel wasn't respecting the prepopulate* log level config options
     * fix: off by one error when wrapping lines in the log panel
+    * fix (11/30/10, r23882): install script was failing to make the temporary directory for the compressed man page
+    * fix (11/30/10, r23882): a torrc validation log entries had a typo
 
 10/6/10 - version 1.3.7 (r23439)
 Numerous improvements, most notably being an expanded log panel, installer, and deb/rpm builds.

Modified: arm/trunk/README
===================================================================
--- arm/trunk/README	2010-12-09 17:14:35 UTC (rev 23911)
+++ arm/trunk/README	2010-12-09 17:25:25 UTC (rev 23912)
@@ -26,11 +26,23 @@
   ... or including 'ControlPort <PORT>' in your torrc
 
 For full functionality this also needs:
-Common *nix commands including: ps, pidof, tail, pwdx, host, ulimit, and a
-  method of connection resolution (netstat, ss, or lsof)
-To be ran with the same user as tor to avoid permission issues with connection
-  resolution and reading the torrc
+- To be ran with the same user as tor to avoid permission issues with
+  connection resolution and reading the torrc.
 
+- Common *nix commands including:
+    * ps
+    * a method of connection resolution (any of the following):
+      * sockstat
+      * netstat
+      * ss
+      * lsof
+      * procstat
+    * tail
+    * pwdx
+    * ulimit
+    * pgrep or pidof
+    * host (if dns lookups are enabled)
+
 This is started via 'arm' (use the '--help' argument for usage).
 
 -------------------------------------------------------------------------------

Modified: arm/trunk/src/interface/controller.py
===================================================================
--- arm/trunk/src/interface/controller.py	2010-12-09 17:14:35 UTC (rev 23911)
+++ arm/trunk/src/interface/controller.py	2010-12-09 17:25:25 UTC (rev 23912)
@@ -535,7 +535,7 @@
   connections.RESOLVER_FINAL_FAILURE_MSG += " (connection related portions of the monitor won't function)"
   
   panels = {
-    "header": headerPanel.HeaderPanel(stdscr, config),
+    "header": headerPanel.HeaderPanel(stdscr, startTime, config),
     "popup": Popup(stdscr, 9),
     "graph": graphing.graphPanel.GraphPanel(stdscr),
     "log": logPanel.LogPanel(stdscr, loggedEvents, config)}
@@ -717,7 +717,10 @@
       
       currentTime = time.time()
       if currentTime - lastPerformanceLog >= CONFIG["queries.refreshRate.rate"]:
-        log.log(CONFIG["log.refreshRate"], "refresh rate: %0.3f seconds" % (currentTime - redrawStartTime))
+        cpuTotal = sum(os.times()[:3])
+        cpuAvg = cpuTotal / (currentTime - startTime)
+        
+        log.log(CONFIG["log.refreshRate"], "refresh rate: %0.3f seconds, average cpu usage: %0.3f%%" % (currentTime - redrawStartTime, 100 * cpuAvg))
         lastPerformanceLog = currentTime
     finally:
       panel.CURSES_LOCK.release()

Modified: arm/trunk/src/interface/headerPanel.py
===================================================================
--- arm/trunk/src/interface/headerPanel.py	2010-12-09 17:14:35 UTC (rev 23911)
+++ arm/trunk/src/interface/headerPanel.py	2010-12-09 17:25:25 UTC (rev 23912)
@@ -38,16 +38,16 @@
   """
   Top area contenting tor settings and system information. Stats are stored in
   the vals mapping, keys including:
-    tor/ version, versionStatus, nickname, orPort, dirPort, controlPort,
-         exitPolicy, isAuthPassword (bool), isAuthCookie (bool)
-         *address, *fingerprint, *flags
-    sys/ hostname, os, version
-    ps/  *%cpu, *rss, *%mem, pid, *etime
+    tor/  version, versionStatus, nickname, orPort, dirPort, controlPort,
+          exitPolicy, isAuthPassword (bool), isAuthCookie (bool)
+          *address, *fingerprint, *flags
+    sys/  hostname, os, version
+    stat/ *%torCpu, *%armCpu, *rss, *%mem, pid, *etime
   
   * volatile parameter that'll be reset on each update
   """
   
-  def __init__(self, stdscr, config=None):
+  def __init__(self, stdscr, startTime, config=None):
     panel.Panel.__init__(self, stdscr, "header", 0)
     threading.Thread.__init__(self)
     self.setDaemon(True)
@@ -61,6 +61,20 @@
     self._cond = threading.Condition()  # used for pausing the thread
     self._config = dict(DEFAULT_CONFIG)
     
+    # The last arm cpu usage sampling taken. This is a tuple of the form:
+    # (total arm cpu time, sampling timestamp)
+    # 
+    # The initial cpu total should be zero. However, at startup the cpu time
+    # in practice is often greater than the real time causing the initially
+    # reported cpu usage to be over 100% (which shouldn't be possible on
+    # single core systems).
+    # 
+    # Setting the initial cpu total to the value at this panel's init tends to
+    # give smoother results (staying in the same ballpark as the second
+    # sampling) so fudging the numbers this way for now.
+    
+    self._armCpuSampling = (sum(os.times()[:3]), startTime)
+    
     if config:
       config.update(self._config, {"queries.ps.rate": 1})
     
@@ -138,13 +152,13 @@
     
     # Line 3 / Line 1 Right (system usage info)
     y, x = (0, leftWidth) if isWide else (2, 0)
-    if self.vals["ps/rss"] != "0": memoryLabel = uiTools.getSizeLabel(int(self.vals["ps/rss"]) * 1024)
+    if self.vals["stat/rss"] != "0": memoryLabel = uiTools.getSizeLabel(int(self.vals["stat/rss"]) * 1024)
     else: memoryLabel = "0"
     
-    sysFields = ((0, "cpu: %s%%" % self.vals["ps/%cpu"]),
-                 (13, "mem: %s (%s%%)" % (memoryLabel, self.vals["ps/%mem"])),
-                 (34, "pid: %s" % (self.vals["ps/pid"] if self._isTorConnected else "")),
-                 (47, "uptime: %s" % self.vals["ps/etime"]))
+    sysFields = ((0, "cpu: %s%% tor, %s%% arm" % (self.vals["stat/%torCpu"], self.vals["stat/%armCpu"])),
+                 (27, "mem: %s (%s%%)" % (memoryLabel, self.vals["stat/%mem"])),
+                 (47, "pid: %s" % (self.vals["stat/pid"] if self._isTorConnected else "")),
+                 (59, "uptime: %s" % self.vals["stat/etime"]))
     
     for (start, label) in sysFields:
       if start + len(label) <= rightWidth: self.addstr(y, x + start, label)
@@ -310,15 +324,16 @@
       self.vals["sys/version"] = unameVals[2]
       
       pid = conn.getMyPid()
-      self.vals["ps/pid"] = pid if pid else ""
+      self.vals["stat/pid"] = pid if pid else ""
       
       # reverts volatile parameters to defaults
       self.vals["tor/fingerprint"] = "Unknown"
       self.vals["tor/flags"] = []
-      self.vals["ps/%cpu"] = "0"
-      self.vals["ps/rss"] = "0"
-      self.vals["ps/%mem"] = "0"
-      self.vals["ps/etime"] = ""
+      self.vals["stat/%torCpu"] = "0"
+      self.vals["stat/%armCpu"] = "0"
+      self.vals["stat/rss"] = "0"
+      self.vals["stat/%mem"] = "0"
+      self.vals["stat/etime"] = ""
     
     # sets volatile parameters
     volatile = {}
@@ -333,32 +348,44 @@
     
     # ps derived stats
     psParams = ["%cpu", "rss", "%mem", "etime"]
-    if self.vals["ps/pid"]:
+    if self.vals["stat/pid"]:
       # if call fails then everything except etime are zeroed out (most likely
       # tor's no longer running)
-      volatile["ps/%cpu"] = "0"
-      volatile["ps/rss"] = "0"
-      volatile["ps/%mem"] = "0"
+      volatile["stat/%torCpu"] = "0"
+      volatile["stat/rss"] = "0"
+      volatile["stat/%mem"] = "0"
       
       # the ps call formats results as:
       # %CPU   RSS %MEM     ELAPSED
       # 0.3 14096  1.3       29:51
       psRate = self._config["queries.ps.rate"]
-      psCall = sysTools.call("ps -p %s -o %s" % (self.vals["ps/pid"], ",".join(psParams)), psRate, True)
+      psCall = sysTools.call("ps -p %s -o %s" % (self.vals["stat/pid"], ",".join(psParams)), psRate, True)
       
       if psCall and len(psCall) >= 2:
         stats = psCall[1].strip().split()
         
         if len(stats) == len(psParams):
           for i in range(len(psParams)):
-            volatile["ps/" + psParams[i]] = stats[i]
+            paramName = psParams[i]
+            if paramName == "%cpu": paramName = "%torCpu"
+            volatile["stat/" + paramName] = stats[i]
     
+    # determines the cpu time for the arm process (including user and system
+    # time of both the primary and child processes)
+    
+    currentTime, totalCpuTime = time.time(), sum(os.times()[:3])
+    cpuDelta = totalCpuTime - self._armCpuSampling[0]
+    timeDelta = currentTime - self._armCpuSampling[1]
+    self.vals["stat/%armCpu"] = "%0.1f" % (100 * cpuDelta / timeDelta)
+    self._armCpuSampling = (totalCpuTime, currentTime)
+    
     # checks if any changes have been made and merges volatile into vals
+    
     self._isChanged |= setStatic
     for key, val in volatile.items():
       self._isChanged |= self.vals[key] != val
       self.vals[key] = val
     
-    self._lastUpdate = time.time()
+    self._lastUpdate = currentTime
     self.valsLock.release()
 



More information about the tor-commits mailing list