lundi 12 mai 2014

Programmatically listen for log message sent to a Python/Django logger


Vote count:

0




Being relatively new to both Python and Django I was not sure how best to go about solving my issue. I did eventually come up with a solution but it seems a bit makeshift, or at least, methods are not being used for purpose. Not being able to find anything much online about the subject I thought I'd post this here Q-A style, so that there is at least an answer on SO, and to see if anyone else has an improved or more "pythonic" approach.


My problem is that I'm writing tests for code that I do not have permissions to modify, and the code itself only outputs responses to the log — so the approach needs to be something that can step in and listen to the log messages and assert they are as expected.



import logging

logger = logging.getLogger('shrubbery')

# do stuff
other_code_that_cant_be_altered_that_will_trigger_log_messages()

# assert that the log messages are as we expected
assert_messages_be_good_and_expected()


asked 26 secs ago

pebbl

8,379

1 Answer



Vote count:

0




So after reading through a number of pages, I found that there were a few logging functions that could be useful to me. I especially liked the descriptions for addHandler, addFilter. Not quite as informative as some of the rest, nor more informative than the naming convention of the functions themselves. However, I do not maintain any public documentation, so can not complain.



  1. http://ift.tt/OVFgbg

  2. http://ift.tt/1iKhZ7Y

  3. http://ift.tt/1slAdhc

  4. http://ift.tt/1iKhZ83


After a bit of trial and error I put the following together. My first attempt was with addHandler but this seemed a lot more involved, and lacking in documentation, than addFilter. So basically the code sets up a fake logging filter, which listens to every log message, and appends them to an array further up the scope. It always returns true, so log messages should never be lost. I'm not sure if this is optimal, or if there is a better more semantic way, but it does indeed work.



import logging

messages = []
logger = logging.getLogger('shrubbery')

# use a filter to listen out for the log
class ListenFilter(logging.Filter):
def filter(self, record):
messages.append(record.getMessage())
return True

# plug our filter listener in
f = ListenFilter()
logger.addFilter(f)

# do stuff
other_code_that_cant_be_altered_that_will_trigger_log_messages()

# do more stuff, this time reading messages
assert_messages_be_good_and_expected(messages)

# tidy up
logger.removeFilter(f)


answered 26 secs ago

pebbl

8,379




Aucun commentaire:

Enregistrer un commentaire