File: //usr/lib/fm-agent/plugins/tomcat.py
import re
import agent_util
from plugins.tomcat_jmx import TomcatJMXPlugin
import logging
try:
from bs4 import BeautifulSoup
except:
try:
import BeautifulSoup
except:
BeautifulSoup = None
from agent_util import float
logger = logging.getLogger(__name__)
def execute_query(config, query):
username = config['username'].strip()
password = config["password"].strip()
url = config['console_url']
queryType = 'wget -qO-'
query = query % (queryType, url, username, password)
ret, output = agent_util.execute_command(query)
return str(output)
def get_all_data(config):
query = '%s %s/manager/status/all --user=%s --password=%s'
output = str(execute_query(config, query))
dom = BeautifulSoup(output)
def parse_item(item, prefix):
res = ""
for line in item.contents:
if isinstance(line, basestring) and not line.strip().startswith("Start time"):
res += "%s " % line
results = {}
for res in re.findall(r"((.*?):\s(.*?)\s((ms|MB|s)\s)?)", res ):
key = "%s/%s" % (prefix, res[1].strip())
results[key] = {
"value": float(res[2]),
"unit": res[4]
}
return results
data = {}
all_items = []
for heading in reversed(dom.select('h1')):
heading_text = heading.string.strip('"')
if heading_text == 'Application list': continue
if heading_text == 'JVM':
data[heading_text] = {}
p = heading.find_next("p")
data[heading_text].update(parse_item(p, "Total"))
table = heading.find_next("table")
if not table: continue
for item in table.find("tbody").find_all("tr"):
try:
row = item.find_all("td")
row = [i.text for i in row]
mem_type = row[1].replace(" memory", "")
pool = row[0]
result = {}
result['%s/Initial' % mem_type] = {
"value": float(row[2].split(" ")[0]),
"unit": row[2].split(" ")[1]
}
result['%s/Total' % mem_type] = {
"value": float(row[3].split(" ")[0]),
"unit": row[3].split(" ")[1]
}
result['%s/Max' % mem_type] = {
"value": float(row[4].split(" ")[0]),
"unit": row[4].split(" ")[1]
}
result['%s/Used' % mem_type] = {
"value": float(row[5].split(" ")[0]),
"unit": row[5].split(" ")[1]
}
result['%s/Used Percentage' % mem_type] = {
"value": float(re.findall("\(([0-9]*)%\)", row[5])[0]),
"unit": "%"
}
data[pool] = result
except Exception:
import sys
_, e, _ = sys.exc_info()
logging.getLogger("plugin 'tomcat'").error(str(e))
pass
continue
data[heading_text] = {}
p = heading.find_next("p")
data[heading_text].update(parse_item(p, "Total"))
for item in heading.find_all_next("h2"):
if item not in all_items:
item['id'] = len(all_items)
all_items.append(item)
p = item.find_next("p")
data[heading_text].update(parse_item(p, item.string.split("[")[0].strip()))
reverse_data = {}
for option, metrics in data.items():
for metric, properties in metrics.items():
metric = metric[0].upper() + metric[1:]
if metric not in reverse_data:
reverse_data[metric] = {
"unit": properties["unit"],
"options": {}
}
reverse_data[metric]["options"][option] = properties["value"]
return reverse_data
class TomcatPlugin(agent_util.Plugin):
textkey = "tomcat"
label = "Tomcat"
@classmethod
def get_metadata(self, config):
if 'username' in config and 'console_url' in config and 'password' in config: # Tomcat via wget Plugin
status = agent_util.SUPPORTED
msg = None
# check for tomcat configuration block
if ("username" not in config or "console_url" not in config or "password" not in config or BeautifulSoup == None):
self.log.info("tomcat is not configured")
status = agent_util.MISCONFIGURED
msg = "tomcat is not configured properly"
return {}
# check if tomcat is even installed or running
ret, output = agent_util.execute_command('wget -qO- %s' % config['console_url'])
if config.get("debug", False):
self.log.debug('#####################################################')
self.log.debug("Tomcat command 'wget -qO- %s' output:" % config['console_url'])
self.log.debug(str(output))
self.log.debug('#####################################################')
if ret != 0:
self.log.info("tomcat is not running or installed")
status = agent_util.UNSUPPORTED
msg = "tomcat not found"
return {}
data = {}
for metric, properties in get_all_data(config).items():
data[metric] = {
"label": metric,
"options": sorted(properties["options"].keys()),
"status": status,
"error_message": msg,
"unit": properties["unit"] or None
}
return data
elif 'host' in config and 'port' in config: # Tomcat via JMX Plugin
return TomcatJMXPlugin.get_metadata(config)
self.log.error(("tomcat is not configured: you must have either a set"
" of [username, console_url, password] or [host, port]"
" configured in your tomcat application block."))
return {}
def check(self, textkey, data, config):
if 'username' in config and 'console_url' in config and 'password' in config: # Tomcat via wget Plugin
try: return get_all_data(config)[textkey]['options'][data]
except: return 0
elif 'host' in config and 'port' in config: # Tomcat via JMX Plugin
return TomcatJMXPlugin.check(textkey, data, config)
self.log.error(("tomcat is not configured: you must have either a set"
" of [username, console_url, password] or [host, port]"
" configured in your tomcat application block."))
return 0