如何配置哨兵以从 python 多处理池生成的进程发送异常?
How to configure sentry to send exception from process spawned by python multiprocessing pools?
我有一个由 celery worker 运行 编写的脚本,它使用台球库中的 Pool 并且我生成了多个进程。我正在尝试在这些进程中使用哨兵,以便可以捕获任何 unhandled/handled 异常。下面写的是我的示例代码:
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 传递给每个进程,但我现在正在努力避免这种情况。
此外,由于这个脚本是由 celery worker 执行的,我已经为 celery 配置了 sentry,任何异常直到 pool.map()
都会被 sentry 很好地捕获。
我还尝试打印 SENTRY_CLIENT.__dict__
,我得到了具有正确值的有效项目。
我的问题是为什么 SENTRY_CLIENT 没有向哨兵仪表板发送异常。可能是我在配置中遗漏了一些东西。
通过一些阅读,我终于得到了解决方案。
Sentry 在基于异步事件的模型上工作,并且在触发 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()
作为 PoloSoares ,您应该更改传输而不是通过睡眠添加任何延迟。 6.10.0 版 raven lib 的有效解决方案示例:
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()
我有一个由 celery worker 运行 编写的脚本,它使用台球库中的 Pool 并且我生成了多个进程。我正在尝试在这些进程中使用哨兵,以便可以捕获任何 unhandled/handled 异常。下面写的是我的示例代码:
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 传递给每个进程,但我现在正在努力避免这种情况。
此外,由于这个脚本是由 celery worker 执行的,我已经为 celery 配置了 sentry,任何异常直到 pool.map()
都会被 sentry 很好地捕获。
我还尝试打印 SENTRY_CLIENT.__dict__
,我得到了具有正确值的有效项目。
我的问题是为什么 SENTRY_CLIENT 没有向哨兵仪表板发送异常。可能是我在配置中遗漏了一些东西。
通过一些阅读,我终于得到了解决方案。 Sentry 在基于异步事件的模型上工作,并且在触发 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()
作为 PoloSoares
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()