使用 Ansible,我希望能够将运行命令的任务的 sysout 写入本地(即托管服务器上)日志文件。目前,我只能使用如下任务来执行此操作:
- name: Run my command
shell: <command> <arg1> <arg3> ... |tee -a <local log file>
这样做的原因是它需要很长时间才能完成(即我们不能等到它完成后才获取其输出)并且希望在执行期间收集输出。
是否有任何“Ansible”方法可以在执行命令期间将命令的 sysout 重定向到本地日志文件而不使用管道tee
?
答案1
您需要在第一个任务中使用寄存器,现在您可以创建第二个任务将输出写入本地文件
- name: shell command
shell: my_shell_command
register: myshell_output
- name: copy the output to a local file
copy:
content: "{{ myshell_output.stdout }}"
dest: "/tmp/hello.txt"
delegate_to: localhost
答案2
Ansible 默认(也是目前最常见的模式)是让任务完成并在最后记录输出。它具有异步功能,但您需要在剧本中查询它所做的工作。
相反,考虑使用 init 脚本功能将其置于后台。您标记了此 Linux,在 systemd 单元中,这种具有强大日志记录功能的东西相当容易。
vmstat 定期将数据输出到 stdout,这是一个简单示例。我介绍了记录 vmstat 输出的最愚蠢的方法: /etc/systemd/system/dumbstat.service
[Unit]
Description=Dumb vmstat wrapper service example
Documentation=https://serverfault.com/questions/958952/ansible-task-write-to-local-log-file
[Service]
Type=oneshot
ExecStart=/usr/bin/vmstat 5 12
StandardOutput=journal
[Install]
WantedBy=multi-user.target
Type=oneshot
将在启动状态下等待,直到进程退出。如果您想要更多的异步分叉和继续行为,您可能需要不同的类型。
标准输出可以通过常用工具捕获和使用。
root@sf-958952:/var/log# systemctl status dumbstat
● dumbstat.service - Dumb vmstat wrapper service example
Loaded: loaded (/etc/systemd/system/dumbstat.service; disabled; vendor preset: enabled)
Active: activating (start) since Wed 2019-03-20 14:49:41 UTC; 7s ago
Docs: https://serverfault.com/questions/958952/ansible-task-write-to-local-log-file
Main PID: 3103 (vmstat)
Tasks: 1 (limit: 4401)
CGroup: /system.slice/dumbstat.service
└─3103 /usr/bin/vmstat -w 5 12
Mar 20 14:49:41 sf-958952 systemd[1]: Starting Dumb vmstat wrapper service example...
Mar 20 14:49:41 sf-958952 vmstat[3103]: procs -----------------------memory---------------------- ---swap-- -----io---- -system-- --------cpu--------
Mar 20 14:49:41 sf-958952 vmstat[3103]: r b swpd free buff cache si so bi bo in cs us sy id wa st
Mar 20 14:49:41 sf-958952 vmstat[3103]: 7 0 0 3104416 70260 417228 0 0 208 36 40 132 1 1 98 0 0
Mar 20 14:49:46 sf-958952 vmstat[3103]: 0 0 0 3107200 70260 417260 0 0 0 0 40 130 1 0 99 0 0
您还可以通过查询 systemd 日志来过滤输出:journalctl _SYSTEMD_UNIT=dumbstat.service
如果您想要本地文件或将日志转发到某个地方,默认情况下它会转发到 syslog。
有趣的是,系统 240 及更高版本可以直接记录到文件, StandardOutput=append:
但这对于 CentOS 7 或 Ubuntu 18.04 来说太新了。
所有这些与 Ansible 关系不大。您可以使用模块部署这样的单元template
,并使用模块启动它systemd
。
答案3
- name: Run my command
shell: <command> <arg1> <arg3> ... >> <local log file>
答案4
我尝试了以下步骤,输出了详细的结果。请尝试一下
- name: save output in file under current directory
copy:
content: "{{ myoutput.results | replace('\\n', '\n') }}"
dest: "/tmp/maintainance/{{ inventory_hostname }}"
delegate_to: localhost