blob: bb2b62f09436556cce4edb2cb747c808c4382d09 [file] [log] [blame]
#!/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)