Skip to content

Instantly share code, notes, and snippets.

@griggheo
Created December 7, 2010 21:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save griggheo/732462 to your computer and use it in GitHub Desktop.
Save griggheo/732462 to your computer and use it in GitHub Desktop.
import os, sys, time
from socket import gethostname
from optparse import OptionParser
from grizzled.os import daemonize
PYTHON_BINARY = "python"
PATH_TO_PYTHON_BINARY = "/usr/bin/%s" % PYTHON_BINARY
PATH_TO_PYTHON_BINARY = "/opt/tornado/myvenv/bin/python"
ROTATELOGS_CMD = "/usr/sbin/rotatelogs"
LOGDIR = "/opt/tornado/logs"
LOGDURATION = 86400
LOGGER = "/usr/bin/logger"
LOGGING_FACILITY = 'local0.info'
def main():
usage = "usage: %prog options"
parser = OptionParser(usage=usage)
parser.add_option("-a", "--action", dest="action",
help="action to be performed for the service (e.g. stop|start|restart)")
parser.add_option("-l", "--logger", dest="logger",
help="full path to log rotating program (e.g. /usr/sbin/rotatelogs)")
parser.add_option("-d", "--logdir", dest="logdir",
help="log directory (e.g. /opt/tornado/logs)")
parser.add_option("-s", "--service", dest="service",
help="name of service module (e.g. myservice.profile)")
parser.add_option("-p", "--port", dest="port",
help="port to run service on (e.g. 9000)")
parser.add_option("-n", "--number", dest="instance_number",
help="number of service instance (e.g. we need several notify instances)")
parser.add_option("-f", "--facility", dest="facility",
help="facility to send to syslog (e.g. local7.info; default is local0.info)")
parser.add_option("-x", "--xargs", dest="xargs",
help="extra arguments to be passed to the service (comma-separated list)")
(options, args) = parser.parse_args()
action = options.action
logger = options.logger
logdir = options.logdir
service = options.service
port = options.port
xargs = options.xargs
facility = options.facility
logger = options.logger
instance_number = options.instance_number
if not action or not service:
parser.print_help()
sys.exit(1)
if action and action not in ['start', 'stop', 'restart']:
parser.print_help()
sys.exit(1)
if not logdir:
logdir = LOGDIR
if not logger:
logger = LOGGER
if not facility:
facility = LOGGING_FACILITY
if not instance_number:
instance_number = 1
else:
instance_number = int(instance_number)
hostname = gethostname()
execve_args = [PYTHON_BINARY, "-m", service]
logfile = "%s_%s_log.%%Y-%%m-%%d" % (service, hostname)
pidfile = "%s/%s.pid" % (logdir, service)
if port:
logfile = "%s_%s_%s_log.%%Y-%%m-%%d" % (service, hostname, port)
pidfile = "%s/%s_%s.pid" % (logdir, service, port)
execve_args.append("--port=%s" % port)
else:
logfile = "%s_%s_%s_log.%%Y-%%m-%%d" % (service, hostname, instance_number)
pidfile = "%s/%s_%s.pid" % (logdir, service, instance_number)
if xargs:
xarglist = xargs.split(',')
for xarg in xarglist:
execve_args.append("--%s" % xarg)
logpipe ="%s -p %s" % (logger, facility)
execve_path = PATH_TO_PYTHON_BINARY
if action == 'start':
start(logpipe, execve_args, execve_path, pidfile)
elif action == 'stop':
stop(pidfile)
elif action == 'restart':
stop(pidfile)
start(logpipe, execve_args, execve_path, pidfile)
def start(logpipe, execve_args, execve_path, pidfile):
# open the pipe to ROTATELOGS
so = se = os.popen(logpipe, 'w')
# re-open stdout without buffering
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
# redirect stdout and stderr to the log file opened above
os.dup2(so.fileno(), sys.stdout.fileno())
os.dup2(se.fileno(), sys.stderr.fileno())
daemonize(no_close=True, pidfile=pidfile)
os.execv(execve_path, execve_args)
def stop(pidfile):
time.sleep(.1)
try:
pid = open(pidfile).readlines()[0]
pid = pid.rstrip()
cmd = "kill -9 %s" % pid
os.system(cmd)
os.unlink(pidfile)
except IOError, e:
print e
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment