python日志记录模块在Ansible模块中写入哪里?

时间:2019-04-23 18:08:19

标签: python ansible

当我运行ansible dnf模块时,dnf通过logging模块写入的消息似乎不会出现在任何地方。为什么会这样?


我有一个类似于的呼叫链:

ansible(python3)-> ansible dnf模块-> import dnf ...-> dnf插件etckeeper-dnf

当前的etckeeper-dnf版本继续使用etckeeper运行os.system()。因此它将写入stdout和confuses ansible。我认为这是etckeeper-dnf中的错误。我相当有信心允许import dnf等使用ansible。我遇到了另一个dnf插件修复程序,该修复程序说dnf cli对象不一定可用,这听起来很像。 >

Ansible希望能够控制stdout / stderr而不受到库代码的干扰似乎是合理的。

因此,我已经修补了etckeeper-dnf,并且有效地将其stdout + stderr用管道传输到python logging模块。这正是我想要的。它修复了Ansible。并且dnf命令仍然显示所有etckeeper消息。 (它们现在也已复制到/var/log/dnf.log)。

但是现在我的阅读能力出现了问题。

当我运行ansible dnf模块时,dnf通过logging模块写入的消息,包括来自etckeeper-dnf的消息,似乎并没有出现在任何地方。

那不是我的改变,不是我的错,也不是我所需要的。我什至测试了如果etckeeper失败的话会发生什么:etckeeper-dnf继续,所以Ansible不会显示任何警告(除非我故意破坏了Ansible)。

但是我对所有警告消息都将丢失的想法感到不安。

我确保同时使用dnfpluginscore.logger.error().info()进行测试,但是在两种情况下都看不到消息。

logging模块的默认配置是写入stderr。除非您使用dnf,否则dnf.cli.BaseCli模块不会对其进行任何配置。 Ansible模块dnf.py不使用dnf.cli中的任何内容,并且对logging不执行任何操作。基类AnsibleModule也不使用python logging;它有自己独立的.log()方法。

那么为什么用.error()编写的消息没有出现在Ansible模块的输出管道上,并再次中断Ansible?

  • ansible-2.7.10-1.fc29.noarch
  • dnf-4.2.2-2.fc29.noarch
  • python3-3.7.3-1.fc29.x86_64

1 个答案:

答案 0 :(得分:0)

原始etckeeper-dnf打破了Ansible,因为它写到了stdout。而我们确定python logging模块将写入stderr。

如果您查看链接中的输出,则Ansible将module_stdoutmodule_stderr分开。通常它只是忽略module_stderr;仅在MODULE FAILURE的情况下显示它。 (尽管某些其他模块并不总是将stdout / stderr e.g. the Ansible script module分开)。

因此,我仍然认为对etckeeper-dnf的更改建议是合理的。而且,不管以这种方式故意来设计Ansible dnf模块,依靠这种特定的行为似乎都是很合理的。更改后的代码不太可能会被Ansible dnf模块中的将来更改破坏。

我会注意到,当您点击MODULE FAILURE时,module_stderr仅显示dnf的错误消息。您不会看到来自日志级别INFO或以下级别的任何消息,即dnf通常的非错误,非交互式输出。

如果etckeeper-dnf did 将任何etckeeper故障视为致命的,那么使用.info()记录所有etckeeper输出不是一个好主意。 Ansible将错过来自etckeeper的原始错误消息(并且该错误消息将不会记录在其他任何地方)。


或更笼统地说:

默认情况下,日志级别为INFO或以下的logging消息将无处发送。日志级别WARNING及更高级别的消息将转到stderr。它们不会干扰Ansible模块的正常运行。在正常的Ansible模块操作中,即使这些消息也不会发送到任何地方。

如果存在MODULE FAILURE-即模块崩溃或未生成Ansible可以按预期解析的JSON输出-Ansible将显示module_stderr,其中包含logging条或更高版本的消息日志级别仅警告。