|
3 | 3 | <h2>Why is this an issue?</h2> |
4 | 4 | <p>Python’s logging module has specific patterns that ensure correctness, performance, and maintainability. Violating these patterns can lead to |
5 | 5 | several problems:</p> |
6 | | -<h2>Eager String Formatting</h2> |
| 6 | +<h3>Eager String Formatting</h3> |
7 | 7 | <p>When you format strings before passing them to logging methods (using f-strings, <code>.format()</code>, <code>%</code> operator, or <code>+</code> |
8 | 8 | concatenation), Python performs the string formatting operation immediately, even if the log message won’t be output due to the current log level. |
9 | 9 | This wastes CPU cycles on string operations that may never be used.</p> |
10 | 10 | <p>The logging module supports lazy formatting by accepting format arguments as separate parameters. The formatting only occurs when the logging |
11 | 11 | framework confirms the message will actually be logged based on the configured log level.</p> |
12 | | -<h2>Deprecated Methods</h2> |
| 12 | +<h3>Deprecated Methods</h3> |
13 | 13 | <p>The <code>logging.warn()</code> and <code>logging.Logger.warn()</code> methods are deprecated. While they still function, they may be removed in |
14 | 14 | future Python versions. The recommended methods are <code>logging.warning()</code> and <code>logging.Logger.warning()</code>, which are functionally |
15 | 15 | equivalent.</p> |
16 | | -<h2>Attribute Name Collisions</h2> |
| 16 | +<h3>Attribute Name Collisions</h3> |
17 | 17 | <p>The logging module’s <code>extra</code> keyword argument allows passing additional values to be included in log records. However, if the keys in |
18 | 18 | the <code>extra</code> dictionary clash with built-in <code>LogRecord</code> attributes (such as 'name', 'msg', 'args', 'created', 'filename', |
19 | 19 | 'funcName', 'levelname', 'levelno', 'lineno', 'module', 'msecs', 'message', 'pathname', 'process', 'processName', 'relativeCreated', 'thread', |
20 | 20 | 'threadName'), a <code>KeyError</code> will be raised when the <code>LogRecord</code> is constructed, causing the logging statement to fail at |
21 | 21 | runtime.</p> |
22 | 22 | <h3>What is the potential impact?</h3> |
23 | | -<h2>Performance Degradation</h2> |
24 | | -<p>Eager string formatting can significantly impact application performance, especially in code paths with frequent logging statements. When log |
25 | | -levels are configured to filter out certain messages (e.g., DEBUG messages in production), the application still pays the cost of formatting strings |
26 | | -that will never be logged.</p> |
27 | | -<h2>Runtime Errors</h2> |
28 | | -<p>Attribute name collisions in the <code>extra</code> parameter raise <code>KeyError</code> exceptions, causing logging statements to fail |
29 | | -unexpectedly.</p> |
30 | | -<h2>Maintenance Issues</h2> |
31 | | -<p>Using deprecated methods creates technical debt. When these methods are eventually removed from Python, code using them will break. Additionally, |
32 | | -mixing deprecated and non-deprecated methods across a codebase creates inconsistency and confusion.</p> |
33 | | -<h2>Inconsistent Logging</h2> |
34 | | -<p>Eager formatting can lead to inconsistent behavior across different log handlers. When using lazy formatting with the <code>extra</code> parameter, |
35 | | -all handlers receive the same structured data and can format it consistently according to their configuration.</p> |
| 23 | +<p>Performance degradation: Eager string formatting can significantly impact application performance, especially in code paths with frequent logging |
| 24 | +statements. When log levels are configured to filter out certain messages (for example, DEBUG messages in production), the application still pays the |
| 25 | +cost of formatting strings that will never be logged.</p> |
| 26 | +<p>Runtime errors: Attribute name collisions in the <code>extra</code> parameter raise <code>KeyError</code> exceptions, causing logging statements to |
| 27 | +fail unexpectedly.</p> |
| 28 | +<p>Maintenance issues: Using deprecated methods creates technical debt. When these methods are eventually removed from Python, code using them will |
| 29 | +break. Additionally, mixing deprecated and non-deprecated methods across a codebase creates inconsistency and confusion.</p> |
| 30 | +<p>Inconsistent logging: Eager formatting can lead to inconsistent behavior across different log handlers. When using lazy formatting with the |
| 31 | +<code>extra</code> parameter, all handlers receive the same structured data and can format it consistently according to their configuration.</p> |
36 | 32 | <h2>How to fix it</h2> |
37 | 33 | <p>Use lazy formatting by passing format arguments as separate parameters to logging methods instead of formatting strings before the call. Replace |
38 | 34 | f-strings, <code>.format()</code>, <code>%</code> operator, and <code>+</code> concatenation with %-style placeholders and separate arguments.</p> |
|
0 commit comments