diff --git a/docs/source/settings.rst b/docs/source/settings.rst index 2a76aa1b79..133bda35e5 100644 --- a/docs/source/settings.rst +++ b/docs/source/settings.rst @@ -532,6 +532,10 @@ 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. +If you enable statsd support, then a special subclass +(``gunicorn.instrument.statsd.Statsd``) is used instead, which handles +sending the metrics to *statsd_host* + 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 @@ -611,6 +615,12 @@ statsd_host ``host:port`` of the statsd server to log to. +Note: enabling this switches the default *logger_class* to +``gunicorn.instrument.statsd.Statsd``. If you wish to use statsd with +a custom *logger_class*, you should make sure your class is API +compatible with ``gunicorn.instrument.statsd.Statsd``, or inherit from +it. + .. versionadded:: 19.1 statsd_prefix diff --git a/gunicorn/config.py b/gunicorn/config.py index 3b028e7f89..47bc09fcbc 100644 --- a/gunicorn/config.py +++ b/gunicorn/config.py @@ -144,16 +144,18 @@ def logger_class(self): uri = self.settings['logger_class'].get() if uri == "simple": # support the default - uri = "gunicorn.glogging.Logger" - - # if statsd is on, automagically switch to the statsd logger - if 'statsd_host' in self.settings and self.settings['statsd_host'].value is not None: - logger_class = util.load_class("gunicorn.instrument.statsd.Statsd", - section="gunicorn.loggers") - else: - logger_class = util.load_class(uri, - default="gunicorn.glogging.Logger", - section="gunicorn.loggers") + uri = LoggerClass.default + + # if default logger is in use, and statsd is on, automagically switch + # to the statsd logger + if uri == LoggerClass.default: + if 'statsd_host' in self.settings and self.settings['statsd_host'].value is not None: + uri = "gunicorn.instrument.statsd.Statsd" + + logger_class = util.load_class( + uri, + default="gunicorn.glogging.Logger", + section="gunicorn.loggers") if hasattr(logger_class, "install"): logger_class.install() diff --git a/tests/test_config.py b/tests/test_config.py index f235564ed5..9f9a2fe977 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -13,6 +13,8 @@ from gunicorn import config from gunicorn.app.base import Application from gunicorn.workers.sync import SyncWorker +from gunicorn import glogging +from gunicorn.instrument import statsd dirname = os.path.dirname(__file__) def cfg_module(): @@ -57,6 +59,9 @@ def test_property_access(): # Class was loaded assert c.worker_class == SyncWorker + # logger class was loaded + assert c.logger_class == glogging.Logger + # Workers defaults to 1 assert c.workers == 1 c.set("workers", 3) @@ -259,3 +264,24 @@ def nworkers_changed_3(server, new_value, old_value): c.set("nworkers_changed", nworkers_changed_3) assert c.nworkers_changed(1, 2, 3) == 3 + + +def test_statsd_changes_logger(): + c = config.Config() + assert c.logger_class == glogging.Logger + c.set('statsd_host', 'localhost:12345') + assert c.logger_class == statsd.Statsd + + +class MyLogger(glogging.Logger): + # dummy custom logger class for testing + pass + + +def test_always_use_configured_logger(): + c = config.Config() + c.set('logger_class', __name__ + '.MyLogger') + assert c.logger_class == MyLogger + c.set('statsd_host', 'localhost:12345') + # still uses custom logger over statsd + assert c.logger_class == MyLogger