Ansible Callback

非api模式下自定义callback

ansible.cfg中开启callback功能

callback_plugins   = /usr/share/ansible/plugins/callback      #指定路径后,callback文件要放到这个目录
bin_ansible_callbacks = True
callback_whitelist = timer    #指定脚本中定义的callback的名称  

 

官网示例:

# cat /usr/local/lib/python3.5/dist-packages/ansible/plugins/callback/log_plays.py    #默认路径

# Make coding more python3-ish from __future__ import (absolute_import, division, print_function) __metaclass__ = type from datetime import datetime from ansible.plugins.callback import CallbackBase class CallbackModule(CallbackBase): """ This callback module tells you how long your plays ran for. """ CALLBACK_VERSION = 2.0 CALLBACK_TYPE = 'aggregate' CALLBACK_NAME = 'timer'        #配置文件中定义的callback名称 CALLBACK_NEEDS_WHITELIST = True def __init__(self): super(CallbackModule, self).__init__() self.start_time = datetime.now() def days_hours_minutes_seconds(self, runtime): minutes = (runtime.seconds // 60) % 60 r_seconds = runtime.seconds - (minutes * 60) return runtime.days, runtime.seconds // 3600, minutes, r_seconds def playbook_on_stats(self, stats): self.v2_playbook_on_stats(stats) def v2_playbook_on_stats(self, stats): end_time = datetime.now() runtime = end_time - self.start_time self._display.display("Playbook run took %s days, %s hours, %s minutes, %s seconds" % (self.days_hours_minutes_seconds(runtime)))

效果图:

 

ansible自带的log插件

from __future__ import (absolute_import, division, print_function)
__metaclass__ = type

import os
import time
import json

from ansible.module_utils._text import to_bytes
from ansible.plugins.callback import CallbackBase

class CallbackModule(CallbackBase):
    """
    logs playbook results, per host, in /var/log/ansible/hosts
    """
    CALLBACK_VERSION = 2.0
    CALLBACK_TYPE = 'notification'
    CALLBACK_NAME = 'log_plays'            #callback name,需要在ansible配置文件中指定 如果下面参数为False,可忽略
    CALLBACK_NEEDS_WHITELIST = True    

    TIME_FORMAT="%b %d %Y %H:%M:%S"
    MSG_FORMAT="%(now)s - %(category)s - %(data)s\n\n"

    def __init__(self):

        super(CallbackModule, self).__init__()

        if not os.path.exists("/var/log/ansible/hosts"):
            os.makedirs("/var/log/ansible/hosts")

    def log(self, host, category, data):
        if type(data) == dict:
            if '_ansible_verbose_override' in data:
                # avoid logging extraneous data
                data = 'omitted'
            else:
                data = data.copy()
                invocation = data.pop('invocation', None)
                data = json.dumps(data)
                if invocation is not None:
                    data = json.dumps(invocation) + " => %s " % data

        path = os.path.join("/var/log/ansible/hosts", host)
        now = time.strftime(self.TIME_FORMAT, time.localtime())

        msg = to_bytes(self.MSG_FORMAT % dict(now=now, category=category, data=data))
        with open(path, "ab") as fd:
            fd.write(msg)

    def runner_on_failed(self, host, res, ignore_errors=False):
        self.log(host, 'FAILED', res)

    def runner_on_ok(self, host, res):
        self.log(host, 'OK', res)

    def runner_on_skipped(self, host, item=None):
        self.log(host, 'SKIPPED', '...')

    def runner_on_unreachable(self, host, res):
        self.log(host, 'UNREACHABLE', res)

    def runner_on_async_failed(self, host, res, jid):
        self.log(host, 'ASYNC_FAILED', res)

    def playbook_on_import_for_host(self, host, imported_file):
        self.log(host, 'IMPORTED', imported_file)

    def playbook_on_not_import_for_host(self, host, missing_file):
        self.log(host, 'NOTIMPORTED', missing_file)

以上示例为将执行结果写入到 /var/log/ansible/hosts目录以host为名的文件里,

 

#修改log_plays脚本并进行简单说明

#!/usr/bin/env python
#-*-coding:utf-8 -*-

from __future__ import (absolute_import, division, print_function) __metaclass__
= type import os import time import json from ansible.module_utils._text import to_bytes from ansible.plugins.callback import CallbackBase class CallbackModule(CallbackBase): """ logs playbook results, per host, in /var/log/ansible/hosts """ CALLBACK_VERSION = 2.0 CALLBACK_TYPE = 'notification' CALLBACK_NAME = 'log_plays'            #此处为callback_name,需要在配置文件中指定 CALLBACK_NEEDS_WHITELIST = True          #为True时,以上必做
  #定义的格式,自定义即可 TIME_FORMAT
="%b %d %Y %H:%M:%S" MSG_FORMAT="%(now)s - %(category)s - %(data)s\n\n" MSG_FORMAT1="%(data)s\n\n" def __init__(self): super(CallbackModule, self).__init__() if not os.path.exists("/var/log/ansible/hosts"): os.makedirs("/var/log/ansible/hosts")
  #定义log函数的目的是将处理后的执行结果写到文件,我这里直接display在屏幕上,这里可以自定义一个写入到数据库的函数, def log(self, host, category, data):
#默认的执行结果为一个字典,即data在这里为一个字典 result_last = json.dumps(self.option_result(data))  #定义一个函数,接收执行的结果,由于结果不支持字典数据,所以只能dumps成str self._display.display(result_last)            #将执行结果在屏幕上显示出来(不支持print打印)
     #以下为相关格式化内容 
   path
= os.path.join("/var/log/ansible/hosts", host) now = time.strftime(self.TIME_FORMAT, time.localtime()) # msg = to_bytes(self.MSG_FORMAT % dict(now=now, category=category, data=data)) # msg1 = to_bytes(self.MSG_FORMAT1 % dict(data=data)) # with open(path, "ab") as fd: # fd.write(msg)   #定义函数,解析执行结果,并返回给log函数(注:此函数里代码可直接写到log函数里,此处为了区分清楚,单写一个) def option_result(self,msg):   result = {}   result['stderr_lines'] = data_result['stderr_lines']   result['start_time'] = data_result['start']   result['end_time'] = data_result['end']   result['stderr'] = data_result['stderr']   return result
def runner_on_failed(self, host, res, ignore_errors
=False): self.log(host, 'FAILED', res) def runner_on_ok(self, host, res): self.log(host, 'OK', res) def runner_on_skipped(self, host, item=None): self.log(host, 'SKIPPED', '...') def runner_on_unreachable(self, host, res): self.log(host, 'UNREACHABLE', res) def runner_on_async_failed(self, host, res, jid): self.log(host, 'ASYNC_FAILED', res) def playbook_on_import_for_host(self, host, imported_file): self.log(host, 'IMPORTED', imported_file) def playbook_on_not_import_for_host(self, host, missing_file): self.log(host, 'NOTIMPORTED', missing_file)

 

结果(没有经过解析处理的完整内容):

 

经过解析:

 #然后可以自定义脚本,将结果发送邮件给管理员,或者写入到数据库,此处不再详细介绍

Api模式下使用CallBack功能

首先看一下简单示例(ad-hoc),python_version == 2.3.1

#!/usr/bin/env python
# -*-coding:utf-8 -*-

import json
from collections import namedtuple
from ansible.parsing.dataloader import DataLoader
from ansible.vars import VariableManager
from ansible.inventory import Inventory
from ansible.playbook.play import Play
from ansible.executor.task_queue_manager import TaskQueueManager
from ansible.plugins.callback import CallbackBase

# 自定义运行callback,即运行完api后调用v2_runner_on_ok函数,打印host和result
class ResultsCallback(CallbackBase):
    def __init__(self, *args, **kwargs):
        super(ResultsCallback, self).__init__(*args, **kwargs)          #初始化父类
        self.host_ok = {}
     
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值