blob: 38ed733a11ee576750be65cbdd60c842f34f0cdb [file] [log] [blame]
#! /usr/bin/env python
# -----------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
# -----------------------------------------------------------------------
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# +
# + ducc_status
# +
# + purpose: report current ducc daemons status
# +
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
import datetime
import sys
import time
from HTMLParser import HTMLParser
from optparse import OptionParser
from ducc_base import find_ducc_home
from properties import *
# -----------------------------------------------------------------------
# Extend OptionParser class
class ExtendedOptionParser(OptionParser):
# override epilog formatter so
# that newlines are not deleted!
def format_epilog(self, formatter):
return self.epilog
# -----------------------------------------------------------------------
# parser for the system.daemons WS page
class DuccHtmlParser(HTMLParser):
tr_state = False
daemon_state = None
daemon_name = None
daemon_date = None
daemon_ip = None
daemon_host = None
daemons = {}
def get_daemons(self):
return self.daemons
def handle_starttag(self, tag, attrs):
if(tag == 'tr' ):
self.tr_state = True
def handle_endtag(self, tag):
if(tag == 'tr'):
self.tr_state = False
self.daemon_state = None
self.daemon_name = None
self.daemon_date = None
self.daemon_ip = None
self.daemon_host = None
def handle_data(self, data):
if(self.tr_state):
if(self.daemon_state == None):
self.daemon_state = data
elif(self.daemon_name == None):
self.daemon_name = data
if(self.daemon_name == 'Agent'):
pass
else:
self.daemons[self.daemon_name] = self.daemon_state
elif(self.daemon_date == None):
self.daemon_date = data
elif(self.daemon_ip == None):
self.daemon_ip = data
elif(self.daemon_host == None):
self.daemon_host = data
self.daemon_name = data
self.daemons[self.daemon_name] = self.daemon_state
# -----------------------------------------------------------------------
default_host = 'localhost'
default_port = '42133'
protocol = 'http://'
servlet = '/ducc-servlet/classic-system-daemons-data'
options = None
webserver = 'Webserver'
head_daemons = [ 'Orchestrator', 'ResourceManager', 'Database', 'Broker', 'ProcessManager', 'ServiceManager', webserver ]
newline = '\n'
version = '1.0'
# to console
def to_stdout(text):
try:
print text
except:
pass
try:
sys.stdout.flush()
except:
pass
def close():
try:
sys.stdout.close()
except:
pass
# check for log-style formating of text message
def is_log_format():
retVal = False
if(not options == None):
if(options.flag_log_format):
retVal = True
return retVal
# produce a time stamp
def get_timestamp():
global options
tod = time.time()
timestamp = datetime.datetime.fromtimestamp(tod).strftime('%Y-%m-%d %H:%M:%S')
return timestamp
# exception
def exception(e):
to_stdout(str(e))
# error message
def error(text):
prefix = ''
if(is_log_format()):
type = 'E'
prefix = get_timestamp()+' '+type+' '
line = prefix+text
to_stdout(line)
# info message
def info(text):
prefix = ''
if(is_log_format()):
type = 'I'
prefix = get_timestamp()+' '+type+' '
line = prefix+text
to_stdout(line)
# debug message
def debug(text):
global options
if(not options == None):
if(options.flag_debug):
prefix = ''
if(is_log_format()):
type = 'D'
prefix = get_timestamp()+' '+type+' '
line = prefix+text
to_stdout(line)
# trace message
def trace(text):
pass
# exit
def exit(code,msg=True):
if(msg):
text = 'exit code='+str(code)
error(text)
sys.exit(code)
# epilog for --help
def get_epilog():
epilog = ''
return epilog
# --target host:port of WS for fetching of daemons status
def validate_target():
global options
global default_port
global protocol
global servlet
target = options.target
if(':' not in target):
target = target+':'+default_port
if(target.startswith(protocol)):
target = target.replace(protocol,'',1)
options.ducc_url_base = protocol+target
options.ducc_url_servlet = protocol+target+servlet
debug('target: '+options.ducc_url_base)
# parse command line
def parse_cmdline():
global options
global default_host
global default_port
parser = ExtendedOptionParser(epilog=get_epilog())
width = 45
parser.formatter.help_position = width
parser.formatter.max_help_position = width
parser.add_option('-a','--agents', action='store_true', dest='flag_agents', default=False,
help='include agents')
parser.add_option('-d','--debug', action='store_true', dest='flag_debug', default=False,
help='display debugging messages')
parser.add_option('-e','--enumerate', action='store_true', dest='flag_enumerate', default=False,
help='display each individual daemon status')
parser.add_option('-l','--log-format', action='store_true', dest='flag_log_format', default=False,
help='display in log format')
parser.add_option('-t','--target', action='store', dest='target', default=default_host+':'+default_port,
help='<host>:<port> with default of '+default_host+':'+default_port)
parser.add_option('-v','--version', action='store_true', dest='flag_version', default=False,
help='display version of this script')
(options, args) = parser.parse_args()
if(options.flag_version):
info('version='+version)
exit(1,msg=False)
validate_target()
# fetch current daemons state
def fetch_state_current():
global options
import urllib2
try:
opener = urllib2.build_opener()
if(options.flag_agents):
opener.addheaders.append(('Cookie', 'DUCCagents=show'))
response = opener.open(options.ducc_url_servlet)
options.ducc_raw_data = response.read()
trace(options.ducc_raw_data)
except Exception,e:
error('unable to fetch data from '+options.ducc_url_servlet)
exception(e)
exit(1)
# filter non-head daemons
def filter():
global options
global head_daemons
if(not options.flag_agents):
daemons = options.daemons
options.daemons = {}
for key in daemons:
if(key in head_daemons):
options.daemons[key] = daemons[key]
else:
debug('delete '+key)
# transform raw data
def transform():
global options
global head_daemons
try:
parser = DuccHtmlParser()
parser.feed(options.ducc_raw_data)
options.daemons = parser.get_daemons()
options.daemons_head = {}
options.daemons_agent = {}
for key in options.daemons:
value = options.daemons[key]
if(key in head_daemons):
options.daemons_head[key] = value
else:
options.daemons_agent[key] = value
debug(str(options.daemons))
filter()
except Exception,e:
error('unable to transform data from '+options.ducc_url_servlet)
exception(e)
exit(1)
# summarize
def summarize():
global options
global head_daemons
options.head_up = 0
options.head_down = 0
options.agent_up = 0
options.agent_down = 0
for key in options.daemons_head:
value = options.daemons_head[key]
if(value == 'up'):
options.head_up = options.head_up + 1
elif(value == 'up, pending JD allocation'):
options.head_up = options.head_up + 1
else:
options.head_down = options.head_down + 1
for key in options.daemons_agent:
value = options.daemons_agent[key]
if(value == 'up'):
options.agent_up = options.agent_up + 1
else:
options.agent_down = options.agent_down + 1
# display results
def display():
global options
global newline
summarize();
text0 = options.target
text1 = 'head: '+'up='+str(options.head_up)+' '+'down='+str(options.head_down)
text2 = 'agent: '+'up='+str(options.agent_up)+' '+'down='+str(options.agent_down)
if(options.flag_agents):
text = text0+' '+text1+' '+text2
else:
text = text0+' '+text1
output = text
info(output)
if(options.flag_enumerate):
for key in sorted(options.daemons):
output = key+'='+options.daemons[key]
info(output)
def init():
global default_host
global default_port
DUCC_HOME = find_ducc_home()
#print DUCC_HOME
propsfile = DUCC_HOME+'/resources/ducc.properties'
ducc_properties = Properties()
ducc_properties.load(propsfile)
_head = ducc_properties.get('ducc.head')
#print _head
if _head != None:
default_host = _head
_port = ducc_properties.get('ducc.ws.port')
#print _port
if _port != None:
default_port = _port
# report current ducc daemons status
def main(argv):
init()
parse_cmdline()
fetch_state_current()
transform()
display()
close()
if __name__ == '__main__':
main(sys.argv[1:])