~doctormo/processmonitor/project-fixes

« back to all changes in this revision

Viewing changes to PMon.py

  • Committer: Tim Konick
  • Date: 2013-01-16 01:19:37 UTC
  • Revision ID: konick781@gmail.com-20130116011937-8wdpaggx8sd1ed28
restructure

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#!/usr/bin/env python
2
 
 
3
 
import os
4
 
import dbus
5
 
import struct
6
 
import socket
7
 
import daemon
8
 
import psutil # maybe not...
9
 
import gobject
10
 
import dbus.service
11
 
from dbus.mainloop.glib import DBusGMainLoop
12
 
 
13
 
 
14
 
"""
15
 
Time to make this latest version with netlink sockets and
16
 
 
17
 
the methods polling /sys/block/dev/... for device i/o
18
 
 
19
 
"""
20
 
 
21
 
class IoMonitor(dbus.service.Object):
22
 
 
23
 
    def __init__(self):
24
 
        name = dbus.service.BusName('org.iomonitor', dbus.SystemBus(mainloop=DBusGMainLoop()))
25
 
        dbus.service.Object.__init__(self, name, '/org/iomonitor')
26
 
        self.conn = socket.socket(socket.AF_NETLINK, socket.SOCK_RAW, 16)
27
 
        self.conn.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 65536)
28
 
        self.conn.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 65536)
29
 
        self.conn.bind((0,0))
30
 
        self.pid, self.grp = self.conn.getsockname()
31
 
 
32
 
    def grab_data(self):
33
 
        aps = []
34
 
        ps = [int(i) for i in os.listdir('/proc') if i.isdigit()]
35
 
        for pid in ps:
36
 
            front = struct.pack('HH', 1, 0)
37
 
            back = struct.pack('I', pid)
38
 
            back_hdr = struct.pack('HH', len(back) + 4, 1)
39
 
            back = back_hdr + back
40
 
            load = b''.join(front+back)
41
 
            hdr = struct.pack('IHHII', len(load) + 16, 23, 1, 1, self.pid)
42
 
            self.conn.send(hdr+load)
43
 
            t, (x, y) = self.conn.recvfrom(16384)
44
 
            t = t[20:]
45
 
            a = {}
46
 
            while 3 not in a.keys():
47
 
                while len(t):
48
 
                    atl, aty = struct.unpack('HH', t[:4])
49
 
                    a[aty] = t[4:atl]
50
 
                    t = t[atl:]
51
 
                t = a[aty]
52
 
            try:
53
 
                aps.append(['PID:', pid, 'READ:', struct.unpack('Q', t[248:256])[0],
54
 
                                 'WRITE:', struct.unpack('Q', t[256:264])[0]])
55
 
            except struct.error:
56
 
                pass
57
 
        return aps
58
 
 
59
 
    @dbus.service.method('org.iomonitor', out_signature='as')
60
 
    def process_list(self):
61
 
        pidnamelst = []
62
 
        prclst = [pid for pid in os.listdir('/proc') if pid.isdigit()]
63
 
        for pid in prclst:
64
 
            if os.path.isfile('/proc/%s/stat' % pid):
65
 
                with open('/proc/%s/stat' % pid, 'r+') as f:
66
 
                    name = f.readline()
67
 
                f.close()
68
 
                name = [j for j in name.split(' ') if '(' in j]
69
 
                pidnamelst.append(name[0][1:-1])
70
 
        return pidnamelst
71
 
 
72
 
    @dbus.service.method('org.iomonitor', out_signature='aas')
73
 
    def allprocess_stats(self):
74
 
        aps = self.grab_data()
75
 
        return aps
76
 
 
77
 
    @dbus.service.method('org.iomonitor', in_signature='s', out_signature='as')
78
 
    def process_stats(self, pid):
79
 
        aps = self.grab_data()
80
 
        for i in aps:
81
 
            if pid == str(i[1]):
82
 
                return i
83
 
        return ['No i/o']
84
 
 
85
 
    @dbus.service.method('org.iomonitor', out_signature='as')
86
 
    def process_swap(self, pid):
87
 
        # check if this best place to monitor?
88
 
        with open('/proc/swaps') as f:
89
 
            data = f.readlines()
90
 
        f.close()
91
 
        if len(data) > 1:
92
 
            return data
93
 
        return ['No swap']
94
 
 
95
 
    @dbus.service.method('org.iomonitor', out_signature='s')
96
 
    def memory(self):
97
 
        # work out psutil
98
 
        return str(psutil.avail_phymem())
99
 
 
100
 
    @dbus.service.method('org.iomonitor', in_signature='s', out_signature='as')
101
 
    def diskstats(self, disk):
102
 
        with open('/sys/block/sda/%s/stat' % disk, 'r') as f:
103
 
            data = f.readlines()
104
 
        f.close()
105
 
        data = [i for i in data[0].split(' ') if len(i) > 0]
106
 
        return ['read ' + data[0], 'write ' + data[4]]
107
 
 
108
 
    @dbus.service.method('org.iomonitor', out_signature='as')
109
 
    def disklist(self):
110
 
        # /sys/block/dev/...just sda/hda -- or all partitions??
111
 
        dl = os.listdir('/sys/block')
112
 
        return dl
113
 
 
114
 
    @dbus.service.method('org.iomonitor', out_signature='as')
115
 
    def deviceinfo(self):
116
 
        with open('/proc/scsi/scsi', 'r') as f:
117
 
            devinfo = f.readlines()
118
 
        f.close()
119
 
        return devinfo
120
 
 
121
 
if __name__ == '__main__':
122
 
    with daemon.DaemonContext():
123
 
        iom = IoMonitor
124
 
        iom()
125
 
        gobject.MainLoop().run()
126
 
 
127
 
# this will need a .conf file in /etc/dbus/system.d/...
128
 
# and also for startup execution an entry in --> sudo crontab -e @reboot
129