import agent_util
import socket
def get_stats(host, port):
size = 4096#1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host,int(port)))
s.send("stats \n")
data = s.recv(size)
data = data.replace("STAT ","").replace("END", "")
stats = dict(metric.split(" ",1) for metric in data.splitlines() if metric != '')
s.close()
return stats
class MemcachePlugin(agent_util.Plugin):
textkey = "memcache"
label = "Memcache"
@classmethod
def get_metadata(self, config):
status = agent_util.SUPPORTED
msg = None
# check if memcached is even installed
installed = agent_util.which("memcached")
if not installed:
self.log.info("memcached binary not found")
status = agent_util.UNSUPPORTED
return {}
if not config:
msg = "The [memcache] config block is not found in the agent config file."
self.log.info(msg)
status = agent_util.MISCONFIGURED
if status == agent_util.SUPPORTED and (not "hostname" in config or not "port" in config):
msg = "hostname or port missing from the [memcache] block in the agent config file."
self.log.info(msg)
status = agent_util.MISCONFIGURED
if status == agent_util.SUPPORTED:
try:
stats = get_stats(config['hostname'], config['port'])
except:
status = agent_util.MISCONFIGURED
msg = "Unable to get memcache status information, please double check hostname and port on config file."
self.log.error(msg)
metadata = {
"bytes": {
"label": "Number of bytes",
"options": None,
"status": status,
"error_message": msg,
"unit": "B"
},
"bytes_read": {
"label": "Total number of bytes read",
"options": None,
"status": status,
"error_message": msg,
"unit": "B"
},
"bytes_written": {
"label": "Total number of bytes sent",
"options": None,
"status": status,
"error_message": msg,
"unit": "B"
},
"cmd_get": {
"label": "Total number of retrieval requests (get operations)",
"options": None,
"status": status,
"error_message": msg,
"unit": "requests"
},
"cmd_set": {
"label": "Total number of storage requests (set operations)",
"options": None,
"status": status,
"error_message": msg,
"unit": "requests"
},
"connection_structures": {
"label": "Number of connection structures",
"options": None,
"status": status,
"error_message": msg,
"unit": "structures"
},
"curr_connections": {
"label": "Current number of open connections",
"options": None,
"status": status,
"error_message": msg,
"unit": "connections"
},
"curr_items": {
"label": "Current number of items",
"options": None,
"status": status,
"error_message": msg,
"unit": "items"
},
"evictions": {
"label": "Number of valid items removed from cache to free memory for new items",
"options": None,
"status": status,
"error_message": msg,
"unit": "items"
},
"get_hits": {
"label": "Number of keys that have been requested and found present",
"options": None,
"status": status,
"error_message": msg,
"unit": "keys"
},
"get_misses": {
"label": "Number of items that have been requested and not found",
"options": None,
"status": status,
"error_message": msg,
"unit": "items"
},
"pointer_size": {
"label": "Size of pointers",
"options": None,
"status": status,
"error_message": msg,
"unit": "bits"
},
"rusage_system": {
"label": "Total system time",
"options": None,
"status": status,
"error_message": msg,
"unit": "seconds:microseconds"
},
"rusage_user": {
"label": "Total user time",
"options": None,
"status": status,
"error_message": msg,
"unit": "seconds:microseconds"
},
"threads": {
"label": "Number of worker threads requested",
"options": None,
"status": status,
"error_message": msg,
"unit": "threads"
},
"total_connections": {
"label": "Total number of connections opened",
"options": None,
"status": status,
"error_message": msg,
"unit": "connections"
},
"total_items": {
"label": "Total number of items stored",
"options": None,
"status": status,
"error_message": msg,
"unit": "items"
}
}
return metadata
def check(self, textkey, data, config):
stats = get_stats(config['hostname'], config['port'])
res = 0
try:
res = int(stats[textkey])
except:
res = 0
return res