当我运行ansible dnf模块时,dnf通过logging模块写入的消息似乎不会到达任何地方。这一切为什么要发生?
我有一个呼叫链,类似于:
(python3) ->抗dnf模块-> import dnf . -> dnf插件蚀刻器-dnf
当前版本的etckeeper继续运行etckeeper,使用os.system()。所以它写到stdout和confuses ansible。我想这是蚀刻器dnf中的一个错误。我对ansible被允许使用import dnf等很有信心。我遇到了另一个dnf插件的补丁,它说dnf cli对象不一定可用,这听起来类似于一种类似的场景。
对于Ansible来说,想要能够控制stdout/stderr,而不让它们受到库代码的干扰似乎是合理的。
因此,我已经修补了etckeeper,我实际上是将它的stdout+stderr传输到python模块。这正是我想要的。它修复了Ansible。而dnf命令仍然显示所有的etckeeper消息。(它们现在也被复制到/var/log/dnf.log)。
,但现在我有一个阅读理解问题。
当我运行ansible dnf模块时,dnf通过logging模块写入的消息,包括来自etckeeper的消息,似乎不会出现在任何地方。
那不是我的零钱,不是我的错,也不是我需要的东西。我甚至测试了如果守护者失败的话会发生什么: etckeeper只是在继续,所以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?
发布于 2019-04-23 18:08:18
最初的etckeeper-dnf破坏了Ansible,因为它写信给stdout。然而,我们确定python logging模块写入stderr。
如果您查看链接中的输出,Ansible将module_stdout和module_stderr分开。通常它只是忽略module_stderr;它只在MODULE FAILURE的情况下显示它。(尽管其他一些模块并不总是独立于stdout/stderr, module)。
因此,我仍然认为,修改蚀刻师-dnf的建议是合理的。不管dnf模块是如何故意以这种方式设计的,依赖这种特定行为似乎是相当合理的。修改后的代码不太可能被Ansible dnf模块中的未来更改所破坏。
我要注意的是,当您按下MODULE FAILURE时,module_stderr只显示dnf的错误消息。您不会看到来自日志级信息或更低级别的任何消息,即dnf通常的无错误、非交互输出。
(如果在使用etckeeper时,etckeeper故障被视为致命的,那么使用.info()记录所有etc禁者的输出可能不是个好主意。Ansible将丢失来自的原始错误消息(并且错误消息不会被记录在其他任何地方)。
然而,我测试了系统后,黑客蚀刻返回EXIT_FAILURE。IIRC,dnf继续执行,而不考虑任何守护者故障。总体效果是,无论我如何记录错误,Ansible都不会向您提供有关未能运行etc禁者的任何信息。通常,单独处理stdout和stderr消息要复杂得多,并且会对消息的顺序产生奇怪的影响。所以我遵循了K.I.S.S.原则:-)。
或者更笼统地说:
默认情况下,写在日志级信息及以下的logging消息将无处可去。日志级警告和更高级别的消息将转到stderr。它们不会干扰正常的无源模块操作。在正常的Ansible模块操作中,即使这些消息也不会去任何地方。
如果存在MODULE FAILURE --即模块崩溃或不生成Ansible可以按预期解析的JSON输出-- Ansible将显示module_stderr,其中仅包含日志级警告或以上的logging消息。
https://stackoverflow.com/questions/55817067
复制相似问题