You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python代码中调用Ansible 2.0 API时屏蔽playbook输出?

嘿,这个问题我熟!Ansible 2.0 API默认确实会把playbook的执行过程一股脑打出来,要屏蔽这些输出的话,有几个靠谱的办法,你可以根据情况选:

解决Python调用Ansible 2.0 API屏蔽执行过程输出的方法

方法1:自定义回调类并禁用默认输出

你已经用了自定义的ResultsCollector回调,但可能默认的输出回调还在偷偷生效。可以重载回调类的方法,只收集结果不打印,同时确保Ansible只加载你的自定义回调:

首先完善你的自定义回调类:

from ansible.plugins.callback import CallbackBase

class ResultsCollector(CallbackBase):
    def __init__(self, *args, **kwargs):
        super(ResultsCollector, self).__init__(*args, **kwargs)
        self.results = []

    # 重载所有可能产生输出的方法,只收集结果不打印
    def v2_runner_on_ok(self, result, **kwargs):
        self.results.append(result._result)
    
    def v2_runner_on_failed(self, result, **kwargs):
        self.results.append(result._result)
    
    def v2_runner_on_unreachable(self, result, **kwargs):
        self.results.append(result._result)
    
    # 其他如v2_playbook_on_start、v2_playbook_on_task_start等方法,留空或只收集数据即可

然后在run_playbook函数里,指定使用自定义回调并禁用默认输出:

from ansible.executor.playbook_executor import PlaybookExecutor
from ansible.utils.display import Display

def run_playbook(playbook, inventory, package, var_file_path, forks):
    callback = ResultsCollector()
    variable_manager = VariableManager()
    loader = DataLoader()
    inventory = Inventory(loader=loader, variable_manager=variable_manager, host_list=inventory)
    playbook_path = playbook
    
    if not os.path.exists(playbook_path):
        print "Playbook文件不存在!"
        return
    
    # 设置选项,把verbosity调到0减少输出
    options = Options(
        forks=forks,
        verbosity=0,
        connection='ssh'
    )
    
    pbex = PlaybookExecutor(
        playbooks=[playbook_path],
        inventory=inventory,
        variable_manager=variable_manager,
        loader=loader,
        options=options,
        passwords={}
    )
    
    # 替换默认的输出回调为自定义的
    pbex._tqm._stdout_callback = callback
    # 同时关闭Display类的输出
    Display().verbosity = 0
    
    result = pbex.run()
    return callback.results

方法2:临时重定向标准输出/错误

如果有些输出是Ansible底层直接打印到控制台的,没法通过回调控制,可以临时把stdout和stderr重定向到空设备:

import os
import sys

def run_playbook(playbook, inventory, package, var_file_path, forks):
    # 保存原来的输出流
    original_stdout = sys.stdout
    original_stderr = sys.stderr
    
    # 重定向到空设备(Linux/macOS用/dev/null,Windows替换为'nul')
    dev_null = open(os.devnull, 'w')
    sys.stdout = dev_null
    sys.stderr = dev_null
    
    try:
        # 这里放你原来的playbook执行代码
        callback = ResultsCollector()
        variable_manager = VariableManager()
        loader = DataLoader()
        inventory = Inventory(loader=loader, variable_manager=variable_manager, host_list=inventory)
        playbook_path = playbook
        
        if not os.path.exists(playbook_path):
            print "Playbook文件不存在!"
            return
        
        pbex = PlaybookExecutor(
            playbooks=[playbook_path],
            inventory=inventory,
            variable_manager=variable_manager,
            loader=loader,
            options=Options(forks=forks, verbosity=0),
            passwords={}
        )
        pbex._tqm._stdout_callback = callback
        result = pbex.run()
        return callback.results
    finally:
        # 恢复原来的输出流
        sys.stdout = original_stdout
        sys.stderr = original_stderr
        dev_null.close()

方法3:调整Ansible日志级别

通过环境变量把Ansible的日志级别调高到ERROR,这样只有错误信息会输出,执行过程的INFO级日志会被屏蔽:

import os

def run_playbook(playbook, inventory, package, var_file_path, forks):
    # 设置环境变量,将日志级别设为ERROR
    os.environ['ANSIBLE_LOG_LEVEL'] = 'ERROR'
    
    # 后续的playbook执行代码和原来一致即可
    callback = ResultsCollector()
    variable_manager = VariableManager()
    loader = DataLoader()
    inventory = Inventory(loader=loader, variable_manager=variable_manager, host_list=inventory)
    # ...其余代码不变

其中方法1是最推荐的,它从回调层面精准控制输出;方法2是兜底方案,适合处理那些无法通过回调拦截的输出;方法3则能快速减少Ansible本身的日志量。

内容的提问来源于stack exchange,提问作者Jitu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:03:00