Check out R. Tyler’s post on blocking detection in Eventlet. It’s good stuff — if you’re concerned about performance under load, detecting places where your code blocks should be your first order of business. Here’s the official documentation on enabling blocking detection.
Using signals is kind of appropriate for this sort of functionality, because signals are part of a sorta old-school way of implementing concurrency. The nice thing about them versus, say, a watchdog thread, is that the Python interpreter really interrupts itself in the middle of whatever it was doing when the signal comes in, so the handler can print the lowest-level line of code that was blocking.