Package: logquacious
logquaciousLogquacious is a set of simple logging utilities to help you over-communicate.
(Logorrhea would’ve been a good name, if it didn’t sound so terrible.)Good application logging is easy to overlook, until you have to debug an error
in production. Logquacious aims to make logging as easy as possible. You can
find read more at the officialReadTheDocs documentation.Quick startTo get started, first make sure logquacious is installed:$pipinstalllogquaciousYou’ll also need to set up logging for your application. For this
example, we’ll use a really simple configuration:importlogginglogging.basicConfig(format='%(levelname)s:%(message)s',level=logging.DEBUG)Note that this simple configuration is used for demonstration purposes, only.
See theLogging Cookbookin the official Python docs for examples of
options used for real logging configuration.The main interface tologquaciousis theLogManager, which can be used for
normal logging:importlogquaciouslog=logquacious.LogManager(__name__)log.debug('Nothing to see here.')Due to our simplified logging format defined earlier, that would output:DEBUG: Nothing to see here.That isn’t a very interesting example. In addition to basic logging,LogManagerhas acontextattribute for use as a context manager:>>>withlog.context.debug('greetings'):...print('Hello!')DEBUG:EntergreetingsHello!DEBUG:ExitgreetingsThe same attribute can be used as a decorator, as well:@log.context.infodefdivide(numerator,denominator):ifdenominator==0:log.warning('Attempted division by zero. Returning None')returnNonereturnnumerator/denominator>>>divide(1,0)INFO:Call`divide()`WARNING:Attempteddivisionbyzero.ReturningNoneINFO:Returnfrom`divide`Even better, you can log input arguments as well:@log.context.info(show_args=True,show_kwargs=True)defgreet(name,char='-'):msg='Hello,{name}'.format(name=name)print(msg)print(char*len(msg))>>>greet('Tony',char='~')INFO:Call`greet('Tony',char='~')`Hello,Tony~~~~~~~~~~~INFO:Returnfrom`greet`There’s also a special context manager for suppressing errors and logging:withlog.and_suppress(ValueError,msg="It's ok, mistakes happen"):raiseValueError('Test error')[ERROR] It's ok, mistakes happen
Traceback (most recent call last):
  File "/Users/tyu/code/logquacious/logquacious/log_manager.py", line 103, in and_suppress
    yield
  File "scripts/example.py", line 26, in <module>
    raise ValueError('Test error')
ValueError: Test errorNote the traceback above is logged, not streamed to stderr.ConfigurationThe message templates used byLogManager.contextcan be configured to your
liking by passing acontext_templatesargument toLogManager:log=logquacious.LogManager(__name__,context_templates={'context.start':'=============== Enter{label}===============','context.finish':'=============== Exit{label}===============',})withlog.context.debug('greetings'):print('Hello!')[DEBUG] =============== Enter greetings ===============
Hello!
[DEBUG] =============== Exit greetings ===============The general format forcontext_templateskeys is:[CONTEXT_TYPE.]('start'|'finish')[.LOG_LEVEL_NAME]where square-brackets marks optional fields.CONTEXT_TYPEcan be any of the following:function: Template used when called as a decorator.context: Template used when called as a context manager.LOG_LEVEL_NAMEcan be any of the following logging levels:DEBUGINFOWARNINGERRORCRITICALFor example, consider the cascade graph forfunction.start.DEBUG, which
looks like:function.start.DEBUG
          /       \
start.DEBUG       function.start
          \       /
            startThe cascade is performed using a breadth-first search. Iffunction.start.DEBUGis not defined, checkstart.DEBUGthen checkfunction.startBEFOREcheckingstart.The default configuration is:DEFAULT_TEMPLATES={'start':'Enter{label}','finish':'Exit{label}','function.start':'Call `{label}({arguments})`','function.finish':'Return from `{label}`',}Note that custom configurationupdatesthese defaults. For example, if you
want to if you want to skip logging on exit for all context managers and
decorators, you’ll have setboth'finish'and'function.finish'toNoneor an empty string.As you can see above, two template variables may be passed to the template
string:labelandarguments. When called as a context manager, thelabelis the first argument to the context manager andargumentsis always empty.
When called as a decorator,labelis the function’s__name__andargumentsa string representing input arguments, ifshow_argsorshow_kwargsparameters areTrue.CreditsThis package was created withCookiecutterand theaudreyr/cookiecutter-pypackageproject template.History0.5.0 (2019-05-05)Backportstacklevelkeyword argument from Python 3.8 and configure
stacklevel such that logging utilities report the context (e.g. filename
and line number) wherelogquaciousutilities are called.0.4.0 (2018-10-05)Fix config override behavior to extend rather than replace default templates0.3.0 (2018-10-05)Add decorator support forlog.and_suppressandlog.and_reraisecontext
managersSuppress logging for null/empty log message templates0.2.0 (2018-10-03)Changed default templates. In 0.1.0, the templates were:DEFAULT_TEMPLATES={'start':'Start{label}','finish':'Finish{label}',}These defaults have been changed to:DEFAULT_TEMPLATES={'start':'Enter{label}','finish':'Exit{label}','function.start':'Call `{label}({arguments})`','function.finish':'Return from `{label}`',}0.1.0 (2018-10-03)First release on PyPI.