mirror of
https://github.com/frappe/gunicorn.git
synced 2026-01-14 11:09:11 +08:00
add systemd sd_notify support (#1897)
* add systemd sd_notify support roughly based on sd_notify() from systemd and https://github.com/bb4242/sdnotify only implements `READY=1` and `STATUS=Gunicorn arbiter booted` of the protocol in the arbiter. in the future, reloads can be notified, and possibly also other statuses. see https://www.freedesktop.org/software/systemd/man/sd_notify.html for more info sd_notify() is a noop when not run in a systemd service (i.e NOTIFY_SOCKET environment variable is not set)
This commit is contained in:
parent
ad1afe7b79
commit
9184ae8898
@ -227,7 +227,7 @@ unix socket:
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
PIDFile=/run/gunicorn/pid
|
||||
Type=notify
|
||||
User=someuser
|
||||
Group=someuser
|
||||
RuntimeDirectory=gunicorn
|
||||
|
||||
@ -158,6 +158,7 @@ class Arbiter(object):
|
||||
self.log.debug("Arbiter booted")
|
||||
self.log.info("Listening at: %s (%s)", listeners_str, self.pid)
|
||||
self.log.info("Using worker: %s", self.cfg.worker_class_str)
|
||||
systemd.sd_notify("READY=1\nSTATUS=Gunicorn arbiter booted", self.log)
|
||||
|
||||
# check worker class requirements
|
||||
if hasattr(self.worker_class, "check_config"):
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
# See the NOTICE for more information.
|
||||
|
||||
import os
|
||||
import socket
|
||||
|
||||
SD_LISTEN_FDS_START = 3
|
||||
|
||||
@ -43,3 +44,34 @@ def listen_fds(unset_environment=True):
|
||||
os.environ.pop('LISTEN_FDS', None)
|
||||
|
||||
return fds
|
||||
|
||||
|
||||
def sd_notify(state, logger, unset_environment=False):
|
||||
"""Send a notification to systemd. state is a string; see
|
||||
the man page of sd_notify (http://www.freedesktop.org/software/systemd/man/sd_notify.html)
|
||||
for a description of the allowable values.
|
||||
|
||||
If the unset_environment parameter is True, sd_notify() will unset
|
||||
the $NOTIFY_SOCKET environment variable before returning (regardless of
|
||||
whether the function call itself succeeded or not). Further calls to
|
||||
sd_notify() will then fail, but the variable is no longer inherited by
|
||||
child processes.
|
||||
"""
|
||||
|
||||
|
||||
addr = os.environ.get('NOTIFY_SOCKET')
|
||||
if addr is None:
|
||||
# not run in a service, just a noop
|
||||
return
|
||||
try:
|
||||
sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM | socket.SOCK_CLOEXEC)
|
||||
if addr[0] == '@':
|
||||
addr = '\0' + addr[1:]
|
||||
sock.connect(addr)
|
||||
sock.sendall(state.encode('utf-8'))
|
||||
except:
|
||||
logger.debug("Exception while invoking sd_notify()", exc_info=True)
|
||||
finally:
|
||||
if unset_environment:
|
||||
os.environ.pop('NOTIFY_SOCKET')
|
||||
sock.close()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user