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 to install the logger in its default configuration. It's also possible to tweak its configuration (mostly to tune its performance).

fn main() {
use log::info;
use pyo3::prelude::*;
use pyo3::wrap_pyfunction;

fn log_something() {
    // This will use the logger installed in `my_module` to send the `info`
    // message to the Python logging facilities.

fn my_module(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
    // A good place to install the Rust -> Python logger.


Then it is up to the Python side to actually output the messages somewhere.

import logging
import my_module

FORMAT = '%(levelname)s %(name)s %(asctime)-15s %(filename)s:%(lineno)d %(message)s'

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.