Differences

This shows you the differences between two versions of the page.

 tutorials:python_development_standards [2018/05/01 08:52]dgarcia [Python development standards] tutorials:python_development_standards [2019/06/24 22:26] (current)dgarcia [Logging] Both sides previous revision Previous revision 2019/06/24 22:26 dgarcia [Logging] 2019/06/24 22:16 dgarcia [Logging] 2019/06/24 21:50 dgarcia [Logging] 2019/06/24 21:49 dgarcia [Logging] 2019/06/24 21:46 dgarcia [Logging] 2019/06/24 21:42 dgarcia [Logging] 2019/06/24 19:46 dgarcia [Logging] 2019/06/24 19:45 dgarcia [Logging] Add color section2019/06/24 19:30 dgarcia [Logging] typos2019/06/16 23:52 dgarcia [Logging] 2019/06/16 23:50 dgarcia [Logging] 2019/06/16 23:39 dgarcia [Logging] add example2019/06/16 23:09 dgarcia [Tools] Explain logging levels2019/06/16 22:38 dgarcia [Issues] 2018/05/01 08:52 dgarcia [Python development standards] 2018/02/24 16:49 jperalta [Project Layout] Add an exmaple layout2018/02/24 13:01 jperalta [Python development standards] Add a note for readers to take a look at the linked docs2018/02/02 17:16 dgarcia [Progress tracking] 2018/02/02 17:16 dgarcia [Progress tracking] 2018/02/02 10:47 igomez [Tools] 2018/01/26 18:25 jperalta [Python3 Migration] Update python3 migrating procedure2018/01/26 18:24 jperalta [Python3 Migration] 2018/01/26 18:08 jperalta [Python3 Migration] add the progress tracker section2018/01/26 18:01 jperalta Add a python3 migration2018/01/26 17:40 jperalta Add a Project Layout section2018/01/26 17:23 jperalta created Next revision Previous revision 2019/06/24 22:26 dgarcia [Logging] 2019/06/24 22:16 dgarcia [Logging] 2019/06/24 21:50 dgarcia [Logging] 2019/06/24 21:49 dgarcia [Logging] 2019/06/24 21:46 dgarcia [Logging] 2019/06/24 21:42 dgarcia [Logging] 2019/06/24 19:46 dgarcia [Logging] 2019/06/24 19:45 dgarcia [Logging] Add color section2019/06/24 19:30 dgarcia [Logging] typos2019/06/16 23:52 dgarcia [Logging] 2019/06/16 23:50 dgarcia [Logging] 2019/06/16 23:39 dgarcia [Logging] add example2019/06/16 23:09 dgarcia [Tools] Explain logging levels2019/06/16 22:38 dgarcia [Issues] 2018/05/01 08:52 dgarcia [Python development standards] 2018/02/24 16:49 jperalta [Project Layout] Add an exmaple layout2018/02/24 13:01 jperalta [Python development standards] Add a note for readers to take a look at the linked docs2018/02/02 17:16 dgarcia [Progress tracking] 2018/02/02 17:16 dgarcia [Progress tracking] 2018/02/02 10:47 igomez [Tools] 2018/01/26 18:25 jperalta [Python3 Migration] Update python3 migrating procedure2018/01/26 18:24 jperalta [Python3 Migration] 2018/01/26 18:08 jperalta [Python3 Migration] add the progress tracker section2018/01/26 18:01 jperalta Add a python3 migration2018/01/26 17:40 jperalta Add a Project Layout section2018/01/26 17:23 jperalta created Line 19: Line 19: To install: To install: - <​code>​ + <​code ​bash> apt-get install flake8 apt-get install flake8 ​ Usage: Usage: - <​code>​ + <​code ​bash> flake8 path/​to/​code/​ flake8 path/​to/​code/​ ​ Line 32: Line 32: To install: To install: - <​code>​ + <​code ​bash> apt-get install yapf3 apt-get install yapf3 ​ Usage: Usage: - <​code>​ + <​code ​bash> yapf3 -ir path/​to/​code_dir yapf3 -ir path/​to/​code_dir ​ or or - <​code>​ + <​code ​bash> yapf3 -i path/​to/​code/​file.py yapf3 -i path/​to/​code/​file.py ​ + ==== Logging ==== + + Logging is a very important part of every software project, because it is the best way to deliver valuable information to our users. Logs are used to report errors, warnings, or just general information of how the program is executing. Good logs help us to discover why the program fails some times, they help us diagnose problems with our programs and help us plan strategies for improvement. It is crucial to maintain good and healthy logging practices so that you can increase the maintainability of your code. + + Python developers, knowing that logs are so important, have developed a module just for this: the [[https://​docs.python.org/​3.7/​library/​logging.html|Logging]] module. It is very important that we use this tool and **Not plain prints**. Also, take into consideration that logging helpers are going to be removed from ''​arcospyu''​ very soon. There are 5 default levels of logging, ordered from most important to less important are: ''​CRITICAL'',​ ''​Error'',​ ''​Warning'',​ ''​Info'',​ ''​Debug''​. + + === Logging levels === + + ''​CRITICAL''​ logs are messages that are shown to the user that report that something **very bad** happened. The program is not able to continue its execution after that failure and it may cause colateral damage (affect a database, a network, files...). + + ''​Error''​ logs are used when something goes wrong, but only a part is affected. Most failures can be logged as ''​Error''​. + + The ''​Warning''​ level is used to report errors from which your application is able to recover autonomously. Your system won't crash because of a ''​Warning'',​ but you are alerting the user that something is not OK. ''​Warning''​ logs can also be used in libraries when you want to tell your users that there are going to be some API changes. For example, if you want to change the name of a function, or if a method will be deprecated, the best thing to do is to create a ''​Warning''​ to announce that before doing the changes. + + ''​Info''​ logs are for general information,​ there is nothing going wrong with your program, but you want to inform the user about events that might be of interest. Messages like "The file has been opened",​ "​Connection established"​ are common ''​Info''​ messages. + + Finally ''​Debug''​ logs are used only during development. Let's say that you are not sure why your program is behaving in a certain way, and you believe that there might be a problem with the value of a certain variable. So you can create a ''​Debug''​ log to print that variable'​s value, to see if there really is a problem. + + When you define a logging level, you are telling Python which messages you want to receive. If you define a level //A//, you will receive all //A// messages and all messages with more priority. If you say that you want a ''​Error''​ level, so you will receive ''​Error''​ and ''​CRITICAL''​ logs only. If you define ''​Debug''​ level, you will receive all logs. For most cases you will want to set ''​Info''​ or ''​Warning''​ levels. + + === Loggers === + + In Python, the [[https://​docs.python.org/​3.7/​library/​logging.html#​logging.Logger|logger]] is the object in charge of handling your logs. This are the objects that you as a programmer will use to create the logs. In order to get a logger you just have to call the module level function [[https://​docs.python.org/​3.7/​library/​logging.html#​logging.getLogger|getLogger()]]. This function will return a logger object that you can use. Loggers have the ''​setLevel''​ method. This method sets the level of your logger as explained above. Then you have the ''​debug'',​ ''​info'',​ ''​warning'',​ ''​error'',​ and ''​critical''​ methods which create a message of their respective level. Note that if you set the ''​Warning''​ level, and create a ''​Debug''​ message, it won't be shown to the user. That is exactly the idea of defining these levels. + + The following is an example, + + + # myapp.py + import logging + import math + + def main(): + # Instead of printing the message send it to a file named '​filename'​ + # Set the INFO level + logging.basicConfig(filename="​myapp.log",​ level=logging.INFO) + ​ + # log some info + logging.info("​Started"​) + total = 0 + for number in range(-2, 100): + logging.debug(number) + try: + math.sqrt(number) + except ValueError: + # report that there was an error, but we handled it. + logging.warning("​Recovering from a negative sqrt") + number = 0 + + total += number + + if total < 0: + # If after adding possive numbers you got a negative, then there is something really wrong + logging.error("​Negative sum of positive numbers"​) + raise ValueError + ​ + # If everything went OK, report it + logging.info('​Finished'​) + + if __name__ == '​__main__':​ + main() + ​ + + + === Colors === + + It is also possible to add colors to your logs. For that we need to deal with a [[https://​docs.python.org/​3.7/​library/​logging.html#​handler-objects| Handler]] which is the object in charge of sending your logs to the apropiate destination. The default is to send them to the standard output, but you can also send them to a log file as we did in the example above. ​ + + If you want to add colors to your logs you will need a package named colorlog. You can install it from PyPi with: + + + pip install colorlog + ​ + + If you do not want to use ''​pip'',​ there are also [[https://​packages.debian.org/​jessie/​python-colorlog| Debian]], [[https://​launchpad.net/​python-colorlog| Ubuntu]], and [[https://​aur.archlinux.org/​packages/​python-colorlog/​| AUR]] packages. For example for Debian, you can install with: + + + sudo apt install python-colorlog python3-colorlog + ​ + + Here you have an example of how to use colorlog: + + + import colorlog + + # create the format object with colors. + formatter = colorlog.ColoredFormatter( + "​%(asctime)s%(log_color)s%(levelname)-8s%(reset)s %(blue)s%(message)s",​ + datefmt=None,​ + reset=True,​ + log_colors={ + '​DEBUG': ​   '​cyan',​ + '​INFO': ​    '​green',​ + '​WARNING': ​ '​yellow',​ + '​ERROR': ​   '​red',​ + '​CRITICAL':​ '​red,​bg_white',​ + }, + secondary_log_colors={},​ + style='​%'​ + ) + + # Create the handler + handler = colorlog.StreamHandler() + # Add the formatter we created earlier + handler.setFormatter(formatter) + + # Get a logger called "​example"​. (It is created if it doesn'​t exist) + logger = colorlog.getLogger("​example"​) + # Add the colored formatter to the logger we just created + logger.addHandler(handler) + + logger.error("​This is an error"​) + logger.warning("​This is a warning"​) + logger.info("​This is an info (that you will not see)") + logger.debug("​This a debug (that you will not see)") + ​ ===== Project Layout ===== ===== Project Layout ===== The recommended project layout for a python projected named <​code>​ptoject_name​ is as follows: The recommended project layout for a python projected named <​code>​ptoject_name​ is as follows: Line 111: Line 226: ==== Issues ==== ==== Issues ==== - Any problems encountered due to migration should be reported with a github ​issue on the corresponding repo. + Any problems encountered due to migration should be reported with a GitLab ​issue on the corresponding repo. ==== Progress tracking ==== ==== Progress tracking ====
• tutorials/python_development_standards.1525182737.txt.gz