A powerful decorator-based logging library with automatic depth tracking, log levels, smart argument formatting, and full async support.
Project description
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
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file logorator-2.0.2.tar.gz.
File metadata
- Download URL: logorator-2.0.2.tar.gz
- Upload date:
- Size: 9.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8d1a79b7372725ebe160b86f9fcc8271428d94ca8cbaf98c19c79500058a55b1
|
|
| MD5 |
0a81467c95a79d05e96bd4e1c5594115
|
|
| BLAKE2b-256 |
fe3b5884b1d6731f49e440fb232039ee21e921de8af08736a6db181cb0729378
|
File details
Details for the file logorator-2.0.2-py3-none-any.whl.
File metadata
- Download URL: logorator-2.0.2-py3-none-any.whl
- Upload date:
- Size: 7.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1ee9fe8ecc899277e865c0cabf03b388a871ea5b8d4d88bc9c75b0db4f4dc567
|
|
| MD5 |
7578d7b2190838189040f0297acd6934
|
|
| BLAKE2b-256 |
385c935435a6aa1b325bcf2e7a82cb3babeee0cc2e4977285f795aae1893dcc4
|