Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🎨 Improving servicelib.logging_utils #6224

Merged
merged 4 commits into from
Aug 23, 2024

Conversation

pcrespov
Copy link
Member

@pcrespov pcrespov commented Aug 22, 2024

What do these changes do?

Addresses some issues with servicelib.logging_utils:

  • 🎨 fixes log_decorator to log only in level
  • ✨ new log_exceptions context manager

Motivation

The idea of log_decorator is to log inputs/outputs of a function. Inputs are the function arguments and are logged before calling the function. Outputs are either returned values or exceptions which are logged after the call.

Let's look at this example. Assume I decorate foo to log in debug mode

@log_decorator(_logger, logging.DEBUG)
def foo(x):
   if x<0:
       raise ValueError(x)
   return 2*x

and then use it inside another function where I handle the exceptions it might raise

def safe_foo(x):
   try:
      return foo(x)
    except ValueError: 
       return foo(abs(x)

Then, when I call safe_foo(-1) what would you expect in the logs. I would expect a DEBUG trace for all foo calls. Instead I was getting something like

DEBUG Begin foo(x=-1)
ERROR foo raised ValueError
 Traceback (most recent call last):
  # ...
  raise ValueError(msg)
 ValueError: -1
DEBUG Begin foo(x=1)
DEBUG End foo(x=1) -> 2 

But, didn't I handled that error? Why the function exception is logged as ERROR if I am logging my function as DEBUG.
The issues was introduced when we introduced log_catch within `log_decorator.

Thoughts

Logging should follow very rationale and the fucntions hsould have very similar signatures to builtin logging

  • Direct log
logger.info("direct log")
# or
logger.log(logging.INFO, "direct log")
  • Logging exceptions with a context manager
# raises
with log_exceptions(logger, logging.INFO):
    # ...
    resp.raise_for_status()
    
# does NOT raises  (NOTE: use composition of context managers)
with suppress(Exception), log_exceptions(logger, logging.INFO):
    # ...
    resp.raise_for_status()
  • Logging a "section of code"
with log_context(logger, logging.INFO, "foo and perhaps bar"):
   r = foo(1)
   if r:
      bar(r, 2) 

Composition of context managers can also be implemented using contextlib.ExitStack

Proposal

This is taking too much time and effort to get it right. I think we should move to something like loguru and even get asyncio improvement for free! On lets implement https://superfastpython.com/asyncio-logging-best-practices/

Related issue/s

How to test

cd packages/service-library
make install-dev
pytest -vv tests/test_logging_utils

@pcrespov pcrespov added a:services-library issues on packages/service-libs t:maintenance Some planned maintenance work labels Aug 22, 2024
@pcrespov pcrespov added this to the Eisbock milestone Aug 22, 2024
@pcrespov pcrespov self-assigned this Aug 22, 2024
Copy link

codecov bot commented Aug 22, 2024

Codecov Report

Attention: Patch coverage is 90.24390% with 4 lines in your changes missing coverage. Please review.

Project coverage is 87.8%. Comparing base (cafbf96) to head (26eba64).
Report is 463 commits behind head on master.

Files Patch % Lines
...es/service-library/src/servicelib/logging_utils.py 90.2% 3 Missing and 1 partial ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff            @@
##           master   #6224      +/-   ##
=========================================
+ Coverage    84.5%   87.8%    +3.2%     
=========================================
  Files          10    1143    +1133     
  Lines         214   50332   +50118     
  Branches       25     780     +755     
=========================================
+ Hits          181   44222   +44041     
- Misses         23    5939    +5916     
- Partials       10     171     +161     
Flag Coverage Ξ”
integrationtests 64.9% <ΓΈ> (?)
unittests 85.3% <90.2%> (+0.8%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files Coverage Ξ”
...es/service-library/src/servicelib/logging_utils.py 75.7% <90.2%> (ΓΈ)

... and 1152 files with indirect coverage changes

@pcrespov pcrespov changed the title WIP: Mai/logging utils 🎨 Improving servicelib.logging_utils Aug 22, 2024
@pcrespov pcrespov marked this pull request as ready for review August 22, 2024 19:32
@pcrespov pcrespov enabled auto-merge (squash) August 22, 2024 19:33
Copy link
Contributor

@GitHK GitHK left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, please see my question below.
FYI: I would not mind us moving towards loguru.

Copy link
Member

@sanderegg sanderegg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I don't see where loguru say they are asyncio compatible. can you point that please?

@pcrespov
Copy link
Member Author

Thanks, I don't see where loguru say they are asyncio compatible. can you point that please?

@sanderegg they seem to provide support to enqueue logs asyncronously. https://loguru.readthedocs.io/en/stable/overview.html#asynchronous-thread-safe-multiprocess-safe
I would test the impact it has compared to the builtin logger and then decide

@pcrespov pcrespov requested a review from GitHK August 23, 2024 07:34
@sanderegg
Copy link
Member

Thanks, I don't see where loguru say they are asyncio compatible. can you point that please?

@sanderegg they seem to provide support to enqueue logs asyncronously. https://loguru.readthedocs.io/en/stable/overview.html#asynchronous-thread-safe-multiprocess-safe I would test the impact it has compared to the builtin logger and then decide

@pcrespov then please also check with this:
https://superfastpython.com/asyncio-logging-best-practices/

Copy link
Contributor

@matusdrobuliak66 matusdrobuliak66 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks

Copy link

@pcrespov pcrespov merged commit ea698ad into ITISFoundation:master Aug 23, 2024
57 checks passed
@pcrespov pcrespov deleted the mai/logging_utils branch August 30, 2024 12:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
a:services-library issues on packages/service-libs t:maintenance Some planned maintenance work
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants