[Python Tips] Beyond print()

in #utopian-io7 years ago

Beyond print()

print() is a great quick and dirty way to log to the console in python. Even senior developers will use print() all the time. For anything more than a quick app you should be using a real logging module.

There is nothing print() can do that logging can't do better.

Python already includes a fantastic logging module built-in!

Why use the logging module?

The logging module allows you to set different level of logging based on the event you are logging. If you use an external log collection tool this becomes invaluable. Syslog and Papertrail are two great examples of logging services that functionality depends on using intelligent logging levels throughout your code.

Want to be notified automatically when there is an error in your code?
No need to write any code to do this, just use CRITICAL, WARNING, ERROR log levels in your code and tools like Papertrail can automatically alert you without changes to your code.

Using the logging module allows you to use different log levels for events and only display what you are interested in. If down the road you need to troubleshoot something, you can turn on DEBUG level logging. If done properly, you will already have DEBUG level logging events in your code base.

Logging levels

  • CRITICAL
  • ERROR
  • WARNING
  • INFO
  • DEBUG
  • NOTSET

While coding, you can insert DEBUG level events for areas of code that might be important to troubleshoot down the line but hide these messages by setting the log level to INFO or higher.

Many modules use python's logging module. This will allow you to get log events from other modules that may be critical to troubleshooting.

How to use logging in your application

I am not going to cover the entire logging module, this is an introduction to show how easy it is to use and why you should be using the logging module instead of print().

If you want more information I recommend going through the documentation for the logging module.

Before you can use the logging module, you need to import it.

import logging

After importing the logging module, you need to configure it. There are three ways to configure the logging module:

  • Ini File
  • Dictionary
  • Code

I am only going to cover using code, the other two methods are easy to use and you can find details in the above documentation.

The most basic logging configuration

You are able to start logging with only one line of setup code.

logging.basicConfig(level=logging.INFO)

At this point, you can start logging.

logging.info('Connected to super cool database')
logging.debug('Connection failed to super cool database')

Quiz: What will be displayed?

Only the first line will be displayed, when we set up the logger we set the default logging level to be INFO and DEBUG level events will not be displayed.

Logger basic config

In many applications, you will use the basicConfig() function to further configure the logging module. This is typically used to customize the format of log entries.

import logging

logging.basicConfig(format='%(process)d-%(levelname)s-%(message)s')

Use the logging module documentation if you need a more complex formatting setup.

Getting a logger

Up to now, we have been using the root logger. It is common for an application to have one or more custom loggers.

Getting a custom logger is as simple as specifying the name.

logger = logging.getLogger('my_logger')

It is very common to use the __name__ variable to create a custom logger. This will create a new logger with the name of the module.

``logger = logging.getLogger('name')`

When using a custom logger, you need to use this object to log events or you will be using the root logger again.

logger = logging.getLogger('__name__')
logger.info('This is using my custom logger')
logging.info('This is using the root logger')

Handlers

While the default logging interface works for most things, there are situations you will want to use log handlers.

Log handlers allow you to log to multiple locations at once, log to email, or even a stream each with their own default levels.

import logging

logger = logging.getLogger('__name__')

log_stream_handler = logging.StreamHandler()
log_file_handler = logging.FileHanlder('log.txt')

log_stream_handler.setLevel(logging.INFO)
log_file_handler.setLevel(logging.DEBUG)

logger.addHandler(log_stream_handler)
logger.addHanlder(log_file_handler)

Any log events you create using the logger object will be written to the console and added to the log file. The log file will capture all log events down to DEBUG where the console will only show INFO level events.

Conclusion

This covers most of the core functionality of the logging module, but it isn't everything. Remember to check the documentation if you have any questions. Most larger applications you are going to want to have console and file logging with different levels and custom formatting.

You are also going to want the end user to be able to configure logging settings from a configuration file. While the logging module has the ability to load settings from a configuration file, you will likely already have a configuration file that you will want to specify log level there and just create the logging objects from your own custom configuration object.

My Python Tips Series

Sort:  

I thank you for your contribution. Here are my thoughts. Note that, my thoughts are my personal ideas on your post and they are not directly related to the review and scoring unlike the answers I gave in the questionnaire;

  • Structure

    • I appreciate the structure of your post. It is well done; organizes the post and makes it easier to read.
  • Language

    • I personally think the usage of the first person reduces the efficiency of the post. I advise you to consider using less first person. Still, this is a personal thought, don't get me wrong! :)
  • Content

    • It is a simple but good tutorial. Normally I don't like simple, short tutorials, because they are a lot easier to write than the others; which forces me to state it specifically. But I liked the "trick". When people check out the documentation, they usually don't check obvious things until they really need those specific things. So, when someone wants to debug/logging, they just use print if they don't need specific ways of logging. For example, I always used print for debugging. That's why this post is a "trick". It shows something useful that you don't know and harder to acquire. Thanks, waiting for the next one!

Your contribution has been evaluated according to Utopian policies and guidelines, as well as a predefined set of questions pertaining to the category.

To view those questions and the relevant answers related to your post, click here.


Need help? Write a ticket on https://support.utopian.io/.
Chat with us on Discord.
[utopian-moderator]

By the way, I did notice that you are a Firefly fan! Wow, I've never seen anyone on Steem before. :P

Thank you for your review, @yokunjon! Keep up the good work!

I use python too.
While dealing with lists , I use pprint () which is pretty print to display in an organised way.

Posted using Partiko Android

pprint() is very handy for lists and dictionaries, but that's typically something you would do when debugging and not production.


This post was shared in the Curation Collective Discord community for curators, and upvoted and resteemed by the @c-squared community account after manual review.
@c-squared runs a community witness. Please consider using one of your witness votes on us here

I remember years ago trying to do research on logging methods in Python and being surprised how difficult it seemed to find info about it. A lot really do just use print. That really doesn't cut it except in tiny quickly written programs.

Hi @themarkymark!

Your post was upvoted by @steem-ua, new Steem dApp, using UserAuthority for algorithmic post curation!
Your UA account score is currently 8.053 which ranks you at #26 across all Steem accounts.
Your rank has improved 1 places in the last three days (old rank 27).

In our last Algorithmic Curation Round, consisting of 218 contributions, your post is ranked at #1. Congratulations!

Evaluation of your UA score:
  • Your follower network is great!
  • The readers appreciate your great work!
  • Good user engagement!

Feel free to join our @steem-ua Discord server

Hey, @themarkymark!

Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!

Get higher incentives and support Utopian.io!
Simply set @utopian.pay as a 5% (or higher) payout beneficiary on your contribution post (via SteemPlus or Steeditor).

Want to chat? Join us on Discord https://discord.gg/h52nFrV.

Vote for Utopian Witness!