jupyter-xeus / xeus-r

Jupyter kernel for the R programming language
Other
40 stars 5 forks source link

logging R related messages #62

Open romainfrancois opened 7 months ago

romainfrancois commented 7 months ago

As of #61, we have the log_debug(), log_info() and log_info() functions on the R side that end up calling xeusr_log() which at the moment does not do much of anything:

SEXP xeusr_log(SEXP level_, SEXP msg_) {
    std::string level = CHAR(STRING_ELT(level_, 0));
    std::string msg = CHAR(STRING_ELT(msg_, 0));

    // TODO: actually do some logging
    return R_NilValue;
}

I've read the Logger section in kernel_customization.rst but I don't understand how to send log messages to these loggers.

Logger
------

``xeus`` does not log anything by default. However, it can be useful during the development phase of a new
kernel to print the messages that are received by and sent from the kernel. Having a logger that can
be enabled on-demand is also useful to track bugs once your new kernel has been released.

``xeus`` provides a flexible logging mechanism that can be easily extended. Two default loggers are
available: one that logs to the console, and another one that logs to files. You can add your own
by defining a class that inherit from ``xlogger``. Three logging levels are provided, one for message type,
one for the content of the message and one for the full message. Loggers can be chained, meaning you can log
the message types to the console and the full messages into files:

.. code::

    int main(int argc, char* argv[])
    {
        // ....
        // Instantiates interpreter and config
        // ....
        auto logger = xeus::make_console_logger(xeus::xlogger::msg_type,
                                                xeus::make_file_logger(xeus::xlogger::full, "my_log_file.log"));
        xeus::xkernel kernel(config,
                             xeus::get_user_name(),
                             interpreter,
                             xeus::make_in_memory_history_manager(),
                             std::move(logger));
        kernel.start();
        return 0;

    }

To turn on logging, you need to define the variable environment ``XEUS_LOG`` before starting the kernel. This way,
enabling and disabling the logs do not require to rebuild the kernel.

Defining a new type of logger is as simple as defining a new type of history manager: inherit from ``xlogger``
and implement the abstract methods:

.. code::

    class my_logger : public xeus::xlogger
    {
    public:

        my_logger();
        virtual ~mylogger();

    private:

        void log_received_message_impl(const xmessage& message, channel c) const override;
        void log_sent_message_impl(const xmessage& message, channel c) const override;
        void log_iopub_message_impl(const xpub_message& message) const override;

        void log_message_impl(const std::string& socket_info,
                                      const nl::json& header,
                                      const nl::json& parent_header,
                                      const nl::json& metadata,
                                      const nl::json& content) const override;
    };