Skip to content

Commit

Permalink
Merge pull request benoitc#1188 from bloodearnest/patch-1
Browse files Browse the repository at this point in the history
Allow configuring logger_class with statsd_host
  • Loading branch information
tilgovi committed Feb 19, 2016
2 parents 1b5b0f2 + 1359b3d commit 1d34629
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 10 deletions.
10 changes: 10 additions & 0 deletions docs/source/settings.rst
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
22 changes: 12 additions & 10 deletions gunicorn/config.py
Expand Up @@ -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()
Expand Down
26 changes: 26 additions & 0 deletions tests/test_config.py
Expand Up @@ -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():
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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

0 comments on commit 1d34629

Please sign in to comment.