Ever spent ten minutes or more trying to find where some logging is going to? Ever wanted a simple way to log from multiple processes or servers? Today my pair and I were having a bad logging day, and having had bad logging days before, I thought I'd do something about it. I wrote a simple http server (based on a previous article) that logs whatever you hit the web server with (here I'm calling it the "url logger server").
The url logger server makes logging for debugging purposes simple. It's not meant for "proper" logging, but as a simple and quick way to add logging for debugging for things where it's difficult to get access to files (or just to work out where they end up!) or where there are a variety of places you want to put logging (e.g. several different servers, processes or code in multiple languages). Please let me know if there's something that already does this. My pair and I found the url logger server useful for our purposes, so I've published it here for others (with permission from my lovely client).
This is how you log to the url logger server from Java. Most languages can do the equivalent quite easily. In this example I'm running the url logger server on the same machine that this code is running on, but there's no need - it could be anywhere on the network.
private void someMethod() {
log("this is a log message");
}
private void log(String message) {
try {
new URL("http://localhost:8010/log/"+URLEncoder.encode(message)).getContent();
} catch (MalformedURLException e) {
} catch (IOException e) {
}
}
In the example above, a browser pointed at "http://localhost:8010/" will show:
this is a log message
Hitting "http://localhost:8010/clear" will clear the log.
This can be run by jython or python.
import BaseHTTPServer, urllib, os.path
class DBHandler(BaseHTTPServer.BaseHTTPRequestHandler):
def append(self, message):
f=open('log','a')
f.write(urllib.unquote(message).replace('+',' ')+'\n')
f.close()
def clear(self):
open('log','w').close()
def read(self):
if not os.path.exists('log'):
return ""
return open('log').read()
def do_GET(self):
path = urllib.unquote(self.path[1:]).split('/')
self.send_response(200)
self.send_header("Content-type", "text/html")
self.end_headers()
if path[0] == 'log':
self.append('/'.join(path[1:]))
else:
if path[0] == 'clear':
self.clear()
else:
html = "<html><head></head><body><pre>"
html = html + self.read()
html = html + "< /pre></body></html>"
self.wfile.write(html)
server_address = ('', 8010)
httpd = BaseHTTPServer.HTTPServer(server_address, DBHandler)
httpd.serve_forever()
Posted by ivan at December 12, 2006 10:18 PM
I read this entry a while back and it seemed like a useful tool but I couldn't see where I might use it.
Recently I've been re-engineering an Ajax application which has been quite frustrating. One of the reasons it has been so frustrating is because of the time spent trying to fix bugs. So, I set up server-side logging to more clearly see the interaction between client and server - this helped. But more bugs appeared - some hidden away in Apache error logs - so I now tailed this log - this helped some more.
But I was still spending a lot of time looking for the source of bugs and often missing them in various logs & outputs. I realized a lot of grief came from the distribution of output for the project - I had server-side tests, client-side tests, server-side logging and the apache logs all in different places. So I came to the realization that I need all my output in one place - a single log! Then I realized that I'd already seen such a thing elsewhere.
Posted by: Chris Clarke at January 2, 2007 5:56 AM