Decorator for logging function arguments and return value by human-readable way
Project description
logwrap
logwrap is a helper for logging in human-readable format function arguments and call result on function call. Why? Because logging of *args, **kwargs become useless with project grow and you need more details in call log.
Cons:
Log records are not single line.
Pros:
Log records are not single 100500 symbols length line. (Especially actual for testing/development environments and for Kibana users).
Service free: job is done by this library and it’s dependencies. It works at virtualenv
Free software: Apache license
Open Source: https://github.com/python-useful-helpers/logwrap
PyPI packaged: https://pypi.python.org/pypi/logwrap
Self-documented code: docstrings with types in comments
Tested: see bages on top
Support multiple Python versions:
Python 2.7 Python 3.4 Python 3.5 Python 3.6 PyPy PyPy3 3.5+
This package includes helpers:
logwrap - main helper. The same is LogWrap.
LogWrap - class with logwrap implementation. May be used directly.
pretty_repr
pretty_str
PrettyFormat
Usage
logwrap
The main decorator. Could be used as not argumented (@logwrap.logwrap) and argumented (@logwrap.logwrap()). Not argumented usage simple calls with default values for all positions. Argumented usage with arguments from signature:
@logwrap.logwrap(
log=logging.getLogger(__name__), # __name__ = 'logwrap'
log_level=logging.DEBUG,
exc_level=logging.ERROR,
max_indent=20, # forwarded to the pretty_repr
spec=None, # use target callable function for spec
blacklisted_names=None, # list argument names, which should be dropped from log
blacklisted_exceptions=None, # Exceptions to skip in log
log_call_args=True, # Log call arguments before call
log_call_args_on_exc=True, # Log call arguments if exception happens
log_result_obj=True, # Log result object
)
Usage examples:
@logwrap.logwrap()
def foo():
pass
is equal to:
@logwrap.logwrap
def foo():
pass
Get decorator for use without parameters:
get_logs = logwrap.logwrap() # set required parameters via arguments
type(get_logs) == LogWrap # All logic is implemented in LogWrap class starting from version 2.2.0
@get_logs
def foo():
pass
Call example:
import logwrap
@logwrap.logwrap
def example_function1(
arg1: str,
arg2: str='arg2',
*args,
kwarg1: str,
kwarg2: str='kwarg2',
**kwargs
) -> tuple():
return (arg1, arg2, args, kwarg1, kwarg2, kwargs)
example_function1('arg1', kwarg1='kwarg1', kwarg3='kwarg3')
This code during execution will produce log records:
Calling: 'example_function1'( # POSITIONAL_OR_KEYWORD: 'arg1'=u'''arg1''', 'arg2'=u'''arg2''', # VAR_POSITIONAL: 'args'=(), # KEYWORD_ONLY: 'kwarg1'=u'''kwarg1''', 'kwarg2'=u'''kwarg2''', # VAR_KEYWORD: 'kwargs'= dict({ 'kwarg3': u'''kwarg3''', }), ) Done: 'example_function1' with result: tuple(( u'''arg1''', u'''arg2''', (), u'''kwarg1''', u'''kwarg2''', dict({ 'kwarg3': u'''kwarg3''', }), ))
Limitations:
nested wrapping (@logwrap @deco2 …) is not parsed under python 2.7: functools.wraps limitation. Please set logwrap as the first level decorator.
LogWrap
Example construction and read from test:
log_call = logwrap.LogWrap()
log_call.log_level == logging.DEBUG
log_call.exc_level == logging.ERROR
log_call.max_indent == 20
log_call.blacklisted_names == []
log_call.blacklisted_exceptions == []
log_call.log_call_args == True
log_call.log_call_args_on_exc == True
log_call.log_result_obj == True
On object change, variable types is validated.
pretty_repr
This is specified helper for making human-readable repr on complex objects. Signature is self-documenting:
def pretty_repr(
src, # object for repr
indent=0, # start indent
no_indent_start=False, # do not indent the first level
max_indent=20, # maximum allowed indent level
indent_step=4, # step between indents
py2_str=False, # use bytes for python 2 __repr__ and __str__
)
Limitation: Dict like objects is always marked inside {} for readability, even if it is collections.OrderedDict (standard repr as list of tuples).
pretty_str
This is specified helper for making human-readable str on complex objects. Signature is self-documenting:
def pretty_str(
src, # object for __str__
indent=0, # start indent
no_indent_start=False, # do not indent the first level
max_indent=20, # maximum allowed indent level
indent_step=4, # step between indents
py2_str=False, # use bytes for python 2 __repr__ and __str__
)
- Limitations:
Dict like objects is always marked inside {} for readability, even if it is collections.OrderedDict (standard repr as list of tuples).
Iterable types is not declared, only brackets is used.
String and bytes looks the same (its __str__, not __repr__).
PrettyFormat
PrettyFormat is the main formatting implementation class. pretty_repr and pretty_str uses instances of subclasses PrettyRepr and PrettyStr from this class. This class is mostly exposed for typing reasons. Object signature:
def __init__(
self,
max_indent=20, # maximum allowed indent level
indent_step=4, # step between indents
py2_str=False, # use bytes for python 2 __repr__ and __str__
)
Callable object (PrettyFormat instance) signature:
def __call__(
self,
src, # object for repr
indent=0, # start indent
no_indent_start=False # do not indent the first level
)
Adopting your code
pretty_repr behavior could be overridden for your classes by implementing specific magic method:
def __pretty_repr__(
self,
parser # PrettyFormat class instance,
indent # start indent,
no_indent_start # do not indent the first level
):
return ...
This method will be executed instead of __repr__ on your object.
def __pretty_str__(
self,
parser # PrettyFormat class instance,
indent # start indent,
no_indent_start # do not indent the first level
):
return ...
This method will be executed instead of __str__ on your object.
Testing
The main test mechanism for the package logwrap is using tox. Test environments available:
pep8 py27 py34 py35 py36 pypy pypy3 pylint pep257 docs
CI systems
For code checking several CI systems is used in parallel:
Travis CI: is used for checking: PEP8, pylint, bandit, installation possibility and unit tests. Also it’s publishes coverage on coveralls.
coveralls: is used for coverage display.
CD system
Travis CI: is used for package delivery on PyPI.
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 Distributions
Hashes for logwrap-3.2.2-cp36-cp36m-manylinux1_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | df2e2d26ed2c4745b4c5cd76fe01f1fe37131384f0a47fbd9e8f449eb300e09b |
|
MD5 | caca41de6316974250347d1e51af8820 |
|
BLAKE2b-256 | aea0dfcebb262f3cf5f08a4ea0dc38c375792299bec356e591b0324dc53afbb4 |
Hashes for logwrap-3.2.2-cp36-cp36m-manylinux1_i686.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | aed3a42324fcafe67d0d0fbb2735ac5c4b4f6aa1d63e2c05fdb15ca7f39a02e0 |
|
MD5 | 510ef678f704dd625da80ccc1b678e24 |
|
BLAKE2b-256 | 4d31dd5b075e6cb1f85a41142fe0f98e426211c8deb252dff5251ace200506dc |
Hashes for logwrap-3.2.2-cp35-cp35m-manylinux1_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | cedeffbdb1a64fd10ede14b6f304d8b518c041b89944977503e69e25b6efeaaf |
|
MD5 | 2234092ad02fcf27e295be7c0f4eadef |
|
BLAKE2b-256 | f77426bf2c9e5667f219914c2be4b519277ed152d909bec07520af4c35a11afc |
Hashes for logwrap-3.2.2-cp35-cp35m-manylinux1_i686.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 679816016c8775e71a575506978c92255307bb4dd70d082b84eda64fb6a40425 |
|
MD5 | b0b92166d732cab8227b9cd03cb99dcd |
|
BLAKE2b-256 | 9666196cddc95976bf9b8881b466abe246afe184925478b54098de24dbd76cb1 |
Hashes for logwrap-3.2.2-cp34-cp34m-manylinux1_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 54c72f69108d5a6cb393f2df07c04448aee90e22b2b3e473a3d0ac3cb6438c8c |
|
MD5 | 44ae5a08fe06318c21f4fb1b6dd00aa0 |
|
BLAKE2b-256 | 8780a34cb7fb398b542bae6aa7b51e58cd05773f15842433069be7b4323b281b |
Hashes for logwrap-3.2.2-cp34-cp34m-manylinux1_i686.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 95b4697d9e0614bcc6c13505b0a37c5f9b9c345a43c6f5de3ea9665cd1a7ece5 |
|
MD5 | 1ba1e3b256109575782614a69c356439 |
|
BLAKE2b-256 | 9095cd5fff5da16f4cce8cd850b4398dfb908251a3f3b7ee4df355801344c510 |