Skip to main content

A pre-commit script to make log lines lazzier

Project description

Lazy log formatter

PyPI - Version GitHub Actions Workflow Status GitHub License PyPI - Python Version PyPI - Downloads pre-commit

A tool that automatically converts f-strings in Python logging calls into lazy logging calls (logger.info("x %s", var)) for consistency with Python documentation, improved performance and linting compliance.

Why this tool?

In Python, the recommended way to log variable data is to use format-string placeholders and pass values separately:

import logging
logging.warning('%s before you %s', 'Look', 'leap!')

This approach:

  • avoids unnecessary string formatting when a log message is not emitted,
  • is compatible with Python’s logging design and documentation,
  • prevents Pylint’s W1203: logging-fstring-interpolation warning,
  • avoids performance overhead from evaluating f-strings when logging is disabled for a certain level.

Features

  • Scans Python files for f-strings used in logging calls.
  • Provides an option to automatically convert f-strings in logging calls to lazy logging calls.
  • Can be integrated as a pre-commit hook to enforce logging best practices in codebases.

Installation

Install from PyPI:

pip install lazy-log-formatter

Pre-commit integration

Add the following to your .pre-commit-config.yaml:

- repo: https://github.com/dmar1n/lazy-log-formatter
  rev: 0.10.1
  hooks:
    - id: lazy-log-formatter
      args: ['--fix']

Command-line options

You can run the tool from the command line using the following options:

Option Description
--fix Converts f-strings in log calls to lazy logging syntax
--exclude [PATTERN...] Excludes files/directories matching one or more patterns
PATH [PATH...] One or more paths to scan (defaults to current directory)

Examples

Check all Python files in the current directory and subdirectories:

python -m lazy_log.cli .

Fix all Python files in the current directory and subdirectories:

python -m lazy_log.cli . --fix

Check all Python files in two directories:

python -m lazy_log.cli lazy_log/ tests/

Check specific files:

python -m lazy_log.cli lazy_log/cli.py tests/data/test.py

Exclude specific files or directories:

python -m lazy_log.cli tests/data --exclude "*.pyc" "__pycache__/*" 

Fix issues in all Python files in a directory:

python -m lazy_log.cli mydir --fix

Example transformations

Simple f-string

# Before
logger.info(f'Hello {name}')

# After
logger.info('Hello %s', name)

Multiple variables

# Before
logger.info(f'Hello {name} {surname}')

# After
logger.info('Hello %s %s', name, surname)

Class-based logging example

import logging
from datetime import datetime


def log_and_return_datetime():
    now = datetime.now()
    logging.info(f"Current datetime: {now}")
    return now


class DateTimeLogger:
    def __init__(self):
        self._logger = logging.getLogger(self.__class__.__name__)

    def log_datetime(self):
        now = datetime.now()
        self._logger.info(f"Current datetime: {now}")
        return now

After running the formatter without --fix, the output will be:

F-strings found in '...\tests\data\test.py':
 - F-string in logging call at ...\tests\data\test.py:8: f'Current datetime: {now}'
 - F-string in logging call at ...\tests\data\test.py:18: f'Current datetime: {now}'

After running the formatter with --fix, the output will be:

F-strings found and fixed in '...\tests\data\test.py'.

The transformed code will be:

import logging
from datetime import datetime


def log_and_return_datetime():
    now = datetime.now()
    logging.info("Current datetime: %s", now)
    return now


class DateTimeLogger:
    def __init__(self):
        self._logger = logging.getLogger(self.__class__.__name__)

    def log_datetime(self):
        now = datetime.now()
        self._logger.info("Current datetime: %s", now)
        return now

Notes

Code formatting with Black

When transforming code, the tool uses Black to reformat the modified files. If your project already uses Black, the changes produced by this tool will be consistent with Black’s formatting style.

Detection of log calls

The tool includes logic to detect logging calls based on the assumption that your logger instances follow common naming conventions (e.g., logger.info(...), log.info(...)). If a logger variable does not contain the substring "log" in its name, the tool will ignore it.

Other logging libraries

Only works with the native Python logging module. Other libraries, such as loguru, do not support lazy calls.

For loguru, see Lazy evaluation of expensive functions:

logger.opt(lazy=True).debug("If sink level <= DEBUG: {x}", x=lambda: expensive_function(2**64))

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

lazy_log_formatter-0.10.1.tar.gz (11.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

lazy_log_formatter-0.10.1-py3-none-any.whl (14.0 kB view details)

Uploaded Python 3

File details

Details for the file lazy_log_formatter-0.10.1.tar.gz.

File metadata

  • Download URL: lazy_log_formatter-0.10.1.tar.gz
  • Upload date:
  • Size: 11.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for lazy_log_formatter-0.10.1.tar.gz
Algorithm Hash digest
SHA256 d573860ae0455a7ceb9fd40b1d4999a11601ec731a79e18f6fe5a54374641c30
MD5 c2d143a3e00109c7f1ee5000b466b66f
BLAKE2b-256 3a174c64395565d448c9fb641d4e8fdeab356293fe5045ea1fb21dfb9d52b1d5

See more details on using hashes here.

Provenance

The following attestation bundles were made for lazy_log_formatter-0.10.1.tar.gz:

Publisher: release.yaml on dmar1n/lazy-log-formatter

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file lazy_log_formatter-0.10.1-py3-none-any.whl.

File metadata

File hashes

Hashes for lazy_log_formatter-0.10.1-py3-none-any.whl
Algorithm Hash digest
SHA256 ad084e1b425134efd51123080326e5fb1620f23645e26b0b6747c6ec744437df
MD5 1b3741ad3bdfcfcdacfb670484dc0452
BLAKE2b-256 a679ab973064483e4eddfd931b2281d7897ee7cf27700d1d260d90d64451ea38

See more details on using hashes here.

Provenance

The following attestation bundles were made for lazy_log_formatter-0.10.1-py3-none-any.whl:

Publisher: release.yaml on dmar1n/lazy-log-formatter

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page