When programming with 3rd party libraries, sometimes we need to suppress or redirect the standard output generated by the 3rd party libraries. A very common scenario is that a third party library we use in an application generates a very verbose output which clutters up the output of our program. With most programming languages we can write a simple suppress/redirect procedure to fix this problem. Such functions are sometimes colloquially known as STFU functions. Here I'm describing a couple of STFU functions I implemented in some of my recent work.
1. AppsCake (Web interface for AppScale-Tools)
This is a Ruby based dynamic web component which uses some of the core AppScale-Tools libraries. For this project I wanted to capture the standard output of the AppScale-Tools libraries and display it on a web page. As the first step I wanted to redirect the standard output of AppScale-Tools to a separate text file. Here's what I did.
def redirect_standard_io(timestamp) begin orig_stderr = $stderr.clone orig_stdout = $stdout.clone log_path = File.join(File.expand_path(File.dirname(__FILE__)), "..", "logs") $stderr.reopen File.new(File.join(log_path, "deploy-#{timestamp}.log"), "w") $stderr.sync = true $stdout.reopen File.new(File.join(log_path, "deploy-#{timestamp}.log"), "w") $stdout.sync = true retval = yield rescue Exception => e puts "[__ERROR__] Runtime error in deployment process: #{e.message}" $stdout.reopen orig_stdout $stderr.reopen orig_stderr raise e ensure $stdout.reopen orig_stdout $stderr.reopen orig_stderr end retval end
Now whenever I want to redirect the standard output and invoke the AppScale-Tools API I can do this.
redirect_standard_io(timestamp) do # Call AppScale-Tools API end
2. Hawkeye (API fidelity test suite for AppScale)
This is a Python based framework which makes a lot of RESTful invocations using the standard Python httplib API. I wanted to trace the HTTP requests and responses that are being exchanged during the execution of the framework and log them to a separate log file. Python httplib has a verbose mode which can be enabled by passing a special flag to the HTTPConnection class and it turns out this mode logs almost all the information I need. But unfortunately it logs all this information to the standard output of the program thus messing up the output I wanted to present to users. Therefore I needed a way to redirect the standard output for all httplib API calls. Here's how that problem was solved.
http_log = open('logs/http.log', 'a') original = sys.stdout sys.stdout = http_log try: # Invoke httplib finally: sys.stdout = original http_log.close()
No comments:
Post a Comment