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

fix(utils): prevent duplicate log messages (#339) #366

Merged
merged 3 commits into from
Jul 17, 2023

Conversation

nweston
Copy link
Contributor

@nweston nweston commented Jul 9, 2023

What kind of change does this PR introduce?
Fixes a race condition in utils.configure_logging which leads to duplicate log messages.

Summary
Fixes #339.

The duplicate messages are caused by multiple threads calling configure_logging concurrently. This function had a race condition where two threads could both call logger.remove() and then both call logger.add(), creating two identical sinks.

Adding a lock prevents this bug although I don't think it makes configure_logging entirely thread-safe. In particular, if thread A tries to log something after thread B has called logger.remove(), but before it calls logger.add(), the message might get dropped (though I haven't observed this in practice).

I also removed some redundant configure_logging calls in record.py. This isn't necessary to fix the bug, but it seemed like a worthwhile cleanup. It's in a separate commit so it can easily be dropped if not desired.

Checklist

  • My code follows the style guidelines of OpenAdapt
  • I have performed a self-review of my code
  • If applicable, I have added tests to prove my fix is functional/effective
  • I have linted my code locally prior to submission
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation (e.g. README.md, requirements.txt)
  • New and existing unit tests pass locally with my changes

How can your code be run and tested?
python -m openadapt.record foo will reproduce the original issue and validate the fix.

Other information
I saw your post on Hacker News and I might be interested in paid work on OpenAdapt. How can I learn more?

nweston added 2 commits July 9, 2023 10:38
Acquire a lock in utils.configure_logging. Otherwise this function has
a race where two threads can both call logger.remove(), and then both
call logger.add(), creating two identical sinks.
configure_logging is already called at the module level so there's no
need to call it with identical arguments in various functions.
@nweston nweston marked this pull request as ready for review July 9, 2023 14:39
@0dm
Copy link
Collaborator

0dm commented Jul 11, 2023

Thanks for the contribution!

One small thing:

looks like the logger's colours are lost 🥲

image

vs main

image

@cr-gpt
Copy link

cr-gpt bot commented Jul 11, 2023

Seems you are using me but didn't get OPENAI_API_KEY seted in Variables/Secrets for this repo. you could follow readme for more information

@nweston
Copy link
Contributor Author

nweston commented Jul 11, 2023

Oops, I took the colors out for ease of grepping while I was debugging, and forgot to put them back. It's fixed now.

I used a fixup commit -- let me know if I should squash that before merging.

Copy link
Collaborator

@0dm 0dm left a comment

Choose a reason for hiding this comment

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

lgtm!

@@ -134,7 +134,6 @@ def process_events(
terminate_event: An event to signal the termination of the process.
"""

utils.configure_logging(logger, LOG_LEVEL)
Copy link
Member

Choose a reason for hiding this comment

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

Thanks @nweston !

Can you please clarify why it was necessary to remove these calls to utils.configure_logging?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's not strictly necessary -- adding the lock is sufficient to fix the bug. But these calls appear to be redundant (utils.configure_logging is already called at module level with the same arguments), and it's possible that there could be other race conditions, e.g. if one thread is outputting log messages while another is configuring. So removing them seemed like the safest option.

But if there's a reason to keep them, we can do that and the duplicate log messages will still be fixed.

@abrichr
Copy link
Member

abrichr commented Jul 17, 2023

Thanks @nweston ! Please grab some time on my calendar: https://www.getclockwise.com/c/richard-abrich/quick-meeting

@abrichr abrichr merged commit cf1a782 into OpenAdaptAI:main Jul 17, 2023
R-ohit-B-isht pushed a commit to R-ohit-B-isht/OpenAdapt that referenced this pull request Jun 21, 2024
…ptAI#366)

* fix(utils): prevent duplicate log messages (OpenAdaptAI#339)

Acquire a lock in utils.configure_logging. Otherwise this function has
a race where two threads can both call logger.remove(), and then both
call logger.add(), creating two identical sinks.

* refactor(record): remove redundant configure_logging calls

configure_logging is already called at the module level so there's no
need to call it with identical arguments in various functions.

* fixup! fix(utils): prevent duplicate log messages (OpenAdaptAI#339)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Bug]: logger produces duplicates on MacOS
3 participants