Unix Signals for Live Debugging
It's unit tested, the integration and regressions tests are all green, you even added a set of performance benchmarks, and yet after a couple of hours of production use the process is falling over - we've all been there before. Good instrumentation in these situations is worth its weight in gold. If you're lucky, you may be able to use DTrace, if you're adventurous you may try to attach with GDB, but what if you build this instrumentation into your app right from the start?
System signals for easy debugging
Any UNIX process can respond to a collection of system signals, and what's even better: we can safely define a subset (USR1, and USR2) to invoke arbitrary logic within our process. For example, let's create a worker process which on receipt of a USR1 signal will toggle debug mode on demand:
require 'rubygems' require 'log4r' # initialize the logger @log = Log4r::Logger.new 'log' @log.outputters = Log4r::StdoutOutputter.new 'console' @log.level = Log4r::INFO worker = Thread.new do while (true) do @log.info 'Hello!' @log.debug 'Debug!' sleep(1) end end # put worker into debug mode via USR1 signal trap("USR1") { @log.level = @log.level == Log4r::INFO ? Log4r::DEBUG : Log4r::INFO } # cleanly shutdown the thread on Ctrl-C / kill signal trap("INT") { worker.terminate } # run the worker worker.join
In the example above Log4r provides us with a convenient logging hierarchy: DEBUG < INFO < WARN < ERROR < FATAL. By sending our process a USR1 signal (kill -s USR1 pid), we toggle between the INFO and DEBUG levels, allowing ourselves the luxury of performing live debugging without incurring the cost of redundantly logging debug information when we don't need it. Now you have the tools to perform that open-heart surgery.
INFO log: Hello! < process is started
INFO log: Hello!
INFO log: Hello! < process receives USR1
DEBUG log: Debug!
INFO log: Hello!
DEBUG log: Debug! < process receives USR1
INFO log: Hello!
INFO log: Hello!
For bonus points, check what signals your favorite UNIX processes respond to. For example, did you know that kill -s USR1 mongrel_pid will turn on debug mode on any Mongrel process? Make use of system signals, they're there for reason!
About this entry
- Published:
- 22.07.08 / 8am
- Category:
- Ruby
Related Posts
- 19.06 Splunk Your Distributed Logs in EC2
- 19.02 Live Mongrel Debugging and Recovery
- 22.10 Distributed Logging: Syslog-ng & Splunk
- 11.12 Visual Database Explorer in Ruby
- 22.09 High-Performance DNS for The Cloud

















Entries RSS
2 Comments
comments rss | trackback uri