File: //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(r"\(([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