-
Notifications
You must be signed in to change notification settings - Fork 14
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
Proposal for a logging module #456
Merged
Merged
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
jeremykubica
reviewed
Feb 8, 2024
- Fix singleton object lifetime by wrapping it into a static method - use py::object instead of py::handle to wrap a Python Logger instance - this respects the refcount tracking, unlike before. Why we didn't get an error at the end of every program execution - I don't know. - add destructors, call them for Logger in the registry, let the default per-field destructor handle the rest. - Add virtual destructor to Logger class itself, - Deleting a derived class object using a pointer of base class type that has a non-virtual destructor results in undefined behavior. - Add more formatting options - support the major formatting keywords for the whole debug string (asctimes, names, levelnames and messages) using regex - support time-zone aware timestamps - support more Python-like formatting options. This is probably exactly how they do it. Actually I know it is: https://github.com/python/cpython/blob/main/Modules/_datetimemodule.c#L1646 - Fix the potential memory leak on time-stamp via put_time instead of mallocing untill strftime does not throw an error. - Add the missing logger call to image_stack.
DinoBektesevic
force-pushed
the
proposals/logging
branch
from
February 27, 2024 11:28
6f35a95
to
567d2a4
Compare
jeremykubica
requested changes
Feb 27, 2024
Fix the forgotten new allocation in Logging::logging. Convert even more prints to logging. Add our own root logger and rework the config system. Add DebugTimer support (how did I miss this the first time?) Actually test that it works by hand.
DinoBektesevic
force-pushed
the
proposals/logging
branch
from
February 28, 2024 01:45
149f4d7
to
1643fd9
Compare
jeremykubica
approved these changes
Feb 28, 2024
DinoBektesevic
added a commit
that referenced
this pull request
Mar 14, 2024
…s/logging"" This reverts commit 22bdac3.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Issue
Logging in Python is a singleton that expects a logger to be declared on a module level. Each Logger has a unique name, and is retrieved via getLogger with the corresponding name. The recommended way to uniquely achieve this Python is to register a logger on a module level, using module's name:
Occasionally we have to produce a log on the C++ side. Primary use-case are logs produced by
StackSearch
- a C++ class used to manage processing, but generally not by the user. Users are expected to use theSearchRunner
class instead.SearchRunner
produces logs of the processing progress, Python-side, usingprint
and theStackSearch
on the C++ side usingstd::cout
. This is done so that the print-outs appear as if they are coming from the same place. If we replaced the prints Python side withlogging
functionality, the outputs from the two objects would diverge and the C++ side output would not follow the Python logging output configuration anymore.Potential solutions
To restore this behavior we would need to call the Python-side
logger
from C++. For that, we need to (somehow) pass a reference to thelogger
into the "StackSearch" class. Several options exist:The second approach is implemented in this proposal. I don't see many (any) benefits of the first approach, we would have to wrap all uses of the logger in a class anyhow (which is basically what 2 is minus the Py-wrapper logger) or use pre-processor directives to call either some output or the Python
logger
.How it works
The
Logging
class is a singleton that keeps a reference to all createdLoggers
. TheLoggers
define the log format and IO method (stdout, file etc.).Logging
keeps references toLoggers
in a registry. This registry is exposed via thegetLogger
method, which doubles as a factory function forLoggers
. This is modeled after Python's logging module. WhengetLogger
is called from Python (via the pybind11 bindings) it creates a new Python-sideLogger
object and registers its reference. When called C++ side it creates a C++-sideLogger
and registers its reference. Accessing agetLogger
using a name that was already registered - it returns the reference from the registry.This allows us to access Python-side loggers directly from C++ by invoking
from C++. On the example of SearchRunner, placing:
somewhere in the
search_runner.cpp
would return:a) the Python
Logger
object for the module, assumingsearch
module is being called from Python, because the loggers are defined as module-global variables; i.e. guaranteed to occur before any C++ code executes.b) or the default
std::cout
logger named "kbmod.run_search" that is basically acting as a more glorified print formatted that can prune and not-emit certain "levels" of messages.The obvious pitfall is the case when a user does not route through this
Logging
, and instead registers a Python-sideLogger
via itslogging
module. Because these Python-sideLoggers
are not registered in theLogging
's registry the KBMODLogging
will default to using the C++std::out
logger. This can lead to differing output formats if the Python Logger in question is then re-configured (as the default behavior of the internal KBMODLogger
was made to match that of default PythonLogger
).