提交 06f955da authored 作者: 陈泽健's avatar 陈泽健

处理重连一直失败,会无限循环重试。建议加个重试计数器和退避时间增长策略;处理运行12小时后被远程主机主动断开连接问题,通过配置 SSH Client 的...

处理重连一直失败,会无限循环重试。建议加个重试计数器和退避时间增长策略;处理运行12小时后被远程主机主动断开连接问题,通过配置 SSH Client 的 keepalive 参数,让连接保持活跃,避免超时断开。
上级 9f38ad46
...@@ -2,4 +2,7 @@ ...@@ -2,4 +2,7 @@
- 补充预定系统对内服务日志的日志监测脚本,获取到错误日志信息会进行收集前后文,并调用钉钉消息发送至钉钉群中。 - 补充预定系统对内服务日志的日志监测脚本,获取到错误日志信息会进行收集前后文,并调用钉钉消息发送至钉钉群中。
- 调整日志监测模块的文件规范路径,补充相关日志打印。 - 调整日志监测模块的文件规范路径,补充相关日志打印。
- 处理日志监测错误异常日志的钉钉发送消息流程,增加预定系统对内外的日志监测,增加通过链接形式打开日志存储的文本数据,支持公网访问。 - 处理日志监测错误异常日志的钉钉发送消息流程,增加预定系统对内外的日志监测,增加通过链接形式打开日志存储的文本数据,支持公网访问。
- 补充对外服务的日志监测。 - 补充对外服务的日志监测。
\ No newline at end of file 2. 2025-06-06:
- 处理重连一直失败,会无限循环重试。建议加个重试计数器和退避时间增长策略;
- 处理运行12小时后被远程主机主动断开连接问题,通过配置 SSH Client 的 keepalive 参数,让连接保持活跃,避免超时断开。
\ No newline at end of file
...@@ -58,8 +58,19 @@ class LogMonitor: ...@@ -58,8 +58,19 @@ class LogMonitor:
private_key = paramiko.RSAKey.from_private_key_file(self.private_key_path, password=self.passphrase) private_key = paramiko.RSAKey.from_private_key_file(self.private_key_path, password=self.passphrase)
self.client = paramiko.SSHClient() self.client = paramiko.SSHClient()
self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
self.client.connect(self.host, username=self.username, pkey=private_key) self.client.connect(
self.host,
username=self.username,
pkey=private_key,
timeout=30,
banner_timeout=200,
auth_timeout=200
)
self.channel = self.client.invoke_shell() self.channel = self.client.invoke_shell()
self.channel.setblocking(0) # 设置为非阻塞模式
self.channel.transport.set_keepalive(30) # 每隔 30 秒发一次 keepalive 包
self.channel.send(f"tail -f {self.log_path}\n") self.channel.send(f"tail -f {self.log_path}\n")
logging.info(f"Connected to {self.host}, monitoring {self.log_path}") logging.info(f"Connected to {self.host}, monitoring {self.log_path}")
return True return True
...@@ -89,24 +100,25 @@ class LogMonitor: ...@@ -89,24 +100,25 @@ class LogMonitor:
logging.info(f"停止对日志 {self.log_path} 的监控.") logging.info(f"停止对日志 {self.log_path} 的监控.")
def _monitor_loop(self): def _monitor_loop(self):
try: retry_count = 0
while self.collecting: MAX_RETRY = 5
while self.collecting:
try:
if self.channel.recv_ready(): if self.channel.recv_ready():
output = self.channel.recv(1024).decode('utf-8', errors='ignore') ...
lines = output.strip().split('\n')
for line in lines:
self._process_line(line)
else: else:
time.sleep(self.check_interval) time.sleep(self.check_interval)
retry_count = 0 # 成功时重置重试次数
except (paramiko.SSHException, paramiko.socket.error, OSError) as e: except (paramiko.SSHException, paramiko.socket.error, OSError) as e:
logging.info(f"SSH 连接中断: {e}") logging.warning(f"SSH 断开,准备重连... 错误: {e}")
self.restart_monitoring() self.restart_monitoring()
except Exception as e: retry_count += 1
logging.info(f"监控过程中发生异常: {e}") if retry_count > MAX_RETRY:
self.restart_monitoring() logging.error("达到最大重试次数,停止监控")
self.stop_monitoring()
return
time.sleep(min(5 * retry_count, 60)) # 指数退避
def save_error_contexts_to_json(self): def save_error_contexts_to_json(self):
# 获取当前脚本所在目录 # 获取当前脚本所在目录
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论