当我运行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?
答案 0 :(得分:0)
原始etckeeper-dnf
打破了Ansible,因为它写到了stdout。而我们确定python logging
模块将写入stderr。
如果您查看链接中的输出,则Ansible将module_stdout
和module_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
条或更高版本的消息日志级别仅警告。