#!/usr/bin/python
import sys
import os
import subprocess
import time
import re
class MessageStore:
def __init__(self, id):
self._id = id
self._buffer = ''
self._recommendation = ''
self._last_update = 0
def add_message(self, msg, level):
self._buffer = '%s [%15s] %s' % (self.__colourise_level(level), self._id, msg)
self.last_update = time.strftime('%a %H:%M:%S')
def add_recommendation(self, msg):
self._recommendation = msg
def percentage_bar(self, percentage):
percent_to_fill = int(percentage/10)
return '[%s%s]' % ("+" * percent_to_fill*2, " " * int(10-percent_to_fill)*2)
def __colourise_level(self,level):
_red = '\033[1;37;41m'
_green = '\033[1;37;42m'
_yellow = '\033[1;37;43m'
_no_colour = '\033[0m'
if level == 'error':
return '%s SERIOUS %s' % (_red, _no_colour)
elif level == 'warning':
return '%s WARNING %s' % (_yellow, _no_colour)
else:
return '%s OK %s' % (_green, _no_colour)
def get_last_update_time(self):
return self._last_update
def get_recommendation(self):
return self._recommendation
def get_buffer(self):
return self._buffer
class MemoryMonitor(MessageStore):
def __init__(self, target, interval, limit_mb):
MessageStore.__init__(self, 'Memory Monitor')
self.target = target
self.interval = interval
self.last_update_t = 0
self.limit_mb = int(limit_mb)
def update(self):
if time.time() >= self.last_update_t + self.interval:
r = self.get_memory_usage()
self.add_message(r[0], r[1])
self.add_recommendation(r[2])
self.last_update_t = time.time()
def generate_recommendation(self, level):
recommendation = ''
if level == 'error':
recommendation = 'High memory usage detected, consider restarting process (pkill )'
return recommendation
def get_memory_usage(self):
p = subprocess.Popen("pgrep -f \"%s\" | xargs -n 1 pmap" % self.target, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE);
(stdout, stderr) = p.communicate()
sum = 0.0
for line in stdout.splitlines():
if "heap" in line or "stack" in line or "anon" in line:
#if "dev:" in line:
heap = re.split(" +", line)
sum = sum + int(heap[1].replace('K',''))
if sum/1024 >= self.limit_mb:
level = 'error'
elif sum/1024 >= self.limit_mb*0.9:
level = 'warning'
else:
level = 'ok'
#msg = '%15s %9.1fM [%s]' % (self.target, sum/1024, "+" * int(sum/102400))
msg = '%15s %9.1fM %s' % (self.target, sum/1024, self.percentage_bar((sum/1024)/self.limit_mb*100))
return [msg, level, self.generate_recommendation(level)]
class DiskMonitor(MessageStore):
def __init__(self, target, interval, limit_perc):
MessageStore.__init__(self, 'Disk Monitor')
self.target = target
self.interval = interval
self.last_update_t = 0
self.limit_perc = int(limit_perc)
def update(self):
if time.time() >= self.last_update_t + self.interval:
r = self.get_disk_usage()
self.add_message(r[0], r[1])
self.add_recommendation(r[2])
self.last_update_t = time.time()
def generate_recommendation(self, level):
recommendation = ''
if level == 'error':
recommendation = 'You got a problem.'
elif level == 'warning':
recommendation = 'Better watch out.'
return recommendation
def get_disk_usage(self):
p = subprocess.Popen("df -h %s | tail -1 | awk '{print $5}'" % self.target, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE);
(stdout, stderr) = p.communicate()
usage_perc = int(stdout.strip()[0:-1])
recommendation = ''
if usage_perc >= self.limit_perc:
level = 'error'
elif usage_perc >= self.limit_perc*0.9:
level = 'warning'
else:
level = 'ok'
msg = '%15s %7d%% %s' % (self.target, usage_perc, self.percentage_bar(usage_perc))
return [msg, level, self.generate_recommendation(level)]
class ZombieProcesses(MessageStore):
def __init__(self, interval):
MessageStore.__init__(self, 'Zombie Monitor')
self.interval = interval
self.last_update_t = 0
def update(self):
if time.time() >= self.last_update_t + self.interval:
r = self.find_zombies()
self.add_message(r[0], r[1])
self.last_update_t = time.time()
def find_zombies(self):
p = subprocess.Popen("ps -ef | grep defunct | grep -v grep | awk '{print $2,$8}'" , shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE);
(stdout, stderr) = p.communicate()
lines = []
recommendation = ''
if not stdout == '':
lines = stdout.strip().split("\n")
if len(lines) > 0:
level = 'warning'
else:
level = 'ok'
msg = " Found %d zombie processes" % len(lines)
if len(lines) > 0:
for line in lines:
print line
msg += "\n %30s" % line
return [msg, level, recommendation]
class CPUMonitor(MessageStore):
def __init__(self, interval, limit):
MessageStore.__init__(self, 'CPU Monitor')
self.interval = interval
self.limit = int(limit)
self.last_update_t = 0
def update(self):
if time.time() >= self.last_update_t + self.interval:
r = self.get_cpu_usage()
self.add_message(r[0], r[1])
self.last_update_t = time.time()
def generate_recommendation(self, level):
recommendation = ''
if level == 'error':
recommendation = 'Very high CPU percentage detected, a high CPU percentage could affect stability. Try closing unnecessary scripts running on the machine.'
return recommendation
def get_cpu_usage(self):
p = subprocess.Popen("sar 1 | tail -1 | awk '{print $2}'" , shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE);
(stdout, stderr) = p.communicate()
cpu_usage = int(stdout.strip())
recommendation = ''
if cpu_usage >= self.limit:
level = 'error'
elif cpu_usage >= self.limit*0.9:
level = 'warning'
else:
level = 'ok'
msg = " CPU usage %7d%% %s" % (cpu_usage, self.percentage_bar(cpu_usage))
return [msg, level, self.generate_recommendation(level)]
def clear_screen():
print "\033[1;1f\033[2K"
if __name__ == "__main__":
processes = [MemoryMonitor('chrome', 60, 400),
MemoryMonitor('compiz', 60, 12000),
DiskMonitor('/tmp', 60, 90),
DiskMonitor('/home', 120, 80),
CPUMonitor(20, 80)
]
print "\033[2J"
while True:
clear_screen()
print time.strftime('%a %H:%M:%S')
last_process_id = ''
recommendations = []
for process in processes:
if process._id != last_process_id:
print "\n"
last_process_id = process._id
process.update()
if process.get_recommendation() != '':
recommendations.append(process.get_recommendation())
print process.get_buffer()
if len(recommendations):
print ''
print '---------------------------------------------'
print ''
print ("\n").join(recommendations)
time.sleep(2)
Recent Comments