unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
From: Maxim Cournoyer <maxim.cournoyer@gmail.com>
To: guile-devel <guile-devel@gnu.org>
Cc: David Pirotte <david@altosw.be>
Subject: [guile-lib] (logging logger) doesn't call flush-log after each log
Date: Tue, 02 Jan 2024 21:54:22 -0500	[thread overview]
Message-ID: <87o7e36s9t.fsf@gmail.com> (raw)

Hi,

I've recently made use of guile-lib's logging library, and was surprised
that by default the rotating-log logger, which logs to a file, would
write to a file using block buffering, which would means logs would only
be seen added to the file every now and then rather than in real time.

That breaks a common expectation of log files, which can typically be
tail'd -f to see a program output as it runs.

I've come up with this workaround:

--8<---------------cut here---------------start------------->8---
    ;; Ensure log messages are written in real time, not block
    ;; buffered.
    (setvbuf (slot-ref rotating 'port) 'line)))
--8<---------------cut here---------------end--------------->8---

But it was not easily discovered and still doesn't feel exactly 'real
time'.  The Python logging library, which is the inspiration for this
one, calls 'flush' after each log message is written in the base class
from which all handlers inherit (see Lib/logging/__init__.py):

--8<---------------cut here---------------start------------->8---
class StreamHandler(Handler):
    """
    A handler class which writes logging records, appropriately formatted,
    to a stream. Note that this class does not close the stream, as
    sys.stdout or sys.stderr may be used.
    """

    terminator = '\n'

    def __init__(self, stream=None):

[...]

    def flush(self):
        """
        Flushes the stream.
        """
        self.acquire()
        try:
            if self.stream and hasattr(self.stream, "flush"):
                self.stream.flush()
        finally:
            self.release()

    def emit(self, record):
        """
        Emit a record.

        If a formatter is specified, it is used to format the record.
        The record is then written to the stream with a trailing newline.  If
        exception information is present, it is formatted using
        traceback.print_exception and appended to the stream.  If the stream
        has an 'encoding' attribute, it is used to determine how to do the
        output to the stream.
        """
        try:
            msg = self.format(record)
            stream = self.stream
            # issue 35046: merged two stream.writes into one.
            stream.write(msg + self.terminator)
            self.flush()
        except RecursionError:  # See issue 36272
            raise
        except Exception:
            self.handleError(record)

[...]
--8<---------------cut here---------------end--------------->8---

This would be easy to do in our logger implementation (we'd call
'flush-log' at the end of 'emit-log'), if we agree it's a good idea.

Would anyone be opposed to that?  If not, I'll happily send a patch.

-- 
Thanks,
Maxim



                 reply	other threads:[~2024-01-03  2:54 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/guile/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87o7e36s9t.fsf@gmail.com \
    --to=maxim.cournoyer@gmail.com \
    --cc=david@altosw.be \
    --cc=guile-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).