#! /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=': 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 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:])