mirror of
https://github.com/frappe/gunicorn.git
synced 2026-01-14 11:09:11 +08:00
Merge pull request #2384 from larribas/2066-statsd-socket
Allow reporting StatsD metrics over UDS sockets
This commit is contained in:
commit
4a1c402e2c
@ -420,7 +420,12 @@ environment variable ``PYTHONUNBUFFERED`` .
|
||||
|
||||
**Default:** ``None``
|
||||
|
||||
``host:port`` of the statsd server to log to.
|
||||
The address of the StatsD server to log to.
|
||||
|
||||
Address is a string of the form:
|
||||
|
||||
* ``unix://PATH`` : for a unix domain socket.
|
||||
* ``HOST:PORT`` : for a network address
|
||||
|
||||
.. versionadded:: 19.1
|
||||
|
||||
|
||||
@ -514,15 +514,25 @@ def validate_chdir(val):
|
||||
return path
|
||||
|
||||
|
||||
def validate_hostport(val):
|
||||
def validate_statsd_address(val):
|
||||
val = validate_string(val)
|
||||
if val is None:
|
||||
return None
|
||||
elements = val.split(":")
|
||||
if len(elements) == 2:
|
||||
return (elements[0], int(elements[1]))
|
||||
else:
|
||||
raise TypeError("Value must consist of: hostname:port")
|
||||
|
||||
# As of major release 20, util.parse_address would recognize unix:PORT
|
||||
# as a UDS address, breaking backwards compatibility. We defend against
|
||||
# that regression here (this is also unit-tested).
|
||||
# Feel free to remove in the next major release.
|
||||
unix_hostname_regression = re.match(r'^unix:(\d+)$', val)
|
||||
if unix_hostname_regression:
|
||||
return ('unix', int(unix_hostname_regression.group(1)))
|
||||
|
||||
try:
|
||||
address = util.parse_address(val, default_port='8125')
|
||||
except RuntimeError:
|
||||
raise TypeError("Value must be one of ('host:port', 'unix://PATH')")
|
||||
|
||||
return address
|
||||
|
||||
|
||||
def validate_reload_engine(val):
|
||||
@ -1630,9 +1640,14 @@ class StatsdHost(Setting):
|
||||
cli = ["--statsd-host"]
|
||||
meta = "STATSD_ADDR"
|
||||
default = None
|
||||
validator = validate_hostport
|
||||
validator = validate_statsd_address
|
||||
desc = """\
|
||||
``host:port`` of the statsd server to log to.
|
||||
The address of the StatsD server to log to.
|
||||
|
||||
Address is a string of the form:
|
||||
|
||||
* ``unix://PATH`` : for a unix domain socket.
|
||||
* ``HOST:PORT`` : for a network address
|
||||
|
||||
.. versionadded:: 19.1
|
||||
"""
|
||||
|
||||
@ -24,14 +24,17 @@ class Statsd(Logger):
|
||||
"""statsD-based instrumentation, that passes as a logger
|
||||
"""
|
||||
def __init__(self, cfg):
|
||||
"""host, port: statsD server
|
||||
"""
|
||||
Logger.__init__(self, cfg)
|
||||
self.prefix = sub(r"^(.+[^.]+)\.*$", "\\g<1>.", cfg.statsd_prefix)
|
||||
|
||||
if isinstance(cfg.statsd_host, str):
|
||||
address_family = socket.AF_UNIX
|
||||
else:
|
||||
address_family = socket.AF_INET
|
||||
|
||||
try:
|
||||
host, port = cfg.statsd_host
|
||||
self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
self.sock.connect((host, int(port)))
|
||||
self.sock = socket.socket(address_family, socket.SOCK_DGRAM)
|
||||
self.sock.connect(cfg.statsd_host)
|
||||
except Exception:
|
||||
self.sock = None
|
||||
|
||||
|
||||
@ -318,6 +318,30 @@ def test_nworkers_changed():
|
||||
assert c.nworkers_changed(1, 2, 3) == 3
|
||||
|
||||
|
||||
def test_statsd_host():
|
||||
c = config.Config()
|
||||
assert c.statsd_host is None
|
||||
c.set("statsd_host", "localhost")
|
||||
assert c.statsd_host == ("localhost", 8125)
|
||||
c.set("statsd_host", "statsd:7777")
|
||||
assert c.statsd_host == ("statsd", 7777)
|
||||
c.set("statsd_host", "unix:///path/to.sock")
|
||||
assert c.statsd_host == "/path/to.sock"
|
||||
pytest.raises(TypeError, c.set, "statsd_host", 666)
|
||||
pytest.raises(TypeError, c.set, "statsd_host", "host:string")
|
||||
|
||||
|
||||
def test_statsd_host_with_unix_as_hostname():
|
||||
# This is a regression test for major release 20. After this release
|
||||
# we should consider modifying the behavior of util.parse_address to
|
||||
# simplify gunicorn's code
|
||||
c = config.Config()
|
||||
c.set("statsd_host", "unix:7777")
|
||||
assert c.statsd_host == ("unix", 7777)
|
||||
c.set("statsd_host", "unix://some.socket")
|
||||
assert c.statsd_host == "some.socket"
|
||||
|
||||
|
||||
def test_statsd_changes_logger():
|
||||
c = config.Config()
|
||||
assert c.logger_class == glogging.Logger
|
||||
|
||||
@ -59,6 +59,18 @@ def test_statsd_fail():
|
||||
logger.exception("No impact on logging")
|
||||
|
||||
|
||||
def test_statsd_host_initialization():
|
||||
c = Config()
|
||||
c.set('statsd_host', 'unix:test.sock')
|
||||
logger = Statsd(c)
|
||||
logger.info("Can be initialized and used with a UDS socket")
|
||||
|
||||
# Can be initialized and used with a UDP address
|
||||
c.set('statsd_host', 'host:8080')
|
||||
logger = Statsd(c)
|
||||
logger.info("Can be initialized and used with a UDP socket")
|
||||
|
||||
|
||||
def test_dogstatsd_tags():
|
||||
c = Config()
|
||||
tags = 'yucatan,libertine:rhubarb'
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user