Help with set_prolog_IO/3

I’m using: SWI-Prolog 64 bits, version 8.1.10-56

I want the code to: I would like to redirect only std err stream to a file.

But what I’m getting is: At the moment I only managed to write everything to a file. I was wondering how could i redirect only the errors. And additionally I would like to add timestamp to error outputs as well, is it possible?

My code looks like this:

create_error_stream :-
    open('/hard_coded_path/output.txt', write, Out, [alias(custom_error)]),
    set_prolog_IO(user_input, custom_error, custom_error), 
    with_output_to(Out, start_main),
    close(Out).
1 Like

I think this is what you need. You were very close. :smiley:

This first example demonstrates the basic code without redirecting the error stream.

io_test_1 :-
    read_string(user_input, "\n", "\r", _, String),
    (
        String = "Error"
    ->
        print_message(error,String)
    ;
        format('~w~n',[String])
    ).

This code modifies the destination of the error stream using set_prolog_IO/3.

This redirects the error stream to a file. The OS is Windows but the file path is easily changed for any specific OS.

io_test_2 :-
    setup_call_cleanup(
        (
            open("C:/Users/Eric/Documents/Projects/Prolog/swi-discourse_032/error.txt",write,Error,[]),
            set_prolog_IO(user_input,user_output,Error)
        ),
        (
            read_string(user_input, "\n", "\r", _, String),
            (
                String = "Error"
            ->
                print_message(error,String)
            ;
                format('~w~n',[String])
            )
        ),
        close(Error)
    ).

Example run without an error

?- io_test_2.
|: Good
Good
true.

Example run with an error that is redirected to a file. Note that error does not appear on the console.

?- io_test_2.
|: Error
true.

Contents of error.txt

ERROR: Unknown message: "Error"

You might also want to take a look at the recently added library(intercept) . I have not had a chance to work with it, but might be using it today with sgml_parse/2


EDIT

Any answer I could give would be a pure guess at this point and there is so much that I would not know how to check, (C code underneath SWI-Prolog predicates) and the entry and exit points along the path.

However if you know all of the errors you want to catch originate via print_message/2 then it might be possible. Just a guess but simple enough to trace though the source code.

@EricGT,

Thank you for your explicit answer, but I have to apologies for not being clear enough. I want to redirect Prolog generated errors. For example: ERROR: [Thread httpsd8000_2] SSL(14094416) ssl3_read_bytes: sslv3 alert certificate unknown .

See https://www.swi-prolog.org/pldoc/doc_for?object=message_hook/3

1 Like

Yes, thank you!

This is what I was looking for, I can add timestamp with this as well, and even save warnings!

Perfect!