perprocess cpu usage added
diff --git a/sensors/host1_config.json b/sensors/host1_config.json
index 450db06..3f339c2 100644
--- a/sensors/host1_config.json
+++ b/sensors/host1_config.json
@@ -9,5 +9,8 @@
"allowed_prefixes": ["cpu"]
},
"system-ram": {
+ },
+ "perprocess-cpu": {
+ "allowed_prefixes": ["ceph"]
}
}
diff --git a/sensors/main.py b/sensors/main.py
index 8668518..7fc5ea7 100644
--- a/sensors/main.py
+++ b/sensors/main.py
@@ -10,6 +10,7 @@
import net_sensors
import syscpu_sensors
import sysram_sensors
+import pscpu_sensors
from utils import SensorInfo
from daemonize import Daemonize
diff --git a/sensors/pscpu_sensors.py b/sensors/pscpu_sensors.py
new file mode 100644
index 0000000..4e1849f
--- /dev/null
+++ b/sensors/pscpu_sensors.py
@@ -0,0 +1,64 @@
+import os
+import time
+
+from discover import provides
+from utils import SensorInfo, get_pid_name, get_pid_list
+
+
+
+@provides("perprocess-cpu")
+def pscpu_stat(disallowed_prefixes=None, allowed_prefixes=None):
+ results = {}
+ pid_stat0 = {}
+ sys_stat0 = {}
+ pid_list = get_pid_list(disallowed_prefixes, allowed_prefixes)
+
+ for pid in pid_list:
+ try:
+ pid_stat0[pid] = pid_stat(pid)
+ sys_stat0[pid] = sys_stat()
+ except IOError:
+ # may be, proc has already terminated
+ continue
+
+ time.sleep(1)
+
+ for pid in pid_list:
+ try:
+ dev_name = get_pid_name(pid)
+
+ pid_stat1 = pid_stat(pid)
+ sys_stat1 = sys_stat()
+ cpu = (pid_stat1 - pid_stat0[pid]) / (sys_stat1 - sys_stat0[pid])
+
+ sensor_name = "{0}.{1}".format(dev_name, pid)
+ results[sensor_name] = SensorInfo(cpu*100, False)
+ except IOError:
+ # may be, proc has already terminated
+ continue
+ return results
+
+
+def pid_stat(pid):
+ """ Return total cpu usage time from process"""
+ # read /proc/pid/stat
+ with open(os.path.join('/proc/', pid, 'stat'), 'r') as pidfile:
+ proctimes = pidfile.readline().split()
+ # get utime from /proc/<pid>/stat, 14 item
+ utime = proctimes[13]
+ # get stime from proc/<pid>/stat, 15 item
+ stime = proctimes[14]
+ # count total process used time
+ proctotal = int(utime) + int(stime)
+ return float(proctotal)
+
+
+def sys_stat():
+ """ Return total system cpu usage time"""
+ with open('/proc/stat', 'r') as procfile:
+ cputimes = procfile.readline().split()[1:]
+ cputotal = 0
+ # count from /proc/stat sum
+ for i in cputimes:
+ cputotal = cputotal + int(i)
+ return float(cputotal)
diff --git a/sensors/utils.py b/sensors/utils.py
index 5af0a2a..e4f45b1 100644
--- a/sensors/utils.py
+++ b/sensors/utils.py
@@ -1,3 +1,5 @@
+import os
+
from collections import namedtuple
SensorInfo = namedtuple("SensorInfo", ['value', 'is_accumulated'])
@@ -17,6 +19,41 @@
return dev_ok
+def get_pid_list(disallowed_prefixes, allowed_prefixes):
+ """ Return pid list from list of pids and names """
+ # exceptions
+ but = disallowed_prefixes if disallowed_prefixes is not None else []
+ if allowed_prefixes is None:
+ # if nothing setted - all ps will be returned except setted
+ result = [pid
+ for pid in os.listdir('/proc')
+ if pid.isdigit() and pid not in but]
+ else:
+ result = []
+ for pid in os.listdir('/proc'):
+ if pid.isdigit() and pid not in but:
+ name = get_pid_name(pid)
+ if pid in allowed_prefixes or \
+ any(name.startswith(val) for val in allowed_prefixes):
+ # this is allowed pid?
+ result.append(pid)
+ return result
+
+
+def get_pid_name(pid):
+ """ Return name by pid """
+ try:
+ with open(os.path.join('/proc/', pid, 'cmdline'), 'r') as pidfile:
+ try:
+ cmd = pidfile.readline().split()[0]
+ return os.path.basename(cmd).rstrip('\x00')
+ except IndexError:
+ # no cmd returned
+ return "no_name"
+ except IOError:
+ return "no_such_process"
+
+
def delta(func, only_upd=True):
prev = {}
while True: