|
| 1 | + |
| 2 | +# The `logging` module |
| 3 | + |
| 4 | +Logging is means of tracking events that happen during software execution. |
| 5 | + |
| 6 | +The `logging` module provides a set of convenience functions that are meant to be used in differnet scenarios |
| 7 | + |
| 8 | + |
| 9 | + |
| 10 | +- **`logging.info()`**: Report events that occur during normal/expected operation of a program. |
| 11 | + |
| 12 | +- **`logging.debug()`**: Report detailed otuput for diagnostic purposes. |
| 13 | + |
| 14 | +- **`logging.warn()`**: Issue a warning due to a runtime event, use this if the situation is avoidable by the user to eliminate the warning. |
| 15 | + |
| 16 | +- **`logging.warning()`**: Issue a warning due to a runtime event, use this if the user cannnot do anything about the situation, the the event should be notted. |
| 17 | + |
| 18 | +- **`logging.error()`**: Report error without raising a python exception. |
| 19 | + |
| 20 | + |
| 21 | +By default, messages that are not printed (due to the logging level threshold) are simply discarded and are not stored anywhere. The logging module only processes messages that meet or exceed the configured logging level. |
| 22 | + |
| 23 | + |
| 24 | + |
| 25 | +### Example 1: |
| 26 | + |
| 27 | +In `ex1.py` one can find the following code |
| 28 | + |
| 29 | +```python |
| 30 | +import logging |
| 31 | +logging.warning('Warning: check this!') # will print a message to the console |
| 32 | +logging.info('Information logged') # will not print anything |
| 33 | +``` |
| 34 | + |
| 35 | +When running `ex1.py` the user will see: |
| 36 | + |
| 37 | +```python |
| 38 | +WARNING:root:Warning: check this! |
| 39 | +``` |
| 40 | + |
| 41 | +Note: Nothing about the `logging.info()` message is displayed.. |
| 42 | + |
| 43 | +Without configuration, only messages at WARNING level or higher will be displayed. The logging levels in order of increasing severity are: |
| 44 | + |
| 45 | +```python |
| 46 | +DEBUG (10) < INFO (20) < WARNING (30) < ERROR (40) < CRITICAL (50) |
| 47 | +``` |
| 48 | + |
| 49 | +Now in example 2 we will simply add `logging.basicConfig(level=logging.INFO)` to the code so that `INFO` messages are shown. |
| 50 | + |
| 51 | + |
| 52 | + |
| 53 | +### Example 2: Chaning logging displayed information |
| 54 | + |
| 55 | +One can change what is printed in the terminal when running a script updating the level of `logging` using `logging.basicConfig(level=logging.LEVEL)` |
| 56 | +where `LEVEL` can be a string from `[]`. |
| 57 | + |
| 58 | +For example, if we add `LEVEL=INFO`, as one can see in `ex2.py` |
| 59 | + |
| 60 | + |
| 61 | +```python |
| 62 | +import logging |
| 63 | + |
| 64 | +logging.basicConfig(level=logging.INFO) |
| 65 | + |
| 66 | +logging.warning('Warning: check this!') # will be printed because `logging.basicConfig(level=logging.INFO)` |
| 67 | +logging.info('Information logged') # will be printed |
| 68 | +``` |
| 69 | + |
| 70 | +When running `python ex2.py` the user will see: |
| 71 | + |
| 72 | +``` |
| 73 | +WARNING:root:Warning: check this! |
| 74 | +INFO:root:Information logged |
| 75 | +``` |
| 76 | + |
| 77 | +Which includes the `INFO` details that did not appear in `ex1.py`. |
| 78 | + |
| 79 | + |
| 80 | + |
| 81 | +### Example 3: Storing some logged information with a file handler with **`logging.FileHandler`** |
| 82 | + |
| 83 | + |
| 84 | +The code in `ex3.py` shows how to add a handler that stores to disk the logged messages. |
| 85 | + |
| 86 | +- To print in the console `console_handler = logging.StreamHandler()` is used. |
| 87 | + |
| 88 | +- To print in a file `file_handler = logging.FileHandler(log_file)` is used. |
| 89 | + |
| 90 | + |
| 91 | +```python |
| 92 | +import logging |
| 93 | + |
| 94 | +# Create and configure handlers |
| 95 | +console_handler = logging.StreamHandler() |
| 96 | +console_handler.setLevel(logging.WARNING) # Console shows only WARNING and above |
| 97 | + |
| 98 | +file_handler = logging.FileHandler('all_messages.log') |
| 99 | +file_handler.setLevel(logging.DEBUG) # File stores everything |
| 100 | + |
| 101 | +# Configure the root logger |
| 102 | +logging.basicConfig( |
| 103 | + level=logging.DEBUG, # Allow processing of all messages |
| 104 | + format='%(asctime)s - %(levelname)s - %(message)s', |
| 105 | + handlers=[console_handler, file_handler] |
| 106 | +) |
| 107 | + |
| 108 | +# Now test all levels |
| 109 | +logging.debug("Debug message - in file only") |
| 110 | +logging.info("Info message - in file only") |
| 111 | +logging.warning("Warning message - in both file and console") |
| 112 | +logging.error("Error message - in both file and console") |
| 113 | +``` |
| 114 | + |
| 115 | + |
| 116 | +After running this: |
| 117 | + |
| 118 | +- Console output will show only WARNING and ERROR messages |
| 119 | + |
| 120 | +- The file `ex3__all_messages.log` will contain ALL messages (DEBUG, INFO, WARNING, and ERROR) |
| 121 | + |
| 122 | + |
| 123 | + |
| 124 | + |
| 125 | +### Example 4: Storing some logged information with a file handler with **`logging.FileHandler`** and adding time into the logged filename |
| 126 | + |
| 127 | + |
| 128 | +Example `ex4.py` shows how to create a logger that stores the logged items to disk with **`logging.FileHandler`**. The example also has a logger that takes care of printing to the console (we can use more than one logger!). |
| 129 | + |
| 130 | +- To print in the console `console_handler = logging.StreamHandler()` is used. |
| 131 | + |
| 132 | +- To print in a file `file_handler = logging.FileHandler(log_file)` is used. |
| 133 | + |
| 134 | + |
| 135 | +```python |
| 136 | +import logging |
| 137 | +import os |
| 138 | +from datetime import datetime |
| 139 | + |
| 140 | +# Create 'logged_messages' directory if it doesn't exist |
| 141 | +log_dir = 'logged_messages' |
| 142 | +if not os.path.exists(log_dir): |
| 143 | + os.makedirs(log_dir) |
| 144 | + |
| 145 | +# Create log file path with timestamp |
| 146 | +timestamp = datetime.now().strftime('%Y_%m_%d_%H_%M_%S') |
| 147 | +log_file = os.path.join(log_dir, f'ex4__all_messages__{timestamp}.log') |
| 148 | + |
| 149 | +# Create and configure handlers |
| 150 | +console_handler = logging.StreamHandler() |
| 151 | +console_handler.setLevel(logging.WARNING) # Console shows only WARNING and above |
| 152 | + |
| 153 | +file_handler = logging.FileHandler(log_file) |
| 154 | +file_handler.setLevel(logging.INFO) # File stores INFO and above (changed from DEBUG) |
| 155 | + |
| 156 | +# Configure the root logger |
| 157 | +logging.basicConfig( |
| 158 | + level=logging.DEBUG, # Keep DEBUG as lowest level to allow all messages to be processed |
| 159 | + format='%(asctime)s - %(levelname)s - %(message)s', |
| 160 | + handlers=[console_handler, file_handler] |
| 161 | +) |
| 162 | + |
| 163 | +# Test all logging levels |
| 164 | +logging.debug("Debug message - won't be stored anywhere") |
| 165 | +logging.info("Info message - in file only") |
| 166 | +logging.warning("Warning message - in both file and console") |
| 167 | +logging.error("Error message - in both file and console") |
| 168 | +``` |
| 169 | + |
| 170 | + |
| 171 | +After running this: |
| 172 | + |
| 173 | +- Console output will show only WARNING and ERROR messages |
| 174 | + |
| 175 | +- The file `ex4__all_messages__2025_02_25_11_20_04.log` will contain messages INFO, WARNING, and ERROR. |
| 176 | + |
0 commit comments