Skip to content

Commit

Permalink
Enable only on Linux platforms, and add config flag
Browse files Browse the repository at this point in the history
  • Loading branch information
raags committed Aug 14, 2024
1 parent aa73f3c commit c35802f
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 23 deletions.
13 changes: 13 additions & 0 deletions docs/source/settings.rst
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,19 @@ if not provided).

.. versionadded:: 19.2

.. _enable-backlog-metric:

``enable_backlog_metric``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

**Command line:** ``--enable-backlog-metric``

**Default:** ``False``

Enable socket backlog metric (only supported on Linux).

.. versionadded:: 23.1

Process Naming
--------------

Expand Down
19 changes: 9 additions & 10 deletions gunicorn/arbiter.py
Original file line number Diff line number Diff line change
Expand Up @@ -583,16 +583,15 @@ def manage_workers(self):
"value": active_worker_count,
"mtype": "gauge"})

backlog = sum(
sock.get_backlog() or 0
for sock in self.LISTENERS
)

if backlog:
self.log.debug("socket backlog: {0}".format(backlog),
extra={"metric": "gunicorn.backlog",
"value": backlog,
"mtype": "histogram"})
if self.cfg.enable_backlog_metric:
backlog = sum(sock.get_backlog() or 0
for sock in self.LISTENERS)

if backlog:
self.log.debug("socket backlog: {0}".format(backlog),
extra={"metric": "gunicorn.backlog",
"value": backlog,
"mtype": "histogram"})

def spawn_worker(self):
self.worker_age += 1
Expand Down
15 changes: 15 additions & 0 deletions gunicorn/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -1693,6 +1693,21 @@ class StatsdPrefix(Setting):
"""


class BacklogMetric(Setting):
name = "enable_backlog_metric"
section = "Logging"
cli = ["--enable-backlog-metric"]
meta = "BACKLOG_METRIC"
validator = validate_bool
default = False
action = "store_true"
desc = """\
Enable socket backlog metric (only supported on Linux).
.. versionadded:: 23.1
"""


class Procname(Setting):
name = "proc_name"
section = "Process Naming"
Expand Down
29 changes: 16 additions & 13 deletions gunicorn/sock.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,19 +93,22 @@ def set_options(self, sock, bound=False):
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
return super().set_options(sock, bound=bound)

def get_backlog(self):
if self.sock and PLATFORM == "linux":
# tcp_info struct from include/uapi/linux/tcp.h
fmt = 'B' * 8 + 'I' * 24
try:
tcp_info_struct = self.sock.getsockopt(socket.IPPROTO_TCP,
socket.TCP_INFO, 104)
# 12 is tcpi_unacked
return struct.unpack(fmt, tcp_info_struct)[12]
except AttributeError:
pass

return None
if PLATFORM == "linux":
def get_backlog(self):
if self.sock:
# tcp_info struct from include/uapi/linux/tcp.h
fmt = 'B' * 8 + 'I' * 24
try:
tcp_info_struct = self.sock.getsockopt(socket.IPPROTO_TCP,
socket.TCP_INFO, 104)
# 12 is tcpi_unacked
return struct.unpack(fmt, tcp_info_struct)[12]
except AttributeError:
pass
return 0
else:
def get_backlog(self):
return -1


class TCP6Socket(TCPSocket):
Expand Down

0 comments on commit c35802f

Please sign in to comment.