Logorator
A powerful decorator-based logging library for Python with support for both synchronous and asynchronous functions, featuring automatic depth tracking, log levels, and smart argument formatting.
Features
- Simple decorator-based logging for function calls
- Full async support for both synchronous and asynchronous functions
- Automatic depth tracking with visual indentation for nested calls
- Log levels (DEBUG, INFO, WARNING, ERROR) with color coding
- Smart argument formatting - shows parameter names and handles objects intelligently
- Argument filtering - include or exclude specific parameters
- Function execution time measurement
- ANSI color-coded output for better readability
- Optional file output with automatic color stripping
- Configurable output formats (normal and short modes)
- Custom notes for inline logging
- Works with classes - instance methods, class methods, static methods
Installation
pip install logorator
Quick Start
from logorator import Logger
@Logger()
def add(a, b):
return a + b
result = add(3, 5)
Output:
Running add
a: 3
b: 5
Finished add Time elapsed: 0.15 ms
Basic Usage
Synchronous Functions
from logorator import Logger
@Logger()
def calculate(x, y, operation="add"):
if operation == "add":
return x + y
return x - y
result = calculate(10, 5, operation="subtract")
Output:
Running calculate
x: 10
y: 5
operation: subtract
Finished calculate Time elapsed: 0.12 ms
Asynchronous Functions
from logorator import Logger
import asyncio
@Logger()
async def fetch_data(url):
await asyncio.sleep(1)
return f"Data from {url}"
asyncio.run(fetch_data("https://example.com"))
Output:
Running async fetch_data
url: https://example.com
Finished async fetch_data (https://example.com) Time elapsed: 1,002.34 ms
Nested Function Calls
Depth tracking is enabled by default, showing call hierarchy with indentation:
@Logger()
def outer(x):
return inner(x * 2)
@Logger()
def inner(y):
return y + 10
outer(5)
Output:
Running outer
x: 5
Running inner
y: 10
Finished inner Time elapsed: 0.08 ms
Finished outer Time elapsed: 0.25 ms
Advanced Features
Log Levels
Control logging verbosity with log levels and color coding:
from logorator import Logger, LogLevel
@Logger(level=LogLevel.DEBUG) # Cyan - detailed info
def debug_function():
pass
@Logger(level=LogLevel.INFO) # Green - general info (default)
def info_function():
pass
@Logger(level=LogLevel.WARNING) # Yellow - warnings
def warning_function():
pass
@Logger(level=LogLevel.ERROR) # Red - errors
def error_function():
pass
# Set global minimum level
Logger.set_level(LogLevel.WARNING) # Only WARNING and ERROR will show
Argument Filtering
Exclude sensitive or verbose arguments:
@Logger(exclude_args=["password", "token"])
def login(username, password, token):
# password and token won't be logged
pass
@Logger(exclude_args=["self"]) # Common for class methods
def process(self, data):
pass
Include only specific arguments:
@Logger(include_args=["user_id", "action"])
def audit_log(user_id, action, timestamp, metadata, session):
# Only user_id and action will be logged
pass
Working with Classes
Logger works seamlessly with all types of class methods:
class DataProcessor:
def __init__(self, name):
self.name = name
@Logger(exclude_args=["self"]) # Hide self for cleaner output
def process(self, data):
return self._transform(data)
@Logger(exclude_args=["self"])
def _transform(self, data):
return [x * 2 for x in data]
@classmethod
@Logger()
def create(cls, name):
return cls(name)
@staticmethod
@Logger()
def validate(value):
return value > 0
Output:
Running process
data: [1, 2, 3]
Running _transform
data: [1, 2, 3]
Finished _transform Time elapsed: 0.05 ms
Finished process Time elapsed: 0.15 ms
Custom Object Formatting
Logger intelligently formats objects:
class User:
def __init__(self, name):
self.name = name
# Without __str__: shows "User"
# With __str__: shows your custom format
def __str__(self):
return f"User({self.name})"
@Logger()
def greet(user):
return f"Hello, {user.name}"
greet(User("Alice"))
Output:
Running greet
user: User(Alice)
Finished greet Time elapsed: 0.08 ms
File Output
Redirect logs to a file (ANSI colors are automatically stripped):
Logger.set_output("logs/application.log")
@Logger()
def main():
# All logs go to file
pass
# Switch back to console
Logger.set_output(None)
Custom Notes
Insert custom log messages during execution:
@Logger()
def process_data(data):
Logger.note("Starting validation")
# validation logic
Logger.note("Validation complete")
return data
Short Mode
Compact tab-separated output:
@Logger(mode="short")
def calculate(a, b):
return a + b
Disable Depth Tracking
@Logger(show_depth=False)
def flat_logging():
pass
Custom Function Names
@Logger(override_function_name="DatabaseConnect")
async def connect_to_db(url):
pass
Global Silent Mode
import os
# Disable all logging in production
if os.environ.get("ENVIRONMENT") == "production":
Logger.set_silent(True)
API Reference
Logger Class
Constructor Parameters
Logger(
silent=None, # Override global silent mode
mode="normal", # "normal" or "short"
override_function_name=None, # Custom name in logs
level=LogLevel.INFO, # Log level (DEBUG, INFO, WARNING, ERROR)
include_args=None, # List of args to include
exclude_args=None, # List of args to exclude
show_depth=True # Enable depth tracking (default: True)
)
Class Methods
Logger.set_silent(silent=True)
Enable or disable all logging globally.
Logger.set_level(level)
Set the minimum log level to display.
Logger.set_level(LogLevel.WARNING) # Only WARNING and ERROR
Logger.set_output(filename=None)
Set output file path. Pass None to log to console.
Logger.set_output("logs/app.log")
Logger.note(note="", mode="normal")
Log a custom note.
Logger.note("Processing complete")
Logger.log(message="", end="")
Low-level logging method (rarely needed directly).
Async Support
Logger fully supports asyncio including concurrent execution:
@Logger()
async def process_item(item_id):
await asyncio.sleep(0.1)
return f"Processed {item_id}"
@Logger()
async def main():
# Concurrent execution - logs are properly tracked
results = await asyncio.gather(
process_item(1),
process_item(2),
process_item(3)
)
asyncio.run(main())
Best Practices
1. Use @Logger() for Most Cases
The defaults work great for most scenarios:
@Logger()
def my_function(x, y):
pass
2. Exclude self in Instance Methods
@Logger(exclude_args=["self"])
def process(self, data):
pass
3. Use Log Levels Appropriately
- DEBUG: Detailed diagnostic information
- INFO: General informational messages (default)
- WARNING: Warning messages for important events
- ERROR: Error messages for serious problems
4. Filter Sensitive Data
@Logger(exclude_args=["password", "api_key", "token", "secret"])
def authenticate(username, password, api_key):
pass
5. Set Global Level in Production
# In production, only show warnings and errors
Logger.set_level(LogLevel.WARNING)
Combining with Other Decorators
Place @Logger() as the outermost (top) decorator:
@Logger()
@cache
@validate_input
def expensive_calculation(x):
pass
Requirements
- Python 3.7+
- No external dependencies
License
MIT License
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Changelog
Version 2.0.0
- Added log levels (DEBUG, INFO, WARNING, ERROR)
- Added automatic depth tracking with indentation
- Added smart argument formatting for objects
- Added parameter name display for all arguments
- Added argument filtering (include_args/exclude_args)
- Improved async support with contextvars
- Enhanced class method support
Version 1.0.0
- Initial release
- Basic decorator logging
- Async function support
- File output
- ANSI color support
Metadata
Release files for logorator 2.0.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| logorator-2.0.3.tar.gz | 9.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| logorator-2.0.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 17.1 kB
Release files / logorator-2.0.3.tar.gz
| Download URL | logorator-2.0.3.tar.gz |
|---|---|
| Size | 9.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ddcaefefb4fcf1a2d5c6ab6e760d557411052f666dd50a2be3357257a64d3ee0
|
|
BLAKE2b-256 checksum How to use checksums |
6be9b161e74ffe28b616a17e9a32e6f933e1f0b0ed3477649aa0a0f5c80e7ee4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.2
|
Release files / logorator-2.0.3-py3-none-any.whl
| Download URL | logorator-2.0.3-py3-none-any.whl |
|---|---|
| Size | 7.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f8412e4dedcf2956c1820e51dad247b9be451d6ce1cee752b8b74521eee4ca52
|
|
BLAKE2b-256 checksum How to use checksums |
7943bf6e8513ab8f369f3909c7684826bce723f9bd657152b79b70cce7907f62
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.2
|