You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Ansible回调插件中如何获取playbook的extra arguments及实现runID标记计时

获取Ansible Callback Plugin中的Playbook额外参数(runID)

我刚好碰到过类似的需求,给你梳理下可行的解决方案,核心在于找对Callback Plugin的钩子方法,以及正确获取额外参数的路径:

1. 关键:在Playbook启动时捕获runID

你需要在v2_playbook_on_start钩子中获取传入的runID——这个钩子会在整个Playbook开始执行时触发,能直接访问到Playbook级别的额外参数。

示例代码片段:

from ansible.plugins.callback import CallbackPlugin
import datetime
import uuid

class CallbackModule(CallbackPlugin):
    CALLBACK_VERSION = 2.0
    CALLBACK_NAME = 'task_timer'
    CALLBACK_NEEDS_WHITELIST = True  # Ansible 2.10+版本可省略

    def __init__(self):
        super().__init__()
        self.run_id = None
        self.task_start_times = {}  # 存储每个task的开始时间

    def v2_playbook_on_start(self, playbook):
        # 从extra_vars中提取runID
        self.run_id = playbook.extra_vars.get('runID')
        # 兜底:如果没有传入runID,生成一个默认唯一ID
        if not self.run_id:
            self.run_id = f"default-run-{str(uuid.uuid4())}"

    # 记录task开始时间
    def v2_runner_on_start(self, host, task):
        self.task_start_times[task._uuid] = datetime.datetime.now()

    # 统一处理不同状态的task结果
    def v2_runner_on_ok(self, result):
        self._process_task_result(result, 'ok')

    def v2_runner_on_failed(self, result, ignore_errors=False):
        self._process_task_result(result, 'failed')

    def v2_runner_on_skipped(self, result):
        self._process_task_result(result, 'skipped')

    def _process_task_result(self, result, status):
        start_time = self.task_start_times.pop(result._task._uuid, None)
        if not start_time:
            return
        
        # 计算耗时(保留两位小数)
        duration = (datetime.datetime.now() - start_time).total_seconds()
        # 组装上报数据,带上runID标记
        log_payload = {
            'runID': self.run_id,
            'task_name': result._task.get_name().strip(),
            'host': result._host.get_name(),
            'duration_seconds': round(duration, 2),
            'status': status,
            'task_uuid': result._task._uuid
        }

        # 替换成你的logging agent上报逻辑(比如HTTP请求、消息队列等)
        self._send_to_logging_agent(log_payload)

    def _send_to_logging_agent(self, payload):
        # 示例:打印到控制台,实际替换成你的上报代码
        print(f"[Task Timer] Reporting: {payload}")

2. 验证与注意事项

  • 传入runID的方式:确保你用--extra-vars(或-e)参数传入,比如:
    ansible-playbook -e "runID=prod-deploy-20240520-001" your_deploy_playbook.yml
    
  • Callback Plugin的加载:把这个插件文件放在callback_plugins目录下(或在ansible.cfg中配置callback_plugins路径),然后启用它:
    [defaults]
    # Ansible 2.10+用callback_enabled,旧版本用callback_whitelist
    callback_enabled = task_timer
    
  • 多Play场景:如果你的Playbook包含多个Play,runID会全局生效;如果需要在单个Play级别覆盖,可在v2_play_on_start钩子中重新读取Play的vars更新self.run_id

3. 为什么之前没找到?

你之前尝试的钩子可能是Task级别的(比如v2_runner_on_ok),这些钩子只能访问单个Task的上下文,而Playbook级别的额外参数需要在Playbook启动的钩子中获取并存储,后续Task钩子再复用这个值。

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

火山引擎 最新活动