Skip to content
Open
Show file tree
Hide file tree
Changes from 7 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
17 changes: 17 additions & 0 deletions src/main/rules/GCI1066/GCI1066.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"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",
"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::results.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.