Python Logging Configuration
Tags: python, logging, debug, config
Published: 2019-10-31 14:32:18

---
title: Python Logging Configuration
published: true
tags: python, logging, debug, config
canonical_url: https://tech.serhatteker.com/post/2019-07/python-logging-config/
---

No, please don't debug your program with `print`.

Python comes with a `logging` module in the standard library that provides a flexible framework for emitting log messages for Python programs.

The module provides some ways for applications to configure different log handlers and a way of routing log messages to these handlers. This allows for a highly flexible configuration that can deal with a lot of different use cases.

The logging functions are named after the level or severity of the events they are used to track. The standard levels and their applicability are described below:

| Level    | Level Code | When used|
| ---      | --- | ---                                                                                          |
| DEBUG    | 10  | Detailed information, typically of interest only when diagnosing problems.                   |
| INFO     | 20  | Confirmation that things are working as expected.                                            |
| WARNING  | 30  | An indication that something unexpected happened. The software is still working as expected. |
| ERROR    | 40  | Due to a more serious problem, the software has not been able to perform some function.      |
| CRITICAL | 50  | A serious error, indicating that the program itself may be unable to continue running.       |


For more details : [Python Foundation How To Logging](https://docs.python.org/3/howto/logging.html)

## Basic Logging
A very simple example for logging is:

```python
import logging


logging.info("Hello, World!")
logging.warning('Watch out!')
```

If you run this script you will see:

```sh
WARNING:root:Watch out!
```
The `INFO` message doesn’t appear because the default level is `WARNING`.

## Logging From Modules

However better approach will be using `__name__` with `DEBUG` logging level. Since `__name__` contains the full name of the current module, so this will simply work in any module.

```python
import logging

logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)


logger.info("Hello, World!")
logger.warning('Watch out!')
```

Output will be:

```sh
INFO:__main__:Hello, World!
WARNING:__main__:Watch out!
```

## Logging to a File
A very common situation is that of recording logging events in a file.


```python
import logging

logging.basicConfig(filename='example.log', level=logging.DEBUG)
logger = logging.getLogger(__name__)


logger.debug('This message should go to the log file')
logger.info('So should this')
logger.warning('And this, too')
```

If we open the file— "example.log", we should find the log messages:

```sh
DEBUG:__main__:This message should go to the log file
INFO:__main__:So should this
WARNING:__main__:And this, too
```

## Configuration via an INI file
This is the best approach for the meajority of cases;

Crate a file name `logging.ini`in the project root directory as below:

```ini
[loggers]
keys=root

[logger_root]
level=DEBUG
handlers=screen,file

[formatters]
keys=simple,verbose

[formatter_simple]
format=%(asctime)s [%(levelname)s] %(name)s: %(message)s

[formatter_verbose]
format=[%(asctime)s] %(levelname)s [%(filename)s %(name)s %(funcName)s (%(lineno)d)]: %(message)s

[handlers]
keys=file,screen

[handler_file]
class=handlers.TimedRotatingFileHandler
interval=midnight
backupCount=5
formatter=verbose
level=DEBUG
args=('debug.log',)

[handler_screen]
class=StreamHandler
formatter=simple
level=DEBUG
args=(sys.stdout,)
```

Or `curl` it:

```sh
$ curl -o logging.ini https://gist.githubusercontent.com/SerhatTeker/13d31a2159cd88c31a8cd464df115789/raw/81d9bbe850799e71b6095a6a43fa65dc1cf0e33c/logging.ini
```

Then configure it as below;

```python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import logging

from logging.config import fileConfig

fileConfig('logging.ini')
logger = logging.getLogger(__name__)


name = "YourName"

logger.info(f"Hello {name}")
logger.debug('This message should go to the log file')
logger.info('So should this')
logger.warning('And this, too')
```

If you run the script, the `sysout` will be:

```
2019-07-14 18:15:13,161 [INFO] __main__: Hello YourName
2019-07-14 18:15:13,161 [DEBUG] __main__: This message should go to the log file
2019-07-14 18:15:13,161 [INFO] __main__: So should this
2019-07-14 18:15:13,161 [WARNING] __main__: And this, too
```

And `debug.log` file should contain:

```
[2019-07-14 18:12:58,910] INFO [logging_ini.py __main__ <module> (14)]: Hello YourName
[2019-07-14 18:12:58,910] DEBUG [logging_ini.py __main__ <module> (15)]: This message should go to the log file
[2019-07-14 18:12:58,910] INFO [logging_ini.py __main__ <module> (16)]: So should this
[2019-07-14 18:12:58,910] WARNING [logging_ini.py __main__ <module> (17)]: And this, too
```

All done.