fix: reconfigure logging to syslog after daemonize() instead of no-op basicConfig
After daemonize() redirects stderr to /dev/null, the existing StreamHandler writes to /dev/null. logging.basicConfig() is a no-op when handlers are already configured, so log messages are silently lost. Replace the daemon block to: 1. Call daemonize() first 2. Explicitly remove existing handlers (pointing to /dev/null) 3. Add SysLogHandler pointing to /dev/log with fallback to UDP localhost:514 4. Log startup message to the new syslog handler Removes redundant syslog.openlog() call which is no longer needed. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+37
-9
@@ -586,6 +586,41 @@ def daemonize(
|
|||||||
os.dup2(se.fileno(), sys.stderr.fileno())
|
os.dup2(se.fileno(), sys.stderr.fileno())
|
||||||
|
|
||||||
|
|
||||||
|
def _reconfigure_logging_for_daemon(log_level: int) -> None:
|
||||||
|
"""Replace StreamHandlers (now writing to /dev/null) with a SysLogHandler."""
|
||||||
|
from logging.handlers import SysLogHandler
|
||||||
|
|
||||||
|
root = logging.getLogger()
|
||||||
|
for handler in root.handlers[:]:
|
||||||
|
root.removeHandler(handler)
|
||||||
|
handler.close()
|
||||||
|
|
||||||
|
try:
|
||||||
|
syslog_handler = SysLogHandler(
|
||||||
|
address="/dev/log",
|
||||||
|
facility=SysLogHandler.LOG_DAEMON,
|
||||||
|
)
|
||||||
|
except OSError:
|
||||||
|
syslog_handler = SysLogHandler(
|
||||||
|
address=("localhost", 514),
|
||||||
|
facility=SysLogHandler.LOG_DAEMON,
|
||||||
|
)
|
||||||
|
# Attach the fallback first so the warning reaches syslog
|
||||||
|
syslog_handler.setFormatter(
|
||||||
|
logging.Formatter("hbc[%(process)d]: %(name)s %(levelname)s: %(message)s")
|
||||||
|
)
|
||||||
|
root.addHandler(syslog_handler)
|
||||||
|
root.setLevel(log_level)
|
||||||
|
logging.warning("/dev/log not found, using syslog UDP localhost:514")
|
||||||
|
return
|
||||||
|
|
||||||
|
syslog_handler.setFormatter(
|
||||||
|
logging.Formatter("hbc[%(process)d]: %(name)s %(levelname)s: %(message)s")
|
||||||
|
)
|
||||||
|
root.addHandler(syslog_handler)
|
||||||
|
root.setLevel(log_level)
|
||||||
|
|
||||||
|
|
||||||
def build_parser():
|
def build_parser():
|
||||||
"""Build argument parser."""
|
"""Build argument parser."""
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
@@ -663,16 +698,9 @@ def main(argv=None):
|
|||||||
# Daemonize if requested
|
# Daemonize if requested
|
||||||
if args.daemon:
|
if args.daemon:
|
||||||
print("Daemonizing...")
|
print("Daemonizing...")
|
||||||
import syslog
|
|
||||||
syslog.openlog("hbc", syslog.LOG_PID, syslog.LOG_DAEMON)
|
|
||||||
syslog.syslog(syslog.LOG_INFO, f"Starting heartbeat to {', '.join(args.hosts)}")
|
|
||||||
daemonize()
|
daemonize()
|
||||||
|
_reconfigure_logging_for_daemon(log_level)
|
||||||
# Reconfigure logging for syslog
|
logging.info(f"hbc starting, sending heartbeat to {', '.join(args.hosts)}")
|
||||||
logging.basicConfig(
|
|
||||||
level=log_level,
|
|
||||||
format="hbc[%(process)d]: %(name)s %(levelname)s: %(message)s"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Run async main
|
# Run async main
|
||||||
try:
|
try:
|
||||||
|
|||||||
Reference in New Issue
Block a user