Merge pull request #887 from jssjr/jssjr/statsd-prefix

Allow for statsd metrics to be prefixed
This commit is contained in:
Benoit Chesneau 2014-10-03 08:57:53 +02:00
commit 27c75d5d75
3 changed files with 53 additions and 4 deletions

View File

@ -1655,3 +1655,14 @@ class StatsdHost(Setting):
desc = """\
host:port of the statsd server to log to
"""
class StatsdPrefix(Setting):
name = "statsd_prefix"
section = "Logging"
cli = ["--statsd-prefix"]
meta = "STATSD_PREFIX"
default = ""
validator = validate_string
desc = """\
prefix to use when emitting statsd metrics (a trailing . is added, if not provided)
"""

View File

@ -7,6 +7,7 @@
import socket
import logging
from re import sub
from gunicorn.glogging import Logger
# Instrumentation constants
@ -25,6 +26,7 @@ class Statsd(Logger):
"""host, port: statsD server
"""
Logger.__init__(self, cfg)
self.prefix = sub(r"^(.+[^.]+)\.*$", "\g<1>.", cfg.statsd_prefix)
try:
host, port = cfg.statsd_host
self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
@ -98,27 +100,27 @@ class Statsd(Logger):
def gauge(self, name, value):
try:
if self.sock:
self.sock.send("{0}:{1}|g".format(name, value))
self.sock.send("{0}{1}:{2}|g".format(self.prefix, name, value))
except Exception:
pass
def increment(self, name, value, sampling_rate=1.0):
try:
if self.sock:
self.sock.send("{0}:{1}|c|@{2}".format(name, value, sampling_rate))
self.sock.send("{0}{1}:{2}|c|@{3}".format(self.prefix, name, value, sampling_rate))
except Exception:
pass
def decrement(self, name, value, sampling_rate=1.0):
try:
if self.sock:
self.sock.send("{0}:-{1}|c|@{2}".format(name, value, sampling_rate))
self.sock.send("{0){1}:-{2}|c|@{3}".format(self.prefix, name, value, sampling_rate))
except Exception:
pass
def histogram(self, name, value):
try:
if self.sock:
self.sock.send("{0}:{1}|ms".format(name, value))
self.sock.send("{0}{1}:{2}|ms".format(self.prefix, name, value))
except Exception:
pass

View File

@ -77,3 +77,39 @@ def test_instrument():
t.eq(logger.sock.msgs[0], "gunicorn.request.duration:7000.0|ms")
t.eq(logger.sock.msgs[1], "gunicorn.requests:1|c|@1.0")
t.eq(logger.sock.msgs[2], "gunicorn.request.status.200:1|c|@1.0")
def test_prefix():
c = Config()
c.set("statsd_prefix", "test.")
logger = Statsd(c)
logger.sock = MockSocket(False)
logger.info("Blah", extra={"mtype": "gauge", "metric": "gunicorn.test", "value": 666})
t.eq(logger.sock.msgs[0], "test.gunicorn.test:666|g")
def test_prefix_no_dot():
c = Config()
c.set("statsd_prefix", "test")
logger = Statsd(c)
logger.sock = MockSocket(False)
logger.info("Blah", extra={"mtype": "gauge", "metric": "gunicorn.test", "value": 666})
t.eq(logger.sock.msgs[0], "test.gunicorn.test:666|g")
def test_prefix_multiple_dots():
c = Config()
c.set("statsd_prefix", "test...")
logger = Statsd(c)
logger.sock = MockSocket(False)
logger.info("Blah", extra={"mtype": "gauge", "metric": "gunicorn.test", "value": 666})
t.eq(logger.sock.msgs[0], "test.gunicorn.test:666|g")
def test_prefix_nested():
c = Config()
c.set("statsd_prefix", "test.asdf.")
logger = Statsd(c)
logger.sock = MockSocket(False)
logger.info("Blah", extra={"mtype": "gauge", "metric": "gunicorn.test", "value": 666})
t.eq(logger.sock.msgs[0], "test.asdf.gunicorn.test:666|g")