Python fabric,发送失败通知
Python fabric, send notification on failure
我一直在尝试找出当我的结构脚本失败时执行某些操作的最佳方法(例如通过 python 模块 slackbot
发送松弛通知消息)。
我已经举了一个例子,我尝试在此处执行上述操作:
fab_failtest.py
my_slackclient.py
您可以 运行 通过将两个文件下载到一个目录,pip install fabric
和 slackbot
,然后 运行:
fab --fabfile=fab_failtest.py fail_test1
或
fab --fabfile=fab_failtest.py fail_test2
(你还必须有一台可以通过 ssh 访问的机器,在这个例子中我有 mrbluesky@elo
并在 22
上打开了 ssh 端口)
fail_test1
使用 try-except
所以我可以获得异常错误信息等等
fail_test2
使用 try-finally
加上一个简单的布尔变量,因此没有可用的异常信息
起初我以为我用 fail_test1
示例就可以了,但我已经看到它多次失败以在失败时发送松弛消息,我想知道是否可能存在竞争条件或其他问题涉及?我可以开始使用 fail_test2
,但我真的很喜欢像 fail_test1
.
那样访问堆栈跟踪
有没有更好的方法来做到这一点,比如 python 结构中提供的东西,它完全可以完成我在上面的例子中想要完成的事情?
我不同意你的两种方法。我坚信代码越少越好。那是什么意思?一个函数应该按照它的名字说的做,不多也不少,如果你必须添加一个全局处理程序,我会把它作为一个包装器添加进去,结构函数很难阅读,不需要添加错误处理到混合。话虽如此:
import sys
import traceback
from fabric.api import task, settings, local, abort
from fabric.decorators import _wrap_as_new
from functools import wraps
HOST = 'elo'
PORT = 22
def alert_on_fail(func):
@wraps(func)
def decorated(*args, **kwargs):
try:
return func(*args, **kwargs)
except:
# TODO: add more code here
exception_type, value, tb_msg = sys.exc_info()
traceback_msg = traceback.format_exc()
notify('something went wrong: ' + traceback_msg)
abort('exiting error!!')
return _wrap_as_new(func, decorated)
@task
@alert_on_fail
def fail_test(host=HOST, port=PORT):
notify('fail test', msg_type='info')
local('''python -c "raise Exception('foobar')"''')
notify('script ran successfully', msg_type='success') # this will never run because the function above crashed
@task
@alert_on_fail
def pass_test(host=HOST, port=PORT):
notify('pass test', msg_type='info')
local('whoami')
notify('script ran successfully', msg_type='success')
def notify(msg, **kwargs):
# DISREGARD THIS
print 'sent to slack:', msg
输出:
$ fab fail_test
sent to slack: fail test
[localhost] local: python -c "raise Exception('foobar')"
Traceback (most recent call last):
File "<string>", line 1, in <module>
Exception: foobar
Fatal error: local() encountered an error (return code 1) while executing 'python -c "raise Exception('foobar')"'
Aborting.
sent to slack: something went wrong: Traceback (most recent call last):
File "/private/tmp/fabfile.py", line 21, in decorated
return func(*args, **kwargs)
File "/private/tmp/fabfile.py", line 34, in fail_test
local('''python -c "raise Exception('foobar')"''')
File "/usr/local/lib/python2.7/site-packages/fabric/operations.py", line 1198, in local
error(message=msg, stdout=out, stderr=err)
File "/usr/local/lib/python2.7/site-packages/fabric/utils.py", line 347, in error
return func(message)
File "/usr/local/lib/python2.7/site-packages/fabric/utils.py", line 53, in abort
sys.exit(msg)
SystemExit: local() encountered an error (return code 1) while executing 'python -c "raise Exception('foobar')"'
Fatal error: exiting error!!
Aborting.
exiting error!!
和:
$ fab pass_test
sent to slack: pass test
[localhost] local: whoami
buzzi
sent to slack: script ran successfully
Done.
您会注意到这些函数现在 "easy" 可以阅读,它们是 "simple",所有错误处理代码都已移至其他地方。
我一直在尝试找出当我的结构脚本失败时执行某些操作的最佳方法(例如通过 python 模块 slackbot
发送松弛通知消息)。
我已经举了一个例子,我尝试在此处执行上述操作:
fab_failtest.py my_slackclient.py
您可以 运行 通过将两个文件下载到一个目录,pip install fabric
和 slackbot
,然后 运行:
fab --fabfile=fab_failtest.py fail_test1
或
fab --fabfile=fab_failtest.py fail_test2
(你还必须有一台可以通过 ssh 访问的机器,在这个例子中我有 mrbluesky@elo
并在 22
上打开了 ssh 端口)
fail_test1
使用try-except
所以我可以获得异常错误信息等等fail_test2
使用try-finally
加上一个简单的布尔变量,因此没有可用的异常信息
起初我以为我用 fail_test1
示例就可以了,但我已经看到它多次失败以在失败时发送松弛消息,我想知道是否可能存在竞争条件或其他问题涉及?我可以开始使用 fail_test2
,但我真的很喜欢像 fail_test1
.
有没有更好的方法来做到这一点,比如 python 结构中提供的东西,它完全可以完成我在上面的例子中想要完成的事情?
我不同意你的两种方法。我坚信代码越少越好。那是什么意思?一个函数应该按照它的名字说的做,不多也不少,如果你必须添加一个全局处理程序,我会把它作为一个包装器添加进去,结构函数很难阅读,不需要添加错误处理到混合。话虽如此:
import sys
import traceback
from fabric.api import task, settings, local, abort
from fabric.decorators import _wrap_as_new
from functools import wraps
HOST = 'elo'
PORT = 22
def alert_on_fail(func):
@wraps(func)
def decorated(*args, **kwargs):
try:
return func(*args, **kwargs)
except:
# TODO: add more code here
exception_type, value, tb_msg = sys.exc_info()
traceback_msg = traceback.format_exc()
notify('something went wrong: ' + traceback_msg)
abort('exiting error!!')
return _wrap_as_new(func, decorated)
@task
@alert_on_fail
def fail_test(host=HOST, port=PORT):
notify('fail test', msg_type='info')
local('''python -c "raise Exception('foobar')"''')
notify('script ran successfully', msg_type='success') # this will never run because the function above crashed
@task
@alert_on_fail
def pass_test(host=HOST, port=PORT):
notify('pass test', msg_type='info')
local('whoami')
notify('script ran successfully', msg_type='success')
def notify(msg, **kwargs):
# DISREGARD THIS
print 'sent to slack:', msg
输出:
$ fab fail_test
sent to slack: fail test
[localhost] local: python -c "raise Exception('foobar')"
Traceback (most recent call last):
File "<string>", line 1, in <module>
Exception: foobar
Fatal error: local() encountered an error (return code 1) while executing 'python -c "raise Exception('foobar')"'
Aborting.
sent to slack: something went wrong: Traceback (most recent call last):
File "/private/tmp/fabfile.py", line 21, in decorated
return func(*args, **kwargs)
File "/private/tmp/fabfile.py", line 34, in fail_test
local('''python -c "raise Exception('foobar')"''')
File "/usr/local/lib/python2.7/site-packages/fabric/operations.py", line 1198, in local
error(message=msg, stdout=out, stderr=err)
File "/usr/local/lib/python2.7/site-packages/fabric/utils.py", line 347, in error
return func(message)
File "/usr/local/lib/python2.7/site-packages/fabric/utils.py", line 53, in abort
sys.exit(msg)
SystemExit: local() encountered an error (return code 1) while executing 'python -c "raise Exception('foobar')"'
Fatal error: exiting error!!
Aborting.
exiting error!!
和:
$ fab pass_test
sent to slack: pass test
[localhost] local: whoami
buzzi
sent to slack: script ran successfully
Done.
您会注意到这些函数现在 "easy" 可以阅读,它们是 "simple",所有错误处理代码都已移至其他地方。