add setproctitle support. -n allow to customize the name. by default

it's the arg passed to command line for wsgi app, module.settings for
djang and ini file path for paster
This commit is contained in:
benoitc 2010-02-22 16:29:35 +01:00
parent 6c12f313e3
commit 5afec8d726
5 changed files with 41 additions and 6 deletions

View File

@ -7,6 +7,7 @@ from __future__ import with_statement
import copy import copy
import errno import errno
import inspect
import logging import logging
import os import os
import select import select
@ -43,10 +44,11 @@ class Arbiter(object):
if name[:3] == "SIG" and name[3] != "_" if name[:3] == "SIG" and name[3] != "_"
) )
def __init__(self, address, num_workers, modname, **kwargs): def __init__(self, address, num_workers, app, **kwargs):
self.address = address self.address = address
self.num_workers = num_workers self.num_workers = num_workers
self.modname = modname self.app = app
self.timeout = 30 self.timeout = 30
self.reexec_pid = 0 self.reexec_pid = 0
self.debug = kwargs.get("debug", False) self.debug = kwargs.get("debug", False)
@ -55,6 +57,7 @@ class Arbiter(object):
self.conf = kwargs.get("config", {}) self.conf = kwargs.get("config", {})
self._pidfile = None self._pidfile = None
self.master_name = "Master" self.master_name = "Master"
self.app_name = self.conf['app_name']
# get current path, try to use PWD env first # get current path, try to use PWD env first
try: try:
@ -160,6 +163,7 @@ class Arbiter(object):
def run(self): def run(self):
""" main master loop. Launch to start the master""" """ main master loop. Launch to start the master"""
self.start() self.start()
util._setproctitle("master [%s]" % self.app_name)
self.manage_workers() self.manage_workers()
while True: while True:
try: try:
@ -355,7 +359,7 @@ class Arbiter(object):
if i in workers: if i in workers:
continue continue
worker = Worker(i, self.pid, self.LISTENER, self.modname, worker = Worker(i, self.pid, self.LISTENER, self.app,
self.timeout/2.0, self.conf) self.timeout/2.0, self.conf)
self.conf.before_fork(self, worker) self.conf.before_fork(self, worker)
pid = os.fork() pid = os.fork()
@ -366,6 +370,7 @@ class Arbiter(object):
# Process Child # Process Child
worker_pid = os.getpid() worker_pid = os.getpid()
try: try:
util._setproctitle("worker [%s]" % self.app_name)
self.log.debug("Worker %s booting" % worker_pid) self.log.debug("Worker %s booting" % worker_pid)
self.conf.after_fork(self, worker) self.conf.after_fork(self, worker)
worker.run() worker.run()

View File

@ -13,6 +13,7 @@ from gunicorn import util
class Config(object): class Config(object):
DEFAULTS = dict( DEFAULTS = dict(
app_name = os.getcwd(),
bind='127.0.0.1:8000', bind='127.0.0.1:8000',
daemon=False, daemon=False,
debug=False, debug=False,

View File

@ -42,6 +42,8 @@ def options():
help="Change worker user"), help="Change worker user"),
op.make_option('-g', '--group', dest="group", op.make_option('-g', '--group', dest="group",
help="Change worker group"), help="Change worker group"),
op.make_option('-n', '--name', dest='app_name',
help="Application name"),
op.make_option('--log-level', dest='loglevel', op.make_option('--log-level', dest='loglevel',
help='Log level below which to silence messages. [info]'), help='Log level below which to silence messages. [info]'),
op.make_option('--log-file', dest='logfile', op.make_option('--log-file', dest='logfile',
@ -141,6 +143,8 @@ def paste_server(app, global_conf=None, host="127.0.0.1", port=None,
if key == "debug": if key == "debug":
value = (value == "true") value = (value == "true")
options[key] = value options[key] = value
if not 'app_name' in options:
options['app_name'] = options['__file__']
conf = Config(options) conf = Config(options)
arbiter = Arbiter(conf.address, conf.workers, app, debug=conf["debug"], arbiter = Arbiter(conf.address, conf.workers, app, debug=conf["debug"],
@ -162,6 +166,9 @@ def run():
if len(args) != 1: if len(args) != 1:
parser.error("No application module specified.") parser.error("No application module specified.")
if not opts.app_name:
opts.app_name = args[0]
try: try:
return util.import_app(args[0]) return util.import_app(args[0])
except: except:
@ -202,7 +209,11 @@ def run_django():
# set environ # set environ
settings_name, ext = os.path.splitext(os.path.basename(settings_path)) settings_name, ext = os.path.splitext(os.path.basename(settings_path))
os.environ['DJANGO_SETTINGS_MODULE'] = '%s.%s' % (project_name, settings_name) settings_modname = '%s.%s' % (project_name, settings_name)
os.environ['DJANGO_SETTINGS_MODULE'] = settings_modname
if not opts.app_name:
opts.app_name = settings_modname
# django wsgi app # django wsgi app
return django.core.handlers.wsgi.WSGIHandler() return django.core.handlers.wsgi.WSGIHandler()
@ -259,6 +270,9 @@ def run_paster():
if not opts.debug: if not opts.debug:
opts.debug = (ctx.global_conf.get('debug') == "true") opts.debug = (ctx.global_conf.get('debug') == "true")
if not opts.app_name:
opts.app_name = ctx.global_conf.get('__file__')
app = loadapp(config_url, relative_to=relative_to) app = loadapp(config_url, relative_to=relative_to)
return app return app

View File

@ -17,7 +17,7 @@ from django.core.handlers.wsgi import WSGIHandler
from gunicorn.arbiter import Arbiter from gunicorn.arbiter import Arbiter
from gunicorn.config import Config from gunicorn.config import Config
from gunicorn.main import daemonize, UMASK, set_owner_process, configure_logging from gunicorn.main import daemonize, UMASK, configure_logging
from gunicorn.util import parse_address, to_bytestring from gunicorn.util import parse_address, to_bytestring
class Command(BaseCommand): class Command(BaseCommand):
@ -36,6 +36,8 @@ class Command(BaseCommand):
help="Change worker user"), help="Change worker user"),
make_option('-g', '--group', dest="group", make_option('-g', '--group', dest="group",
help="Change worker group"), help="Change worker group"),
make_option('-n', '--name', dest='app_name',
help="Application name"),
) )
help = "Starts a fully-functional Web server using gunicorn." help = "Starts a fully-functional Web server using gunicorn."
args = '[optional port number, or ipaddr:port or unix:/path/to/sockfile]' args = '[optional port number, or ipaddr:port or unix:/path/to/sockfile]'
@ -48,6 +50,9 @@ class Command(BaseCommand):
raise CommandError('Usage is runserver %s' % self.args) raise CommandError('Usage is runserver %s' % self.args)
options['bind'] = addrport or '127.0.0.1' options['bind'] = addrport or '127.0.0.1'
if not options.get('app_name'):
options['app_name'] =settings.SETTINGS_MODULE
conf = Config(options) conf = Config(options)
admin_media_path = options.get('admin_media_path', '') admin_media_path = options.get('admin_media_path', '')
@ -55,13 +60,15 @@ class Command(BaseCommand):
print "Validating models..." print "Validating models..."
self.validate(display_num_errors=True) self.validate(display_num_errors=True)
print "\nDjango version %s, using settings %r" % (django.get_version(), settings.SETTINGS_MODULE) print "\nDjango version %s, using settings %r" % (django.get_version(),
settings.SETTINGS_MODULE)
print "Development server is running at %s" % str(conf.address) print "Development server is running at %s" % str(conf.address)
print "Quit the server with %s." % quit_command print "Quit the server with %s." % quit_command
# django.core.management.base forces the locale to en-us. # django.core.management.base forces the locale to en-us.
translation.activate(settings.LANGUAGE_CODE) translation.activate(settings.LANGUAGE_CODE)
try: try:
handler = AdminMediaHandler(WSGIHandler(), admin_media_path) handler = AdminMediaHandler(WSGIHandler(), admin_media_path)
arbiter = Arbiter(conf.address, conf.workers, handler, arbiter = Arbiter(conf.address, conf.workers, handler,

View File

@ -30,6 +30,14 @@ monthname = [None,
'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
try:
from setproctitle import setproctitle
def _setproctitle(title):
setproctitle("gunicorn: %s" % title)
except ImportError:
def _setproctitle(title):
return
def set_owner_process(uid,gid): def set_owner_process(uid,gid):
""" set user and group of workers processes """ """ set user and group of workers processes """
if gid: if gid: