Netmiko 4.4.0无法捕获Juniper设备CLI命令时间戳问题
Netmiko 4.4.0 捕获Juniper MX命令时间戳问题
环境信息
- Netmiko版本:4.4.0
- Python版本:3.11
问题描述
用Netmiko登录Juniper MX路由器,想同时获取命令执行的时间戳和输出。登录后执行set cli timestamp开启时间戳功能,但后续调用send_command()只能拿到命令输出,时间戳被过滤掉了。
查看session_log发现,Juniper设备会先单独返回时间戳,再返回命令结果。旧版Netmiko 2.4.1能正常捕获时间戳,但必须使用4.4.0版本。
示例代码与输出
Python会话:
from netmiko import ConnectHandler conn = ConnectHandler(host=host , username=username, password=password, device_type='juniper_junos', conn_timeout=30, session_log='session.log') # 开启时间戳 conn.send_command('set cli timestamp') # 返回:'Nov 13 14:26:24\nCLI timestamp set to: %b %d %T\n' # 执行查询命令 conn.send_command('show version | match model') # 返回:'Model: mx480\n'
实际输出 vs 预期输出
- 实际输出:
Model: mx480\n - 预期输出:包含对应时间戳和命令结果,类似
Nov 13 14:26:30\nModel: mx480\n
session.log关键内容片段
{master} REDACTED@re0.NYCMNYZR1CW> set cli timestamp Nov 13 14:26:24 CLI timestamp set to: %b %d %T {master} REDACTED@re0.NYCMNYZR1CW> Nov 13 14:26:30 {master} REDACTED@re0.NYCMNYZR1CW> show version | match model Model: mx480 {master} REDACTED@re0.NYCMNYZR1CW>
解决方案
方法1:用send_command_timing替代send_command
send_command_timing基于时间等待捕获输出,不依赖提示符匹配,能拿到所有返回内容,包括单独发送的时间戳。调整代码如下:
from netmiko import ConnectHandler conn = ConnectHandler(host=host , username=username, password=password, device_type='juniper_junos', conn_timeout=30, session_log='session.log') conn.send_command('set cli timestamp') # 使用send_command_timing,delay_factor可根据网络情况调整 result = conn.send_command_timing('show version | match model', delay_factor=1.5) print(result) # 输出会包含时间戳和命令结果
方法2:自定义Juniper设备类,修改输出处理逻辑
Netmiko 4.x的Juniper默认逻辑会过滤提示符前的额外行,我们可以继承原设备类,调整process_output方法保留时间戳:
from netmiko.juniper.juniper_junos import JuniperJunosBase from netmiko import ConnectHandler class CustomJuniper(JuniperJunosBase): def process_output(self, output): cleaned_lines = [] prompt = self.base_prompt for line in output.splitlines(): stripped_line = line.strip() # 跳过空行和提示符行,保留时间戳和命令输出 if stripped_line and not stripped_line.endswith(prompt): cleaned_lines.append(line) return '\n'.join(cleaned_lines) + '\n' # 使用自定义设备类建立连接 conn = ConnectHandler( host=host, username=username, password=password, device_type='juniper_junos', conn_timeout=30, session_log='session.log', device_class=CustomJuniper ) conn.send_command('set cli timestamp') result = conn.send_command('show version | match model') print(result)
方法3:解析session_log文件提取信息
如果前两种方法不适用,可以在执行命令后读取session_log,通过正则匹配提取对应命令的时间戳和输出:
import re from netmiko import ConnectHandler def extract_timestamp_output(log_file, target_cmd): with open(log_file, 'r') as f: log_content = f.read() # 匹配命令前的时间戳和命令输出 regex_pattern = rf'(Nov \d+ \d+:\d+:\d+)\s+{{master}}\s+.+>\s+{re.escape(target_cmd)}\n(.+?)\n{{master}}' match_result = re.search(regex_pattern, log_content, re.DOTALL) if match_result: return f"{match_result.group(1)}\n{match_result.group(2).strip()}" return None # 执行命令 conn = ConnectHandler(host=host , username=username, password=password, device_type='juniper_junos', conn_timeout=30, session_log='session.log') conn.send_command('set cli timestamp') conn.send_command('show version | match model') # 提取结果 final_result = extract_timestamp_output('session.log', 'show version | match model') print(final_result)
内容的提问来源于stack exchange,提问作者programmer1010
相关产品推荐
相关产品推荐

