如何在Python中通过循环为不同NE生成独立日志文件
问题描述
编写Python脚本时,使用paramiko建立SSH连接,在不同NE(网络设备)上执行命令并接收返回结果,希望为每个NE生成独立的日志文件。当前代码在写入单个日志文件时正常,但无法实现每个NE对应独立日志,附上相关代码求实现方法。
原代码:
def main(self): global logger with open(self.hostfile, 'r') as ip: ip_list = ip.read().splitlines() for host in ip_list: filename = "connection_debug-{0}.log".format(host) print('filename is:', filename) logging.basicConfig(filename=filename, format='%(asctime)s %(message)s', filemode='w') logger = logging.getLogger() logger.setLevel(logging.DEBUG) def send_to_ne(self, command, prompt): channel.send('%s \n' % command) while not channel.recv_ready(): time.sleep(2) #self.get_channel_ready() global response response = " " while not response.endswith(prompt): received_result = channel.recv(9999) logger.debug(received_result.decode()) #self.logging_func(received_result, host) received_result = str(received_result)
问题原因及解决方法
核心问题
logging.basicConfig()仅在第一次调用时生效,后续调用不会重新配置日志;同时使用全局logger会导致所有NE共用同一个日志实例,无法区分写入不同文件。
解决步骤
- 为每个NE创建独立Logger实例:以主机名作为Logger的唯一标识,避免全局变量导致的实例复用问题。
- 用FileHandler替代basicConfig:为每个Logger单独配置日志文件,摆脱
basicConfig的全局限制。 - 传递Logger到业务方法:将对应主机的Logger作为参数传入
send_to_ne,确保日志写入正确文件。
修改后的代码示例
import logging import time import paramiko class NEConnector: def __init__(self, hostfile): self.hostfile = hostfile def main(self): with open(self.hostfile, 'r') as ip: ip_list = ip.read().splitlines() for host in ip_list: # 为当前主机创建专属Logger logger = logging.getLogger(host) logger.setLevel(logging.DEBUG) # 避免重复添加Handler(多次运行main时生效) if not logger.handlers: filename = f"connection_debug-{host}.log" # 配置文件处理器和日志格式 file_handler = logging.FileHandler(filename, mode='w') formatter = logging.Formatter('%(asctime)s %(message)s') file_handler.setFormatter(formatter) logger.addHandler(file_handler) # 建立SSH连接(需替换为实际的认证信息) ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(host, username='your_username', password='your_password') channel = ssh.invoke_shell() # 传入当前主机的Logger执行命令 self.send_to_ne(channel, "show version", "#", logger) # 关闭连接 ssh.close() def send_to_ne(self, channel, command, prompt, logger): channel.send(f'{command}\n') while not channel.recv_ready(): time.sleep(2) response = "" while not response.endswith(prompt): received_result = channel.recv(9999) decoded_result = received_result.decode() logger.debug(decoded_result) response += decoded_result # 示例调用 if __name__ == "__main__": connector = NEConnector("hosts.txt") connector.main()
关键说明
- 独立Logger实例:通过
logging.getLogger(host)创建以主机名为标识的Logger,每个主机的日志实例完全独立。 - FileHandler配置:为每个Logger单独绑定文件处理器,精准控制日志输出路径。
- 参数传递Logger:确保
send_to_ne方法使用的是当前主机对应的Logger,避免日志串流。 - 防重复Handler:通过
if not logger.handlers判断,防止多次运行时重复添加处理器导致日志重复写入。
内容的提问来源于stack exchange,提问作者HSHEKHAR
相关产品推荐
相关产品推荐

