Similar to this post, but rather than change the logging level, I would like to redirect all logging information to a file. I believe the relevant API call is:
pybel.ob.obErrorLog.SetOutputStream()
or:
pybel.ob.OBMessageHandler().SetOutputStream()
But the SetOutputStream()
method only accepts objects of type std::ostream *
, not Python file streams, e.g. open('/path/to/log.txt', 'w')
or sys.stdout
.
Here are a few things I tried:
from openbabel import openbabel
import io
import sys
obHandler = openbabel.OBMessageHandler()
obHandler.SetOutputStream(io.BytesIO())
##Out: TypeError: in method 'OBMessageHandler_SetOutputStream', argument 2 of type 'std::ostream *'
obHandler.SetOutputStream(sys.stderr)
##Out: TypeError: in method 'OBMessageHandler_SetOutputStream', argument 2 of type 'std::ostream *'
with open("test.out", "w") as fd:
obHandler.SetOutputStream(fd)
##Out: TypeError: in method 'OBMessageHandler_SetOutputStream', argument 2 of type 'std::ostream *'
TL;DR: is there a reasonable way to direct log information to a file in PyBel?
One way work around this error is to capture the standard error stream.
Unfortunately one cannot directly redirect the standard error to an IOStream, as OpenBabel is operating on the underlying C standard error and unaware of the Python one.
But, thanks to this Stack Overflow answer, it is actually possible to capture the underlying error stream to a string.
With the
OutputGrabber
class loaded/imported, you can capture the output as so:And the text is now in
out.capturedtext
: