mirror of
https://github.com/frappe/gunicorn.git
synced 2026-01-14 11:09:11 +08:00
make the Logger pluggable. Allows people to use their own logger by
giving to gunicorn an entry point or a module path.
This commit is contained in:
parent
2375ca87fe
commit
824801d017
@ -14,7 +14,6 @@ import time
|
|||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
|
|
||||||
from gunicorn.glogging import Logger
|
|
||||||
from gunicorn.errors import HaltServer
|
from gunicorn.errors import HaltServer
|
||||||
from gunicorn.pidfile import Pidfile
|
from gunicorn.pidfile import Pidfile
|
||||||
from gunicorn.sock import create_socket
|
from gunicorn.sock import create_socket
|
||||||
@ -85,7 +84,7 @@ class Arbiter(object):
|
|||||||
def setup(self, app):
|
def setup(self, app):
|
||||||
self.app = app
|
self.app = app
|
||||||
self.cfg = app.cfg
|
self.cfg = app.cfg
|
||||||
self.log = Logger(app.cfg)
|
self.log = self.cfg.logger_class(app.cfg)
|
||||||
|
|
||||||
if 'GUNICORN_FD' in os.environ:
|
if 'GUNICORN_FD' in os.environ:
|
||||||
self.log.reopen_files()
|
self.log.reopen_files()
|
||||||
|
|||||||
@ -72,7 +72,7 @@ class Config(object):
|
|||||||
@property
|
@property
|
||||||
def worker_class(self):
|
def worker_class(self):
|
||||||
uri = self.settings['worker_class'].get()
|
uri = self.settings['worker_class'].get()
|
||||||
worker_class = util.load_worker_class(uri)
|
worker_class = util.load_class(uri)
|
||||||
if hasattr(worker_class, "setup"):
|
if hasattr(worker_class, "setup"):
|
||||||
worker_class.setup()
|
worker_class.setup()
|
||||||
return worker_class
|
return worker_class
|
||||||
@ -101,6 +101,17 @@ class Config(object):
|
|||||||
return pn
|
return pn
|
||||||
else:
|
else:
|
||||||
return self.settings['default_proc_name'].get()
|
return self.settings['default_proc_name'].get()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def logger_class(self):
|
||||||
|
uri = self.settings['logger_class'].get()
|
||||||
|
logger_class = util.load_class(uri, default="simple",
|
||||||
|
section="gunicorn.loggers")
|
||||||
|
|
||||||
|
if hasattr(logger_class, "install"):
|
||||||
|
logger_class.install()
|
||||||
|
return logger_class
|
||||||
|
|
||||||
|
|
||||||
class SettingMeta(type):
|
class SettingMeta(type):
|
||||||
def __new__(cls, name, bases, attrs):
|
def __new__(cls, name, bases, attrs):
|
||||||
@ -617,6 +628,25 @@ class Loglevel(Setting):
|
|||||||
* critical
|
* critical
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
class LoggerClass(Setting):
|
||||||
|
name = "logger_class"
|
||||||
|
section = "Logging"
|
||||||
|
cli = ["--logger-class"]
|
||||||
|
meta = "STRING"
|
||||||
|
validator = validate_string
|
||||||
|
default = "simple"
|
||||||
|
desc = """\
|
||||||
|
The logger you want to use to log events in gunicorn.
|
||||||
|
|
||||||
|
The default class (``gunicorn.glogging.Logger``) handle most of
|
||||||
|
normal usages in logging. It provides error and access logging.
|
||||||
|
|
||||||
|
You can provide your own worker by giving gunicorn a
|
||||||
|
python path to a subclass like gunicorn.glogging.Logger.
|
||||||
|
Alternatively the syntax can also load the Logger class
|
||||||
|
with ``egg:gunicorn#simple`
|
||||||
|
"""
|
||||||
|
|
||||||
class Procname(Setting):
|
class Procname(Setting):
|
||||||
name = "proc_name"
|
name = "proc_name"
|
||||||
section = "Process Naming"
|
section = "Process Naming"
|
||||||
|
|||||||
@ -64,7 +64,7 @@ except ImportError:
|
|||||||
def _setproctitle(title):
|
def _setproctitle(title):
|
||||||
return
|
return
|
||||||
|
|
||||||
def load_worker_class(uri):
|
def load_class(uri, default="sync", section="gunicorn.workers"):
|
||||||
if uri.startswith("egg:"):
|
if uri.startswith("egg:"):
|
||||||
# uses entry points
|
# uses entry points
|
||||||
entry_str = uri.split("egg:")[1]
|
entry_str = uri.split("egg:")[1]
|
||||||
@ -72,19 +72,20 @@ def load_worker_class(uri):
|
|||||||
dist, name = entry_str.rsplit("#",1)
|
dist, name = entry_str.rsplit("#",1)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
dist = entry_str
|
dist = entry_str
|
||||||
name = "sync"
|
name = default
|
||||||
|
|
||||||
return pkg_resources.load_entry_point(dist, "gunicorn.workers", name)
|
return pkg_resources.load_entry_point(dist, section, name)
|
||||||
else:
|
else:
|
||||||
components = uri.split('.')
|
components = uri.split('.')
|
||||||
if len(components) == 1:
|
if len(components) == 1:
|
||||||
try:
|
try:
|
||||||
if uri.startswith("#"):
|
if uri.startswith("#"):
|
||||||
uri = uri[1:]
|
uri = uri[1:]
|
||||||
|
|
||||||
return pkg_resources.load_entry_point("gunicorn",
|
return pkg_resources.load_entry_point("gunicorn",
|
||||||
"gunicorn.workers", uri)
|
section, uri)
|
||||||
except ImportError:
|
except ImportError:
|
||||||
raise RuntimeError("arbiter uri invalid or not found")
|
raise RuntimeError("class uri invalid or not found")
|
||||||
klass = components.pop(-1)
|
klass = components.pop(-1)
|
||||||
mod = __import__('.'.join(components))
|
mod = __import__('.'.join(components))
|
||||||
for comp in components[1:]:
|
for comp in components[1:]:
|
||||||
|
|||||||
3
setup.py
3
setup.py
@ -61,6 +61,9 @@ setup(
|
|||||||
gevent_pywsgi=gunicorn.workers.ggevent:GeventPyWSGIWorker
|
gevent_pywsgi=gunicorn.workers.ggevent:GeventPyWSGIWorker
|
||||||
tornado=gunicorn.workers.gtornado:TornadoWorker
|
tornado=gunicorn.workers.gtornado:TornadoWorker
|
||||||
|
|
||||||
|
[gunicorn.loggers]
|
||||||
|
simple=gunicorn.glogging:Logger
|
||||||
|
|
||||||
[paste.server_runner]
|
[paste.server_runner]
|
||||||
main=gunicorn.app.pasterapp:paste_server
|
main=gunicorn.app.pasterapp:paste_server
|
||||||
""",
|
""",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user