Last active
August 29, 2015 13:58
-
-
Save marcguyer/9955458 to your computer and use it in GitHub Desktop.
Supervisord memory check plugin for serverdensity.io
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
""" | |
Server Density Supervisord plugin. | |
Track the number of processes in each state. | |
For possible states see the docs at | |
http://supervisord.org/subprocess.html#process-states | |
""" | |
import os | |
import httplib | |
import urllib | |
import xmlrpclib | |
from supervisor import childutils | |
from supervisor.datatypes import byte_size | |
def usage(): | |
print doc | |
sys.exit(255) | |
def shell(cmd): | |
return os.popen(cmd).read() | |
SUPERVISORD_RPC_URL = "http://localhost:9001/RPC2" | |
class SupervisordMemory(object): | |
"""Collect and return details of a local Supervisord instance. | |
""" | |
def __init__(self, agent_config, checks_logger, raw_config): | |
self.agent_config = agent_config | |
self.checks_logger = checks_logger | |
self.raw_config = raw_config | |
self.pscommand = 'ps -orss= -p %s' | |
def run(self): | |
stats = {} | |
try: | |
# # Pull the supervisord rpc URL from the config or default | |
url = self.raw_config['Main'].get('supervisord_rpc_url', | |
SUPERVISORD_RPC_URL) | |
server = xmlrpclib.Server(url) | |
except KeyError: | |
# Should only happen if Main section of config is missing | |
self.checks_logger.error('Missing sd-agent configuration') | |
server = xmlrpclib.Server(SUPERVISORD_RPC_URL) | |
try: | |
server_info = server.supervisor.getAllProcessInfo() | |
self.checks_logger.debug(server_info) | |
stats.update(self.get_process_counts(server_info)) | |
except (xmlrpclib.Fault, httplib.HTTPException), exc: | |
stats = {} | |
self.checks_logger.debug(str(exc)) | |
except Exception as e: | |
template = "An exception of type {0} occured. Arguments:\n{1!r}" | |
message = template.format(type(e).__name__, e.args) | |
self.checks_logger.error(message) | |
return stats | |
def get_process_counts(self, server_info): | |
processes = {} | |
processes['total'] = 0 | |
for info in server_info: | |
pid = info['pid'] | |
name = info['name'] | |
group = info['group'] | |
pname = '%s:%s' % (group, name) | |
processes[pname] = 0 | |
if group not in processes: | |
processes[group] = 0 | |
if not pid: | |
# ps throws an error in this case (for processes | |
# in standby mode, non-auto-started). | |
continue | |
data = shell(self.pscommand % pid) | |
if not data: | |
# no such pid (deal with race conditions) | |
continue | |
try: | |
rss = data.lstrip().rstrip() | |
rss = int(rss) * 1024 # rss is in KB | |
processes[pname] = rss | |
processes[group] += rss | |
processes['total'] += rss | |
except ValueError: | |
# line doesn't contain any data, or rss cant be intified | |
continue | |
return processes |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment