我有一个由芹菜工人运行的脚本,它使用台球库中的Pool,我产生了多个进程。我试图在这些进程中使用sentry,以便可以捕获任何未处理/处理的异常。以下是我的示例代码:
from configurations import SENTRY_CLIENT
def process_data(data):
try:
s = data/0
except ZeroDivisionError:
print "Sentry must report this."
SENTRY_CLIENT.captureException()
import multiprocessing
from billiard import Pool
POOL_SIZE=multiprocessing.cpu_count()
pool = Pool(POOL_SIZE)
data=[0, 1, 2, 3, 4, 5]
pool.map(process_data, data)
pool.close()
pool.terminate()
SENTRY_CLIENT在配置文件中定义,定义为: configurations.py
from raven import Client
SENTRY_CLIENT = Client("dsn")
我尝试的一种方法是将SENTRY_CLIENT传递给每个进程,但我现在正试图避免这种情况。
此外,由于这个脚本由芹菜工人执行,我已经为芹菜配置了哨兵,并且任何例外直到pool.map()
被哨兵抓住。
此外,我尝试打印SENTRY_CLIENT.__dict__
,我得到了正确值的有效项。
我的问题在于,为什么SENTRY_CLIENT不向哨兵仪表板发送异常。可能是我在配置中遗漏了一些东西。
答案 0 :(得分:2)
我终于通过一些阅读得到了解决方案。 Sentry在基于异步事件的模型上工作,并且在触发哨兵之后立即终止进程将无法确保到达服务器的异常。因此,我们需要添加一个延迟(10秒),在任何异常的情况下杀死进程,以确保哨兵完成它的工作。
def process_data(data):
from configurations import SENTRY_CLIENT
try:
s = data/0
except ZeroDivisionError:
print "Sentry must report this."
import time
SENTRY_CLIENT.captureException()
time.sleep(10)
import multiprocessing
from billiard import Pool
POOL_SIZE=multiprocessing.cpu_count()
pool = Pool(POOL_SIZE)
data=[0, 1, 2, 3, 4, 5]
pool.map(process_data, data)
pool.close()
pool.terminate()
答案 1 :(得分:1)
作为PoloSoares said,您应该更改传输方式,而不要增加任何睡眠延迟。乌鸦库6.10.0版本的有效解决方案示例:
import multiprocessing
from billiard import Pool
from raven import Client
from raven.transport.http import HTTPTransport
SENTRY_CLIENT = Client("dsn", transport=HTTPTransport)
def process_data(data):
try:
s = data / 0
except ZeroDivisionError:
print("Sentry must report this.")
SENTRY_CLIENT.captureException()
POOL_SIZE = multiprocessing.cpu_count()
pool = Pool(POOL_SIZE)
data = [0, 1, 2, 3, 4, 5]
pool.map(process_data, data)
pool.close()
pool.terminate()