docs: Link to pyo3-log in README and the guide
Show how one can log from Rust through the Python's logging facilities. Related to #1016.
This commit is contained in:
parent
41b35b84ca
commit
e6dd2d980f
|
@ -137,6 +137,7 @@ about this topic.
|
|||
* [pyo3-built](https://github.com/PyO3/pyo3-built) _Simple macro to expose metadata obtained with the [`built`](https://crates.io/crates/built) crate as a [`PyDict`](https://pyo3.github.io/pyo3/pyo3/struct.PyDict.html)_
|
||||
* [rust-numpy](https://github.com/PyO3/rust-numpy) _Rust binding of NumPy C-API_
|
||||
* [dict-derive](https://github.com/gperinazzo/dict-derive) _Derive FromPyObject to automatically transform Python dicts into Rust structs_
|
||||
* [pyo3-log](https://github.com/vorner/pyo3-log) _Bridge from Rust to Python logging_
|
||||
|
||||
## Examples
|
||||
|
||||
|
|
|
@ -16,3 +16,4 @@
|
|||
- [Appendix A: PyO3 and rust-cpython](rust_cpython.md)
|
||||
- [Appendix B: Migration Guide](migration.md)
|
||||
- [Appendix C: Trait bounds](trait_bounds.md)
|
||||
- [Appendix D: Logging](logging.md)
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
# Logging
|
||||
|
||||
It is desirable if both the Python and Rust parts of the application end up
|
||||
logging using the same configuration into the same place.
|
||||
|
||||
This section of the guide briefly discusses how to connect the two languages'
|
||||
logging ecosystems together. The recommended way for Python extension modules is
|
||||
to configure Rust's logger to send log messages to Python using the `pyo3-log`
|
||||
crate. For users who want to do the opposite and send Python log messages to
|
||||
Rust, see the note at the end of this guide.
|
||||
|
||||
## Using `pyo3-log` to send Rust log messages to Python
|
||||
|
||||
The [pyo3-log] crate allows sending the messages from the Rust side to Python's
|
||||
[logging] system. This is mostly suitable for writing native extensions for
|
||||
Python programs.
|
||||
|
||||
Use [`pyo3_log::init`][init] to install the logger in its default configuration.
|
||||
It's also possible to tweak its configuration (mostly to tune its performance).
|
||||
|
||||
```rust
|
||||
use log::info;
|
||||
use pyo3::prelude::*;
|
||||
use pyo3::wrap_pyfunction;
|
||||
|
||||
#[pyfunction]
|
||||
fn log_something() {
|
||||
// This will use the logger installed in `my_module` to send the `info`
|
||||
// message to the Python logging facilities.
|
||||
info!("Something!");
|
||||
}
|
||||
|
||||
#[pymodule]
|
||||
fn my_module(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
|
||||
// A good place to install the Rust -> Python logger.
|
||||
pyo3_log::init();
|
||||
|
||||
m.add_wrapped(wrap_pyfunction!(log_something))?;
|
||||
Ok(())
|
||||
}
|
||||
```
|
||||
|
||||
Then it is up to the Python side to actually output the messages somewhere.
|
||||
|
||||
```python
|
||||
import logging
|
||||
import my_module
|
||||
|
||||
FORMAT = '%(levelname)s %(name)s %(asctime)-15s %(filename)s:%(lineno)d %(message)s'
|
||||
logging.basicConfig(format=FORMAT)
|
||||
logging.getLogger().setLevel(logging.INFO)
|
||||
my_module.log_something()
|
||||
```
|
||||
|
||||
It is important to initialize the Python loggers first, before calling any Rust
|
||||
functions that may log. This limitation can be worked around if it is not
|
||||
possible to satisfy, read the documentation about [caching].
|
||||
|
||||
## The Python to Rust direction
|
||||
|
||||
To best of our knowledge nobody implemented the reverse direction yet, though it
|
||||
should be possible. If interested, the `pyo3` community would be happy to
|
||||
provide guidance.
|
||||
|
||||
[logging]: https://docs.python.org/3/library/logging.html
|
||||
[pyo3-log]: https://crates.io/crates/pyo3-log
|
||||
[init]: https://docs.rs/pyo3-log/*/pyo3_log/fn.init.html
|
||||
[caching]: https://docs.rs/pyo3-log/*/pyo3_log/#performance-filtering-and-caching
|
Loading…
Reference in New Issue