Tuesday, July 20, 2010

Small program "logger" module in Python

I was sitting around and a thought crossed my mind, "How can I get the function name of a function that the trace is in?". I thought about it for a few minutes, and said to myself, "The stack must know". But how do I read the function names of the stack in Python??
For all these system level hacks, usually the sys module has something to offer, and this case was no exception. Here's how you can do it (using something called a "frame object"):


print sys._getframe().f_code.co_name

Another useful modification of the snippet above can give us the name of the function that is calling the current function. This is how it looks:


print sys._getframe(1).f_code.co_name

So as you saw, the argument of sys._getFrame() can take you up or down the stack as your need may be. This utility of the sys module is extremely useful while logging for errors. Almost every good programmer uses some kind of logging in his code. So far most of my logging was using independant file writes or console writes. With my newfound knowledge, all that was going to change, so I wrote myself a small, yet handy logger for my forthcoming projects. Here's the script.

I integrated this into one of the apps I was making and well, it was simply fantastic. Now I just piped out the log messages to this module and it would automatically determine which function was sending the messages. I wrote an app with a GUI in PyQt4, and as will all GUI apps, tracking events of widgets is extremely important in figuring out what went wrong during debugging. This is what the output of my new logger looked like:


Tue Jul 20 12:32:53 2010: <loadAppData()> Trying to load application data
Tue Jul 20 12:32:53 2010: <loadAppData()> Values picked up from appdata file. Interval:43; Dirs:[]
Tue Jul 20 12:32:53 2010: <loadAppData()> Application data loaded successfully
Tue Jul 20 12:32:56 2010: <btnAdd_Click()> Add button clicked
Tue Jul 20 12:33:12 2010: <saveAppData()> Trying to save application data
Tue Jul 20 12:33:12 2010: <saveAppData()> Application data saved successfully!
Tue Jul 20 12:33:26 2010: <trayIcon_Click()> Tray icon clicked. Current visible status:True
Tue Jul 20 12:33:26 2010: <trayIcon_Click()> Tray icon event complete. Current visible status:False
Tue Jul 20 12:33:30 2010: <trayIcon_Click()> Tray icon clicked. Current visible status:False
Tue Jul 20 12:33:30 2010: <trayIcon_Click()> Tray icon event complete. Current visible status:True
Tue Jul 20 12:33:35 2010: <closeEvent()> Form close event raised
Tue Jul 20 12:33:35 2010: <saveAppData()> Trying to save application data
Tue Jul 20 12:33:35 2010: <saveAppData()> Application data saved successfully!
Tue Jul 20 12:33:35 2010: <closeEvent()> Program is exiting.
This is so neat :D

3 comments:

  1. Excellent post! I have only very recently found your blog. I am a student just being introduced to Python programming. I came across your blog from a forum that you participate in. I have been very impressed with your presentation of material here! I am becoming a regular reader!

    ReplyDelete
  2. Nice to know that my exploits are proving to be useful. Where are you from? Feel free to mail me if you ever need any kind of guidance.

    ReplyDelete
  3. I am from north Alabama. I am an ex-component level repair technician, now a student at ITT Tech. Python is the first programming course I have ever taken (I had only built some simple batch files prior to this).

    Thanks for the offer of individual help by e-mail, I hope to not need to worry you so. Although I have of course struggled with some of the challenges I have been assigned, so far I have only asked for suggestions twice by the net to some forums I have signed on to.

    ReplyDelete