You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

139 lines
3.4 KiB
Python

import sys, os, json
from datetime import datetime
# We need to set both the Python module path and system environment path, to make sure that the daemon
# can find both the psutil library and its compiled libraries.
sys.path.insert(0, "%s/lib" % os.path.split(os.path.realpath(__file__))[0])
os.environ['PATH'] = "%s/lib:%s" % (os.path.split(os.path.realpath(__file__))[0], os.environ['PATH'])
import psutil
import urlparse
import SocketServer, SimpleHTTPServer
bind_ip = ""
port = 8081
def generate_stats(get_processes):
listed_filesystems = ["ext2", "ext3", "ext4", "reiserfs", "removable", "fixed", "simfs"]
mem = psutil.virtual_memory()
swap = psutil.swap_memory()
disks = {}
for disk in psutil.disk_partitions(True):
if disk.fstype in listed_filesystems:
usage = psutil.disk_usage(disk.mountpoint)
disks[disk.mountpoint] = {
"device": disk.device,
"options": disk.opts,
"filesystem": disk.fstype,
"total": usage.total,
"free": usage.free
}
uptime = (datetime.now() - datetime.fromtimestamp(psutil.BOOT_TIME))
return_data = {
"uptime": (uptime.microseconds + (uptime.seconds + uptime.days * 24 * 3600) * 10**6) / 10**6,
"memory": {
"total": mem.total,
"available": mem.available,
"used": mem.used,
"unused": mem.free
},
"swap": {
"total": swap.total,
"used": swap.used,
"unused": swap.free,
"in": swap.sin,
"out": swap.sout
},
"disk": disks,
"cpu": psutil.cpu_percent(percpu=True),
"load": list(os.getloadavg())
}
if get_processes:
processes = []
for proc in psutil.process_iter():
try:
cwd = proc.getcwd()
except psutil.AccessDenied, e:
cwd = None
processes.append({
"pid": proc.pid,
"parent": proc.ppid,
"name": proc.name,
"command": proc.cmdline,
"user": proc.username,
"status": str(proc.status), # If we don't explicitly use str() here, json module will get confused
"cwd": cwd,
"cpu": proc.get_cpu_percent(interval=0.1),
"rss": proc.get_memory_info()[0]
})
return_data['process'] = processes
return return_data
class StatsHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
def do_GET(self):
req = urlparse.urlparse(self.path)
get_params = urlparse.parse_qs(req.query)
path = req.path
try:
get_processes = (get_params['processes'][0] == "1")
except:
get_processes = False
if path=='/':
self.send_response(200)
self.send_header('Content-type','text/json')
self.end_headers()
self.wfile.write(json.dumps(generate_stats(get_processes)))
return
else:
self.send_response(404)
self.send_header('Content-type','text/plain')
self.end_headers()
self.wfile.write("404 Not Found")
return
#### Hacky way to daemonize the whole thing
# Fork away
if os.fork(): exit(0)
os.umask(0)
os.setsid()
if os.fork(): exit(0)
# Write PID to file
outfile = open("pylsa.pid", "w")
outfile.write('%i' % os.getpid())
outfile.close()
# Bind the server
httpd = SocketServer.ThreadingTCPServer((bind_ip, port), StatsHandler, False)
httpd.allow_reuse_address = True
httpd.server_bind()
httpd.server_activate()
# If all went well, we'll redirect streams to silence them
sys.stdout.flush()
sys.stderr.flush()
si = file('/dev/null', 'r')
so = file('/dev/null', 'a+')
se = file('/dev/null', 'a+', 0)
os.dup2(si.fileno(), sys.stdin.fileno())
os.dup2(so.fileno(), sys.stdout.fileno())
os.dup2(se.fileno(), sys.stderr.fileno())
# Done!
print 'Port=',port
httpd.serve_forever()