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
DM-30996: Implement log4cxx appender which logs to Python logging #55
Conversation
Work in progress, most things should work already, still need to figure out best way to handle MDC.
e4d811e
to
011c47f
Compare
src/PyLogAppender.cc
Outdated
}; | ||
|
||
/** | ||
* Re-raise Python exception as C++ exception. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you sure that we can't let this propagate through Python directly without catching it and possibly losing information? Seems like a shame otherwise.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not possible unfortunately. Usually C++ wrappers catch C++ exceptions and replace existing Python exception with contents of C++ exception message, so the only way is to save whatever info we could in C++ exception.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even if we were to define an additional C++ exception type like PythonException
and change pex_exceptions
to detect it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is controlled by the code which wraps the C++ calls, catches C++ exceptions and converts them to Python (pybind11 or anything else). I'm not sure that different exception class can provide more control over that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought we own at least some of this code at https://github.com/lsst/pex_exceptions/blob/master/python/lsst/pex/exceptions/exceptions.cc#L156-L164
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to look at that but it will take time for me to learn how it all works. If we want to add pex_exceptions
as another dependency here maybe there is someone already knowledgeable at that who can look at new code. OTOH, most of the exceptions that I generate should not have Python traceback, so maybe it's fine to drop it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, it's fine to keep this as is.
Co-authored-by: Kian-Tat Lim <ktl@slac.stanford.edu>
@ktlim, I am messing around with all ideas and I have found issues that further complicate my already complicated plan. I was hoping to make
It is possible to suppress errors when parsing configuration but this also means missing all other possible errors in configuration. It looks like the only option for now is to drop support for Another issue is the interaction between |
The error doesn't have something to do with https://github.com/lsst/log/blob/accbc96b7321847d4fc4cb6631d63964bfd86104/src/PyLogAppender.cc#L220-222, does it? |
It does. I wanted to make |
@ktlim, I have re-implemented much of the appender code to make/update one |
If LogRecord does not have `MDC` attribute already then create it as an instance of a special `lsst.log.utils._MDC` dictionary class. If `MDC` attribute is already there (added by record factory) then assume it is a dictionary and update it with MDC contents. This allows adding MDC items at Python level as well.
56eea92
to
4d24fb6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great!
python/lsst/log/utils.py
Outdated
This is internal class used for better formatting of MDC in Python logging | ||
output. It behaves like `defaultdict(str)` but overrides ``__str__`` and | ||
``__repr__`` method to produce output better suited for logging records. | ||
It also provides namespace-like access to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"too."? Or "to keys"? Or something else?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was obviously distracted by something important (squirrels or 🐱), will expand 🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am actually inclined to drop attribute-like access and only keep indexing access. It may be convenient to say MDC.key
instead of MDC[key]
in format string but it does not work for keys that do not look like identifiers, and it sort of adds additional requirement on other implementations of MDC dictionary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm fine with just doing **MDC
and having the formatting find the right element. We can always add the .key
later. In python logging I would probably add **MDC
directly into the kwargs in the LoggingAdapter and pull them out of the LogRecord
directly later on.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But that exposes you to potential attribute collision.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. If someone sets MDC to lineno
or something. People can indeed shoot themselves in the foot like that but why would they? I don't think python lets me use a format string of %(extra['LABEL'])s
though so how would I ever include it in a logging format string?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use style='{'
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay. Hmm. So we are okay with a LogFormatter using f-style but all the Loggers using %-style?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Loggers don't have an option for style (would be nice to have but probably hard to implement). Formatter style is set in the same place as format string so we should be OK if we do it consistently.
Co-authored-by: Kian-Tat Lim <ktl@slac.stanford.edu>
`_MDC` is renamed to `MDCDict` and moved to `lsst.log` to avoid circular dependencies when implementing new `configure_pylog_MDC` method.
OK, I think I resolved all comments now, will merge in ~1 hour unless there are objections. New convenience method to configure forwarding is |
Previous location caused usual mess with dynamic libraries in Python, it should work better in Python module. Both locations are probably not right for that piece of code but I do not want to introduce another dynamic library just for that class (and it also depends on Python module).
Just an additional protection, not really needed in this code, but may be useful if someone else uses it.
Adds new log4cxx Appender class that forwards everything to Python logging.