如何以RFC5424格式打印Ansible Playbook所有任务日志?
实现Ansible Playbook任务日志以RFC5424格式输出的方法
要让Ansible任务日志输出符合RFC5424(Syslog标准格式),最直接的方式是自定义Ansible回调插件,通过重写任务事件的处理逻辑来生成符合规范的日志格式。以下是具体实现步骤:
一、明确RFC5424格式结构
RFC5424的标准格式为:
<PRI>VERSION TIMESTAMP HOSTNAME APP-NAME PROCID MSGID STRUCTURED-DATA MSG
各核心字段说明:
<PRI>:由设施码+级别码计算得出,比如用户设施(16)+信息级别(6)对应<134>VERSION:固定为1TIMESTAMP:UTC时区的ISO8601格式,示例:2024-05-20T12:34:56.789ZHOSTNAME:生成日志的主机(可设为Ansible控制节点或目标节点)APP-NAME:标识应用,这里统一设为ansiblePROCID:进程标识(可复用Playbook的PID)MSGID:日志唯一标识(可直接用任务名称)STRUCTURED-DATA:结构化扩展字段(比如模块名、目标主机),无内容时填-MSG:任务的具体结果信息
二、编写自定义回调插件
- 创建插件文件,命名为
rfc5424_callback.py,内容如下:
from ansible.plugins.callback import CallbackBase import datetime import socket import sys class CallbackModule(CallbackBase): CALLBACK_VERSION = 2.0 CALLBACK_NAME = 'rfc5424' CALLBACK_NEEDS_WHITELIST = True def __init__(self): super().__init__() self.control_host = socket.gethostname() self.app_name = 'ansible' # 用Playbook进程ID作为PROCID self.procid = f'{sys.argv[0].split("/")[-1]}-{sys.getpid()}' def _build_rfc5424_msg(self, severity_code, msg_id, structured_data, message): # 计算PRI值:用户设施(16)*8 + 级别码 pri = f'<{16*8 + severity_code}>' version = '1' # 生成UTC毫秒级时间戳 timestamp = datetime.datetime.utcnow().isoformat(timespec='milliseconds') + 'Z' # 处理结构化数据,无内容则用'-' structured_data = f'[{structured_data}]' if structured_data else '-' # 拼接完整日志串 return f'{pri}{version} {timestamp} {self.control_host} {self.app_name} {self.procid} {msg_id} {structured_data} {message}' # 处理任务成功事件 def v2_runner_on_ok(self, result): task_name = result._task.name structured = f'module="{result._task.action}" target_host="{result._host.name}" status="ok"' msg_content = result._result.get("msg", "Task executed successfully") rfc_msg = self._build_rfc5424_msg(6, task_name, structured, str(msg_content)) print(rfc_msg) # 处理任务失败事件 def v2_runner_on_failed(self, result, ignore_errors=False): task_name = result._task.name structured = f'module="{result._task.action}" target_host="{result._host.name}" status="failed"' msg_content = result._result.get("msg", "Task failed") rfc_msg = self._build_rfc5424_msg(3, task_name, structured, str(msg_content)) print(rfc_msg) # 处理任务跳过事件 def v2_runner_on_skipped(self, result): task_name = result._task.name structured = f'module="{result._task.action}" target_host="{result._host.name}" status="skipped"' rfc_msg = self._build_rfc5424_msg(5, task_name, structured, "Task skipped") print(rfc_msg)
- 将插件文件放到Ansible回调插件目录:
- 系统默认目录:
/usr/share/ansible/plugins/callback/ - 或自定义目录:
~/.ansible/plugins/callback/
- 系统默认目录:
三、配置Ansible启用插件
修改ansible.cfg文件(无则在当前目录或~/.ansible/下创建),添加以下配置:
[defaults] # 若使用自定义插件目录,需指定路径(系统默认目录可省略此行) callback_plugins = ~/.ansible/plugins/callback/ # 允许使用自定义回调插件 callback_whitelist = rfc5424
四、验证效果
运行Playbook(如ansible-playbook your_playbook.yml),控制台输出的任务日志会自动转为RFC5424格式,示例如下:
<134>1 2024-05-20T12:40:15.123Z ansible-control ansible ansible-playbook-12345 Install_Nginx [module="apt" target_host="web01" status="ok"] Changed: 1, Unchanged: 0
如果需要将日志发送到Syslog服务器,只需把插件里的print(rfc_msg)替换为Syslog发送逻辑:
import syslog syslog.openlog(ident='ansible', facility=syslog.LOG_USER) syslog.syslog(syslog.LOG_INFO, rfc_msg)
内容的提问来源于stack exchange,提问作者Aditya Siddarth
相关产品推荐
相关产品推荐

