I don't. Not very often, anyway. When I do, I often delete the logging calls as soon as the code is more or less working. The biggest reason is the ugliness.
def days_ago (ndays):
logging.info('days_ago called with arg %s' % str(ndays))
logging.info('arg type %s' % type(ndays))
ndays = int(ndays)
logging.info('argument converted to integer %d' % ndays)
current_date = datetime.datetime.now()
logging.info('current date is %s' % str(current_date))
result = current_date - datetime.timedelta(ndays)
except ValueError, e:
logging.error('Error converting ndays to integer:')
result = None
logging.info('returning from days_ago: %s' % str(result))
EWWWWWW! That is ugly! It completely disrupts the comfortable reading of the code. It buries the actual purpose and actions of the function under a steaming heap of chatter. It offends everything that I value in beauty and readability. What to do?
One solution might be a code editor that would toggle the visibility of all logging calls in a program. You could leave them invisible most of the time, and only look at the logging statements when you have a specific reason to. I can see two problems with that, though.
- The logging calls themselves could get out of synch with the functioning code. This could be partially addressed by having logging calls become visible automatically whenever code adjacent to them is changed.
- This would create code which is readable and beautiful in my editor, but ugly when somebody else tries to read it. Perhaps if we cooked up a convention whereby a header comment could define the suggested hiding of logging calls for each program, and most editors could be trained to recognize and respect these suggestions?
EDIT: Gary Bernhardt tweets, "Anything that you want your editor to to be able to hide (comments, setters/getters, logging) shouldn't exist".
An interesting idea... how to eliminate logging? A good logging decorator could log arguments, return values, and error messages to any decorated function - and that level of information could suffice, if the functions are very fine-grained. Having to write fine-grained functions is the sort of constraint that might improve programming style, too, much the way unit testing demands well-defined functions. I think I'll try this philosophy and see if I can make it work.
It's not much help for the PL/SQL side of things, though. I'm trying to imagine if there's some way to make an analog to Python's decorators in PL/SQL.