Some people complained about my last logging article, wondering if it was even necessary since the docs and Doug Hellman have already written on the topic. I sometimes wonder why I write on these topics too, but usually when I do, I get lots of readers. In this case, I’ve gotten almost 10,000 hits just on that one article in a week, so I guess there must still be room for me to write on topics like this. I received a couple of comments mentioned alternate logging libraries. One of these was lggr by Peter Downs. We’ll take a quick look at the project and see how it shapes up. The documentation is pretty shallow at this point, but let’s see what we can do.
As you might expect, you’ll need to download or checkout the project from Github. Once you have it, you can use the usual command to install it:
python setup.py install
Of course, you can also use easy_install or pip to install it after downloading too and I think there may even be a way to use pip with a github URL directly too.
Writing a Simple Lggr
Now let’s dig into a bit of code and see how this package works. Here’s a really simple example:
import lggr log = lggr.Lggr() # add handler to write to stdout log.add(log.ERROR, lggr.Printer()) # add handler to write to file f = open("sample.log", "a") log.add(log.INFO, lggr.Printer(f)) log.info("This is an informational message") try: print (1/0) except ZeroDivisionError: log.error("ERROR: You can't divide by zero!") log.close()
This code will create two handlers. One to output error messages to stdout and the other to output informational messages to a file. Then we write out a message to each. Sadly, lggr doesn’t appear to provide the traceback information that Python’s standard logging module provides when you log an error message with it. In the logging module, it will actually be a full traceback. On the other hand, lggr’s code is pretty clean and easy to follow. The lggr package also provides the following loggers (or coroutines, as the author likes to call them):
- StderrPrinter – writes to stderr
- SocketWriter(host, port) – writes to a network socket
- Emailer(recipients) – sends emails
- GMailer(recipients, gmail_username, gmail_password, subject=”optional”) also sends emails, but does it from Gmail
The Emailer one may not work if you’re on a corporate network as that port may be blocked. At least, that appeared to be my issue when I tried it. You may be luckier depending on how much your company blocks. Anyway, the lggr package also provides almost two dozen logging variables that you can log, such as threadname, codecontext, stack_info, filename, etc. I personally can see where this would be really handy to have.
I don’t see anything about rotating file handlers, but otherwise this project seems to be a pretty easy-to-use logging package. If you’re looking for something with a slightly lower learning curve than Python’s logging module, then this package may be what you want.
2 thoughts on “Python logging with lggr”
I like the python logging, but…sometime python will throw a stacktrace and the location of this is not captured in the logging. This becomes difficult to locate. For example…I will see at the end of my program ” ‘NoneType’ object is not iterable “. Thus I know something threw and error but it not clear from the logging. Do you have any suggestions on capture this type of information/stack trace? thanks
You are probably iterating in a loop of some kind and whatever is being passed into it isn’t an iterable. Thus, you’ll want to wrap that loop in a try/except and in the except portion you can use your logger’s exception method to catch the exception and log it.
Comments are closed.