我已将 Fabric 设置为使用 INFO 或更高级别记录所有与 SSH/Paramiko 相关的输出:
logging.basicConfig()
logging.getLogger('ssh.transport').setLevel(logging.INFO)
这导致日志如下所示:
[host1] Executing task 'task1'
[host1] Run: ls
...
是否可以更改 ssh.transport 记录器的格式化程序,以便每行旁边也打印日期和时间?
正如alecxe 所说,该格式在 Fabric 1.x 中是硬编码的(截至我发布此版本时,这是唯一可用的版本。)有一个被拒绝的拉取请求可以解决这个问题。
因此,我们需要解决此问题。这是我编写的一个相当老套的解决方案,但它依赖于 Fabric 的未记录部分,这意味着它可能会在未来的版本中中断。
from fabric.io import OutputLooper
from datetime import datetime
def newFlush(self, text):
stamp = datetime.now().strftime("%a %b %d %H:%M:%S - ")
print(stamp + text)
OutputLooper._flush = newFlush
从现在开始,远程机器的任何输出都将带有时间戳。
例如,如果没有此代码,则输出sudo('echo "test"')将是:
[InteractSL-DT1.usma.ibm.com] sudo: echo "test"
[InteractSL-DT1.usma.ibm.com] out: test
[InteractSL-DT1.usma.ibm.com] out:
'test'
但是在添加之后,你现在会得到这个:
[InteractSL-DT1.usma.ibm.com] sudo: echo "test"
Fri Jan 02 12:54:49 - [InteractSL-DT1.usma.ibm.com] out:
Fri Jan 02 12:54:49 - test
Fri Jan 02 12:54:49 - [InteractSL-DT1.usma.ibm.com] out:
Fri Jan 02 12:54:49 -
'test'
你可以玩弄这个基本的想法来清理它。输出开头的sudo行来自fabric.operations._run_command,在第 900 行附近。我不确定您可以修改它的任何简单方法。
现在不可能了。格式是硬编码的:参见source。
仅供参考,有一个提案正在询问您的确切身份。
您可以使用内部设置日志记录格式asctime,但它不会影响结构输出,只会影响 paramiko 输出:
import logging
FORMAT = "%(asctime)s %(name)s %(message)s"
logging.basicConfig(format=FORMAT, level=logging.INFO)
示例输出:
[host] Executing task 'restart'
[host] sudo: ls
2013-09-23 02:36:54,800 paramiko.transport Connected (version 2.0, client OpenSSH_5.3)
2013-09-23 02:36:55,728 paramiko.transport Authentication (password) successful!
2013-09-23 02:36:55,889 paramiko.transport Secsh channel 1 opened.
...
希望有帮助。
除了更换_flush(). 我通常发现在任何类中替换私有方法都是一种冒险的做法,更不用说第三方了。这是一个装饰 Fabric_flush()方法并且还使用原生 Pythontime.asctime方法来格式化时间戳的解决方案。
def time_decorator(msg):
"""
Decorates `msg` with current timestamp
Args:
msg(str): The log message from fabric
Returns:
str: Original message prepended with current date time
"""
if "\n" not in msg and msg.strip():
return "[%s] %s" % (time.asctime(), msg)
return msg
# Compose original method inside of decorator
_original_flush = OutputLooper._flush
OutputLooper._flush = lambda self, msg: {
_original_flush(self, time_decorator(msg))
}
@task
def uptime():
run('uptime')
测试一下,你的输出应该类似于:
> fab uptime -H 10.0.1.3,10.0.1.2
[10.0.1.3] Executing task 'uptime'
[10.0.1.3] run: uptime
[Thu Dec 15 19:34:35 2016] [10.0.1.3] out: 19:34:35 up 69 days, 4:22, 1 user, load average: 0.05, 0.03, 0.05
[Thu Dec 15 19:34:35 2016] [10.0.1.3] out:
[10.0.1.2] Executing task 'uptime'
[10.0.1.2] run: uptime
[Thu Dec 15 19:34:35 2016] [10.0.1.2] out: 19:34:35 up 70 days, 1:12, 1 user, load average: 0.00, 0.01, 0.05
[Thu Dec 15 19:34:35 2016] [10.0.1.2] out:
Done.
Disconnecting from ec2-user@10.0.1.3... done.
Disconnecting from ec2-user@10.0.1.2... done.