| #!/usr/bin/env python | 
 | # | 
 | # Copyright (c) 2006- Facebook | 
 | # Distributed under the Thrift Software License | 
 | # | 
 | # See accompanying file LICENSE or visit the Thrift site at: | 
 | # http://developers.facebook.com/thrift/ | 
 |  | 
 | import sys, os | 
 | from optparse import OptionParser | 
 |  | 
 | from thrift.Thrift import * | 
 |  | 
 | from thrift.transport import TSocket | 
 | from thrift.transport import TTransport | 
 | from thrift.protocol import TBinaryProtocol | 
 |  | 
 | from fb303 import * | 
 | from fb303.ttypes import * | 
 |  | 
 | def service_ctrl( | 
 |                  command, | 
 |                  port, | 
 |                  trans_factory = None, | 
 |                  prot_factory = None): | 
 |     """ | 
 |     service_ctrl is a generic function to execute standard fb303 functions | 
 |  | 
 |     @param command: one of stop, start, reload, status, counters, name, alive | 
 |     @param port: service's port | 
 |     @param trans_factory: TTransportFactory to use for obtaining a TTransport. Default is | 
 |                           TBufferedTransportFactory | 
 |     @param prot_factory: TProtocolFactory to use for obtaining a TProtocol. Default is | 
 |                          TBinaryProtocolFactory | 
 |     """ | 
 |  | 
 |     # Only root should be able to run these scripts, although we could relax this for some of the operations. | 
 |     if os.getuid() != 0: | 
 |         print "requires root." | 
 |         return 4 | 
 |  | 
 |     if command in ["status"]: | 
 |         try: | 
 |             status = fb303_wrapper('status', port, trans_factory, prot_factory) | 
 |             status_details = fb303_wrapper('get_status_details', port, trans_factory, prot_factory) | 
 |  | 
 |             msg = fb_status_string(status) | 
 |             if (len(status_details)): | 
 |                 msg += " - %s" % status_details | 
 |             print msg | 
 |  | 
 |             if (status == fb_status.ALIVE): | 
 |                 return 2 | 
 |             else: | 
 |                 return 3 | 
 |         except: | 
 |             print "Failed to get status" | 
 |             return 3 | 
 |  | 
 |     # async commands | 
 |     if command in ["stop","reload"]: | 
 |         try: | 
 |             fb303_wrapper(command, port, trans_factory, prot_factory) | 
 |             return 0 | 
 |         except: | 
 |             print "failed to tell the service to ", command | 
 |             return 3 | 
 |  | 
 |     # scalar commands | 
 |     if command in ["version","alive","name"]: | 
 |         try: | 
 |             result = fb303_wrapper(command,  port, trans_factory, prot_factory) | 
 |             print result | 
 |             return 0 | 
 |         except: | 
 |             print "failed to get ",command | 
 |             return 3 | 
 |  | 
 |     # counters | 
 |     if command in ["counters"]: | 
 |         try: | 
 |             counters = fb303_wrapper('counters',  port, trans_factory, prot_factory) | 
 |             for counter in counters: | 
 |                 print "%s: %d" % (counter, counters[counter]) | 
 |             return 0 | 
 |         except: | 
 |             print "failed to get counters" | 
 |             return 3 | 
 |  | 
 |     return 0; | 
 |  | 
 |  | 
 | def fb303_wrapper(command, port, trans_factory = None, prot_factory = None): | 
 |     sock = TSocket.TSocket('localhost', port) | 
 |  | 
 |     # use input transport factory if provided | 
 |     if (trans_factory is None): | 
 |         trans = TTransport.TBufferedTransport(sock) | 
 |     else: | 
 |         trans = trans_factory.getTransport(sock) | 
 |  | 
 |     # use input protocol factory if provided | 
 |     if (prot_factory is None): | 
 |         prot = TBinaryProtocol.TBinaryProtocol(trans) | 
 |     else: | 
 |         prot = prot_factory.getProtocol(trans) | 
 |  | 
 |     # initialize client and open transport | 
 |     fb303_client = FacebookService.Client(prot, prot) | 
 |     trans.open() | 
 |  | 
 |     if (command == 'reload'): | 
 |         fb303_client.reinitialize() | 
 |  | 
 |     elif (command == 'stop'): | 
 |         fb303_client.shutdown() | 
 |  | 
 |     elif (command == 'status'): | 
 |         return fb303_client.getStatus() | 
 |  | 
 |     elif (command == 'version'): | 
 |         return fb303_client.getVersion() | 
 |  | 
 |     elif (command == 'get_status_details'): | 
 |         return fb303_client.getStatusDetails() | 
 |  | 
 |     elif (command == 'counters'): | 
 |         return fb303_client.getCounters() | 
 |  | 
 |     elif (command == 'name'): | 
 |         return fb303_client.getName() | 
 |  | 
 |     elif (command == 'alive'): | 
 |         return fb303_client.aliveSince() | 
 |  | 
 |     trans.close() | 
 |  | 
 |  | 
 | def fb_status_string(status_enum): | 
 |     if (status_enum == fb_status.DEAD): | 
 |         return "DEAD" | 
 |     if (status_enum == fb_status.STARTING): | 
 |         return "STARTING" | 
 |     if (status_enum == fb_status.ALIVE): | 
 |         return "ALIVE" | 
 |     if (status_enum == fb_status.STOPPING): | 
 |         return "STOPPING" | 
 |     if (status_enum == fb_status.STOPPED): | 
 |         return "STOPPED" | 
 |     if (status_enum == fb_status.WARNING): | 
 |         return "WARNING" | 
 |  | 
 |  | 
 | def main(port, command): | 
 |     status = service_ctrl(options.command, options.port) | 
 |     sys.exit(status) | 
 |  | 
 |  | 
 | # parse command line options | 
 | parser = OptionParser() | 
 | parser.add_option("-c", "--command", dest="command", help="execute this API", choices=["stop","counters","status","reload","version","name","alive"], | 
 |                   default="status") | 
 | parser.add_option("-p","--port",dest="port",help="the service's port", default=9082) | 
 |  | 
 | (options, args) = parser.parse_args() | 
 |  | 
 | main(options.port, options.command) |