Controlling the RDKit’s logging behavior

documentation
technical
How to disable or capture the RDKit’s logging messages
Published

August 10, 2025

One reasonably frequently asked question is how to disable (easy) or capture (a bit trickier) the log messages that the RDKit sends to the console. There are a few ways to do this, so it seemed worthwhile to do a blog post, particularl since I tend to forget how to do the part where the logs are actually captured.

Here are a couple of other sources of information on the topic: - Earlier blog post: https://greglandrum.github.io/rdkit-blog/posts/2024-02-23-custom-transformations-and-logging.html - A discussion topic: https://github.com/rdkit/rdkit/discussions/8299

There’s considerably more information on how to use Python’s logging module in the Python docs.

import rdkit
from rdkit import rdBase
from rdkit import Chem

print(rdkit.__version__)
2025.03.5
Chem.MolFromSmiles('CO(C)C')
[05:47:43] Explicit valence for atom # 1 O, 3, is greater than permitted

The easiest thing to do is just disable all logging output:

rdBase.DisableLog('rdApp.*')
Chem.MolFromSmiles('CO(C)C')

You can re-enable it later:

rdBase.EnableLog('rdApp.*')
Chem.MolFromSmiles('CO(C)C')
[05:47:43] Explicit valence for atom # 1 O, 3, is greater than permitted

It’s easier (and perhaps safer) to disable the logging output using a context manager:

with rdBase.BlockLogs() as blk:
    Chem.MolFromSmiles('CO(C)C')

Outside of the context manager, the logging is still active:

Chem.MolFromSmiles('CO(C)C')
[05:47:43] Explicit valence for atom # 1 O, 3, is greater than permitted

Capturing the log messages requires a bit more work, but isn’t hard.

We start by telling the RDKit to use Python’s logging framework:

rdBase.LogToPythonLogger()

And now configure the logging using standard Python logging features:

import logging
from io import StringIO

# Here we will capture the log output in a StringIO object
sio = StringIO()
hdlr = logging.StreamHandler(sio)

# and change the way the messages are formatted:
fmt = logging.Formatter('%(name)s - %(levelname)s - %(message)s')
hdlr.setFormatter(fmt)

# Remove any existing handlers from the RDKit logger. This is important if we are working in the notebook:
rdkit.logger.handlers.clear()
rdkit.logger.addHandler(hdlr)

Now errors no longer go to the console:

Chem.MolFromSmiles('CO(C)C')

But we can access them from the StringIO object:

print(sio.getvalue())
rdkit - ERROR - [05:47:43] Explicit valence for atom # 1 O, 3, is greater than permitted

It’s also easy to log to a file:

import tempfile
tf = tempfile.NamedTemporaryFile()
tf.close() #<- close the file or we will get an error on Windows

hdlr = logging.FileHandler(tf.name)

# and change the way the messages are formatted:
fmt = logging.Formatter('%(name)s - %(levelname)s - %(message)s')
hdlr.setFormatter(fmt)

# Remove any existing handlers from the RDKit logger. This is important if we are working in the notebook:
rdkit.logger.handlers.clear()
rdkit.logger.addHandler(hdlr)
Chem.MolFromSmiles('CO(C)C')
with open(tf.name,'r') as inf:
    print(inf.read())
rdkit - ERROR - [05:47:43] Explicit valence for atom # 1 O, 3, is greater than permitted

It’s definitely worth taking a look through Python’s logging HowTo for more info on working with logging.