Forums » Saxon/C Help and Discussions »
Integrate Python logger or redirect stdin and stdout?
Added by Eliot Kimber 7 months ago
I've got Saxonche working in a Python environment where I'm calling it from a little TKInter GUI that provides a logging panel for reflecting the messages from processes run by the GUI.
I'm not seeing an obvious way to have messages emitted by Saxon redirected from stdout/stderr to my own buffer or a different logger.
In Java I would configure my own logger class.
I didn't find anything in the API docs or code samples--they all just use print() to produce messages.
I tried just redirecting sys.stderr and sys.stdout to my own buffer, which works for other Python contexts (i.e., in a Pytest test where you want to evaluate the output of some function) but didn't seem to work here.
I also see that PyXsltExecutable's setProperty() method includes the "m" option to turn on the message listener but I'm not finding anything about how to get or set the message listener itself from the API docs.
Is there a way to do this?
Thanks,
Eliot
Replies (7)
Please register to reply
RE: Integrate Python logger or redirect stdin and stdout? - Added by O'Neil Delpratt 7 months ago
There are a number of options . Yes the default is to output to stdout/stderr. You can turn them on/off, save to file or capture them and return them in an PyXdmValue. To start with see: https://www.saxonica.com/documentation12/index.html#!using-xsl/stylesheet-output/message-output
Also see https://www.saxonica.com/saxon-c/doc12/html/saxonc.html#PyXsltExecutable-set_save_xsl_message
RE: Integrate Python logger or redirect stdin and stdout? - Added by Eliot Kimber 7 months ago
Thanks--that's the docs I was looking for. Should have looked harder.
Am I understanding correctly that there's no way in the Python context to provide a custom handler that will report the messages as they are emitted?
For a longer-running process it would be ideal to show progress as it occurs.
RE: Integrate Python logger or redirect stdin and stdout? - Added by O'Neil Delpratt 7 months ago
That is correct, a custom handler is not currently supported in python.
RE: Integrate Python logger or redirect stdin and stdout? - Added by Eliot Kimber 7 months ago
I'm getting an NPE when I try setting a filename on the executable:
Python code:
message_path: str = output_dir.joinpath('xslt-messages.xml').as_posix()
executable.set_save_xsl_message(True, message_path);
executable.transform_to_file(xdm_node=document)
Which results in this exception:
[ERROR] Exception running transform: NullPointer exception found: net.sf.saxon.s9api.SaxonApiException
at net.sf.saxon.option.cpp.Xslt30Processor.transformToFile(Xslt30Processor.java:1585)
Caused by: java.lang.NullPointerException
at net.sf.saxon.option.cpp.SaxonCMessageListener.<init>(SaxonCMessageListener.java:46)
at net.sf.saxon.option.cpp.Xslt30Processor.applyXsltTransformerProperties(Xslt30Processor.java:1716)
at net.sf.saxon.option.cpp.Xslt30Processor.transformToFile(Xslt30Processor.java:1561)
I've verified that the message_path
variable has a value itself.
If I don't specify a filename then the processing works as expected--I get messages echoed to stdout and I can get the messages using executable.get_xsl_messages()
.
RE: Integrate Python logger or redirect stdin and stdout? - Added by Eliot Kimber 7 months ago
I also noticed that if I reuse a PyXsltExecutable, that the messages will accumulate across calls to transform_to_*() unless I do this:
executable.set_save_xsl_message(False)
executable.set_save_xsl_message(True)
Which works, thankfully, but it would be nice if there was a "clear_messages()" method or something similar.
RE: Integrate Python logger or redirect stdin and stdout? - Added by O'Neil Delpratt 7 months ago
Eliot Kimber wrote in RE: Integrate Python logger or redirect stdin and stdout?:
I'm getting an NPE when I try setting a filename on the executable:
Python code:
message_path: str = output_dir.joinpath('xslt-messages.xml').as_posix() executable.set_save_xsl_message(True, message_path); executable.transform_to_file(xdm_node=document)
Which results in this exception:
[ERROR] Exception running transform: NullPointer exception found: net.sf.saxon.s9api.SaxonApiException at net.sf.saxon.option.cpp.Xslt30Processor.transformToFile(Xslt30Processor.java:1585) Caused by: java.lang.NullPointerException at net.sf.saxon.option.cpp.SaxonCMessageListener.<init>(SaxonCMessageListener.java:46) at net.sf.saxon.option.cpp.Xslt30Processor.applyXsltTransformerProperties(Xslt30Processor.java:1716) at net.sf.saxon.option.cpp.Xslt30Processor.transformToFile(Xslt30Processor.java:1561)
I've verified that the
message_path
variable has a value itself.If I don't specify a filename then the processing works as expected--I get messages echoed to stdout and I can get the messages using
executable.get_xsl_messages()
.
Thanks for reporting this. I have created the following bug issue for it #6401
RE: Integrate Python logger or redirect stdin and stdout? - Added by O'Neil Delpratt 7 months ago
Eliot Kimber wrote in RE: Integrate Python logger or redirect stdin and stdout?:
I also noticed that if I reuse a PyXsltExecutable, that the messages will accumulate across calls to transform_to_*() unless I do this:
executable.set_save_xsl_message(False) executable.set_save_xsl_message(True)
Which works, thankfully, but it would be nice if there was a "clear_messages()" method or something similar.
I have created a feature request here #6402
Please register to reply