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/penguinolog/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.0-cp36-cp36m-manylinux1_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 5498e63afa6e6c69ae1af3058d2a16d9e300043df72f1b17a66d829e79e538cc |
|
MD5 | 106947ff4e4b3fb88d0357341b3d91c3 |
|
BLAKE2b-256 | 5baf01e159ebc66afef3ca159a9a2061a9158531a09884f245dd69a319675657 |
Hashes for logwrap-3.2.0-cp36-cp36m-manylinux1_i686.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | f10c9c1ffb174b1d317a60d686a0a9722ada5bd402fb22e2b6bf316d75d6ef2f |
|
MD5 | 08480543d3dcc11f20de3924ed7bb635 |
|
BLAKE2b-256 | dcef9917f2488f5905a7e4b091f2e8ad6235edac29c6c4ea3d3b58bda11f9c47 |
Hashes for logwrap-3.2.0-cp35-cp35m-manylinux1_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | aed1a8ee7899bf9e118f81015e21fe7635c83b8c498d037af4f4d26d7dd048de |
|
MD5 | c97a35b85a098174e58bc692d0f9e6dd |
|
BLAKE2b-256 | 67072bf10697349b0bcefc4c688e986e3a488de21fa23dde9c322a1479a8e661 |
Hashes for logwrap-3.2.0-cp35-cp35m-manylinux1_i686.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 8daf44c17b12943a9b7cf3b67ea27a5ef681b855adee9990948418d562ea0b6c |
|
MD5 | 3f5ef05e1bfd4fdfecc8fecc6bfee9fa |
|
BLAKE2b-256 | f953a19002cf098bb5177ba360373a0d82c41ca0c09195053e147fbc571b5590 |
Hashes for logwrap-3.2.0-cp34-cp34m-manylinux1_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 21ff129dbe62c149274c3bca0d0a4fcab16915f81bcffb50aa1a1c571ae580de |
|
MD5 | c696b59b329e4d4ba9e36e9b0865f8e0 |
|
BLAKE2b-256 | 7666badfedc8d46a904047bfe119e80cc9914fb965b50cedbf07a12219608d58 |
Hashes for logwrap-3.2.0-cp34-cp34m-manylinux1_i686.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 5b17f75629f7bf4851df7b643e4ecae2f86ddc1961976558161b3d20a8ecaad5 |
|
MD5 | bf783e6836c7f6160b630e7cc31c2135 |
|
BLAKE2b-256 | c9f3b59dab92d40847cccbcc6d4f68931f927e6299c4b4120b20e795a5276b7e |