Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Added rule GCI1066: For logging format, prefer using `%s` with kwargs instead of builtin formatter `"".format()` or `f""`, that way message formatting will be deferred until it cannot be avoided.

### Changed

- Correction of various typos in rules documentations
Expand Down
2 changes: 2 additions & 0 deletions RULES.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ Some are applicable for different technologies.
| | Resize images browser-side | Do not resize images using the HEIGHT and WIDTH attributes of the HTML code. This approach requires transferring these images to their original size, wasting bandwidth and CPU cycles. | [cnumr best practices (3rd edition) BP_034](https://github.com/cnumr/best-practices/blob/main/chapters/BP_034_fr.md) | 🚫 | 🚫 | 🚧 | 🚫 | 🚫 | 🚫 | 🚀 |
| | Modify the DOM when traversing it | Modifying the DOM (Document Object Model) as you traverse it can lead to situations where the loop becomes very resource-intensive, especially CPU cycles. | [cnumr best practices (3rd edition) BP_041](https://github.com/cnumr/best-practices/blob/main/chapters/BP_041_fr.md) | 🚫 | 🚫 | 🚧 | 🚫 | 🚫 | 🚫 | 🚫 |
| | Edit DOM elements to make it invisible | When an element of the Document Object Model (DOM) needs to be modified by several properties, each change in style or content will generate a repaint or reflow. | [cnumr best practices (3rd edition) BP_042](https://github.com/cnumr/best-practices/blob/main/chapters/BP_042_fr.md) | 🚫 | 🚫 | 🚀 | 🚫 | 🚫 | 🚫 | 🚫 |
| GCI1066 | Logging format interpolation | When logging with formatted string, prefer using `%s` with kwargs, which will be deferred until it cannot be avoided, instead of immediate formatter `.format()` of `f""`. | | 🚫 | 🚫 | 🚫 | 🚀 | 🚫 | 🚫 | 🚫 |


## Rules to be reworked / measured / clarified

Expand Down
18 changes: 18 additions & 0 deletions src/main/rules/GCI1066/GCI1066.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"title": "Logging Format Interpolation - Avoid using immediate string formatter in logging calls.",
"type": "CODE_SMELL",
"status": "ready",
"remediation": {
"func": "Constant\/Issue",
"constantCost": "5min"
},
"tags": [
"creedengo",
"eco-design",
"performance",
"python",
"logging",
"format"
],
"defaultSeverity": "Minor"
}
51 changes: 51 additions & 0 deletions src/main/rules/GCI1066/python/GCI1066.asciidoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
When logging with formatted string, prefer using `%s` and logging kwargs which will be deferred until it cannot be avoided, instead of immediate `.format()` of `f""` interpolation.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a new test with codeCarbon to check these to uses cases :

  • one use case where "debug" mode is enabled
  • one use case where "debug" mode is disabled


== Non Compliant Code Example

[source,python]
----
import logging
logging.basicConfig(level=logging.INFO)
name = "world"
logging.debug(f"hello {world}") # Non Compliant: the replacement will be done immediately but will not be printed because current level is INFO
----

== Compliant Solution

[source,python]
----
import logging
logging.basicConfig(level=logging.INFO)
name = "world"
logging.debug("hello %s", name) # Compliant: the replacement will be avoided by logging module because it is not necessary
----


== Relevance Analysis

This rule is relevant to logging formatting. Using logging kwargs is more efficient than immediate builtin formatting.

=== Configuration

* Processor: Intel(R) Core(TM) i5-2520M CPU @ 2.50GHz, 4 cores
* RAM: 8 GB
* CO2 Emissions Measurement: Using https://mlco2.github.io/codecarbon/[CodeCarbon]

=== Context

Two approaches were benchmarked:
- *Non-compliant:* Using logging with `.format()`
- *Compliant:* Using logging with `%s` and kwargs

=== Impact Analysis

image::result.png[]

== Conclusion

Replacing `f""` and `"".format()` with `%s` and logging kwargs permits to defer template replacement when the log is not displayed.

== References

- https://docs.python.org/3/howto/logging.html#optimization
- https://pylint.pycqa.org/en/latest/user_guide/messages/warning/logging-format-interpolation.html
Binary file added src/main/rules/GCI1066/python/result.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.