Skip to content

Instantly share code, notes, and snippets.

@marcguyer
Last active August 29, 2015 13:58
Show Gist options
  • Save marcguyer/9955458 to your computer and use it in GitHub Desktop.
Save marcguyer/9955458 to your computer and use it in GitHub Desktop.
Supervisord memory check plugin for serverdensity.io
#!/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