gpt4 book ai didi

Python SysLogHandler 通过 TCP : handling connection loss

转载 作者:太空狗 更新时间:2023-10-29 20:28:14 26 4
gpt4 key购买 nike

我有一个进程使用 logging.SyslogHandler 通过 TCP 将日志发送到系统日志服务器。不幸的是,如果系统日志服务器由于某种原因重新启动,进程将停止发送日志并且无法重新建立连接。

我想知道是否有人知道克服这种行为并强制 logging.SyslogHandler 重新建立连接的方法。

使用处理程序的代码类似于:

import logging
import logging.handlers
import logging.config

logging.config.fileConfig('logging.cfg')
logging.debug("debug log message")

logging.cfg:

[loggers]
keys=root,remote

[handlers]
keys=local,remote

[logger_remote]
qualname=remote
level=INFO
handlers=remote

[logger_root]
qualname=root
level=DEBUG
handlers=local

[handler_local]
class=handlers.StreamHandler
level=DEBUG
formatter=local
args=(sys.stdout,)

[handler_remote]
class=handlers.SysLogHandler
level=DEBUG
formatter=remote
args=(('localhost', 514), handlers.SysLogHandler.LOG_USER, 1)

[formatters]
keys=local,remote

[formatter_local]
format=%(module)s %(levelname)s %(message)s

[formatter_remote]
format=%(asctime)s %(message)s

系统日志服务器重启后我不断收到的错误是:

Traceback (most recent call last):
File "/usr/local/lib/python2.7/logging/handlers.py", line 866, in emit
self.socket.sendall(msg)
File "/usr/local/lib/python2.7/socket.py", line 228, in meth
return getattr(self._sock,name)(*args)
error: [Errno 32] Broken pipe

如果有任何见解,我将不胜感激。谢谢!

最佳答案

我遇到了同样的问题。我必须编写一个自定义处理程序来处理损坏的管道异常并重新创建套接字。

class ReconnectingSysLogHandler(logging.handlers.SysLogHandler):                
"""Syslog handler that reconnects if the socket closes

If we're writing to syslog with TCP and syslog restarts, the old TCP socket
will no longer be writeable and we'll get a socket.error of type 32. When
than happens, use the default error handling, but also try to reconnect to
the same host/port used before. Also make 1 attempt to re-send the
message.
"""
def __init__(self, *args, **kwargs):
super(ReconnectingSysLogHandler, self).__init__(*args, **kwargs)
self._is_retry = False

def _reconnect(self):
"""Make a new socket that is the same as the old one"""
# close the existing socket before getting a new one to the same host/port
if self.socket:
self.socket.close()

# cut/pasted from logging.handlers.SysLogHandler
if self.unixsocket:
self._connect_unixsocket(self.address)
else:
self.socket = socket.socket(socket.AF_INET, self.socktype)
if self.socktype == socket.SOCK_STREAM:
self.socket.connect(self.address)

def handleError(self, record):
# use the default error handling (writes an error message to stderr)
super(ReconnectingSysLogHandler, self).handleError(record)

# If we get an error within a retry, just return. We don't want an
# infinite, recursive loop telling us something is broken.
# This leaves the socket broken.
if self._is_retry:
return

# Set the retry flag and begin deciding if this is a closed socket, and
# trying to reconnect.
self._is_retry = True
try:
__, exception, __ = sys.exc_info()
# If the error is a broken pipe exception (32), get a new socket.
if isinstance(exception, socket.error) and exception.errno == 32:
try:
self._reconnect()
except:
# If reconnecting fails, give up.
pass
else:
# Make an effort to rescue the recod.
self.emit(record)
finally:
self._is_retry = False

关于Python SysLogHandler 通过 TCP : handling connection loss,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40091456/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com