是否可以在生产Linux系统上安全地监视Python堆栈?

是否可以在生产Linux系统上安全地监视Python堆栈?,python,linux,performance,signals,Python,Linux,Performance,Signals,在开发过程中(即不在生产系统中)针对性能问题的常见调试技术是随机停止程序并检查堆栈。如果您经常看到相同或相似的堆栈,这就表明性能问题是由程序执行该操作时发生的任何事情引起的 我想在一个生产系统中做一些类似的事情,因为如果可以对其进行非破坏性测量的话,那里的信息在解决性能问题方面可能是有用的 我的第一个想法是向相关进程发送UNIX信号。然后,该信号的信号处理程序将记录堆栈(从信号处理程序记录会带来其自身的复杂性,但它们可以解决,并且与此问题并不真正相关) 然而,这是有问题的,因为信号可能会导致系统

在开发过程中(即不在生产系统中)针对性能问题的常见调试技术是随机停止程序并检查堆栈。如果您经常看到相同或相似的堆栈,这就表明性能问题是由程序执行该操作时发生的任何事情引起的

我想在一个生产系统中做一些类似的事情,因为如果可以对其进行非破坏性测量的话,那里的信息在解决性能问题方面可能是有用的

我的第一个想法是向相关进程发送UNIX信号。然后,该信号的信号处理程序将记录堆栈(从信号处理程序记录会带来其自身的复杂性,但它们可以解决,并且与此问题并不真正相关)

然而,这是有问题的,因为信号可能会导致系统调用中断,这可能会通过改变其行为或通过重试降低性能而破坏正常工作的生产代码。我相信Python标准库在很多地方仍然不能正确处理EINTR,这加剧了这个问题

有没有办法部分或全部避免这些问题?答案不需要涉及信号(但我不确定是否有其他方法)。请注意,用信号触发堆栈日志记录的部分吸引力在于,这将有助于揭示由于I/O而出现的问题,而不仅仅是由于CPU时间过度使用而导致的问题。

这似乎有效:

import signal
import traceback

def handler(*_):
  traceback.print_stack()

signal.signal(signal.SIGUSR1, handler)

Python在如何安全地处理信号方面有相当多的专业知识,所以我认为这应该是可以的。在我对Python2.7.6进行的简短测试中,它起到了作用。

Python2(和3,仍然?)与许多其他语言/标准库相比,不能很好地处理EINTR。您编写的代码确实是生产使用中存在问题的代码,原因我在问题中列出:它可能会改变程序行为和性能。发送几个信号是一回事,但很多信号都是潜在的问题。另外,在我的实验中,一个在select中的db锁上被阻塞的postgres查询从未调用过我的SIGUSR2信号处理程序——即使在我随后向它发送了一个SIGINT之后,我希望它能开始为SIGUSR2运行python信号处理程序。)@CroadLangshan:当然,任何信号处理方案都会影响程序性能。我认为这是不可避免的。但让我们谈谈行为。由于异步信号安全要求,Python在执行C代码时可能会“延迟”Python信号处理程序。长时间运行的C扩展可能暂时无法将控制权让给Python解释器,只有在它让出控制权之后才能调用信号处理程序。这就是为什么你会经历SIGUSR2延迟。我不认为有任何方法可以解决这个问题,但我也认为这对您概述的用例来说应该没有太大影响。延迟是我所期望的。我看到的是,即使在第二个信号到达并且控制返回到Python代码之后,处理程序也没有被调用。重新执行:同意,但问题是影响有多大,就我而言,这似乎是个问题。