Project

Profile

Help

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

    (1-7/7)

    Please register to reply