A Python logging linter that enforces best practices
Why?
Production incidents are harder to debug when:
- Exception logs lack stack traces (
exc_info=True) - Hot loops spam logs, degrading performance
- Inconsistent logging causes time delay in parsing logs
- Complementary: Use with
structlog,loguru— not instead of them
Installation
uv pip install pfly
Usage
pfly path/to/code
pfly path/to/code --config=pfly.yml
Policies
| Code | Policy | Description |
|---|---|---|
| LY001 | exception_exc_info |
Enforces exc_info=True for logs in exception handlers to capture stack traces in a consistent format |
| LY002 | log_loop |
Prevents unconditional logging in hot loops (allows conditional logging) |
| LY003 | consistent_kv |
Ensures log variables follow key-value format for consistent parsing |
Configuration
Create a pfly.yml:
logger_names: [logger, logging, log]
exception_exc_info:
levels: [error]
severity: fail
log_loop:
levels: [info, debug]
severity: fail
Examples
LY001: Missing exc_info=True
# Fail
try:
connect_db()
except Exception:
logger.error("Connection failed") # No stack trace!
# Pass
try:
connect_db()
except Exception:
logger.error("Connection failed", exc_info=True)
LY002: Logging in hot loops
# Fail
for user in users:
logger.info(f"Processing {user}") # Logs every iteration
# Pass
for i, user in enumerate(users):
if i % 100 == 0:
logger.info(f"Progress: {i}/{len(users)}") # Conditional logging
LY003: Inconsistent key-value logging
# Fail
logger.info(f"User {user}") # Missing key
logger.info("User %s", user) # Placeholder without key
# Pass
logger.info(f"User user={user}") # Key-value pair
logger.info("User user=%s", user) # Key=placeholder format
License
Apache
Metadata
Release files for pfly 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| pfly-0.1.1.tar.gz | 1.3 MB | Without provenance | Details for pfly-0.1.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| pfly-0.1.1-py3-none-any.whl | Python 3 | none | any | Details for pfly-0.1.1-py3-none-any.whl |
Total release size: 1.4 MB
Release files / pfly-0.1.1.tar.gz
| Download URL | pfly-0.1.1.tar.gz |
|---|---|
| Size | 1.3 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2eddccb61b9c16c6a5ebff2dc7a8106bac5c39497ca84cb42a5c6ba713aeb1c5
|
|
BLAKE2b-256 checksum How to use checksums |
88affd15acf9607602e185bc07caed8c6cd2b097655175e5cf22ac24dbdc6035
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.8.22
|
Release files / pfly-0.1.1-py3-none-any.whl
| Download URL | pfly-0.1.1-py3-none-any.whl |
|---|---|
| Size | 15.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
760369b1fb55d8c5089bc892fb9f772026742cdc627aeeb39b5e93d096ab9b84
|
|
BLAKE2b-256 checksum How to use checksums |
384551a9a3fd220ad84681b0184dfd6befc7331d8e329497dc0946a1c8d80fc6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.8.22
|
Security for pfly 0.1.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.