From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Maxim Cournoyer Newsgroups: gmane.lisp.guile.devel Subject: [Guile-Lib PATCH] logger: Add flush-after-emit? property to . Date: Fri, 1 Mar 2024 23:15:55 -0500 Message-ID: <20240302041612.29833-1-maxim.cournoyer@gmail.com> Mime-Version: 1.0 Content-Transfer-Encoding: 8bit Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="31418"; mail-complaints-to="usenet@ciao.gmane.io" Cc: David Pirotte , Maxim Cournoyer To: guile-devel@gnu.org Original-X-From: guile-devel-bounces+guile-devel=m.gmane-mx.org@gnu.org Sat Mar 02 05:16:41 2024 Return-path: Envelope-to: guile-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1rgGng-0007x9-Vb for guile-devel@m.gmane-mx.org; Sat, 02 Mar 2024 05:16:41 +0100 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rgGnU-0006dN-VM; Fri, 01 Mar 2024 23:16:28 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rgGnU-0006dC-7A for guile-devel@gnu.org; Fri, 01 Mar 2024 23:16:28 -0500 Original-Received: from mail-oi1-x22f.google.com ([2607:f8b0:4864:20::22f]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1rgGnR-0007RB-VR for guile-devel@gnu.org; Fri, 01 Mar 2024 23:16:27 -0500 Original-Received: by mail-oi1-x22f.google.com with SMTP id 5614622812f47-3c19bc08f96so2356210b6e.2 for ; Fri, 01 Mar 2024 20:16:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1709352983; x=1709957783; darn=gnu.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=yJV+X8jja7ZAqZ0HY8hTt6vqIl3SGTdYme1FsERQIOk=; b=k6c7HE4EMTndtEdtFaUX2e6aodyoe9SNbGmb1yrzcc1zxQyifmWGygAv+PGEY+UJ2D misxZQ+h6NWf6hqlqZodquv0XE7xajnjrGZHWklsQYmh2Atgq58bj4afboqBliPb5k2P W5z23nx1pM8QdPETkm+L//QtN2i30Gz0gSrBeS0/9crDIniCxlCDqBAcLE8aw3bm+4dT fkihU0qjTFiwbVT1ce0AiJVP+lqn0mGZM28lz22K539kCyGBzQiYer4s24y9ZqbFtzvG 4kkLVn9TZUXrvw/e5GipXCnp7rQ8PCvp+mRv8tM7nAeqR6LhJ6c6UoqcQz1hz7524HAS Y8Ng== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1709352983; x=1709957783; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=yJV+X8jja7ZAqZ0HY8hTt6vqIl3SGTdYme1FsERQIOk=; b=rbvTmCh/eyXsAhf0X41a0GrRP0WcaAb4FX1J3pnyEw2vDG27KjxYw1M19uDGIXY6v9 Y/RhwD52yS3MPI6bkPPPno9nUfeHRgA4Hl6DEwflieSVwwXGukG4aqB/9jhDkRHPQTQp N3awshlgLbRkUHhBaGGR+Kouv+55E9ElOo8nkrnSV4LqYiTHEQbp/n1+OqcF8S5o0aqO FWmBTL9lD3Qi83yE23Quo0s4gZXZEPyJ0vJ3v7uPcq/tOthfC+b85mE/kAdkdeF/4lA2 b/BZXDvaOPnsk42L4vPyDNoAvDSPrZRI32VsSlJzpMhEmOolZILroYJiiEw3LR6DwuIX PoxA== X-Gm-Message-State: AOJu0Yza47zRZ6KnzcJB30YZKYTBXF5YRRI1E9Fl3kUOYKgeFHhkHABO aQ+Iqwx2beV8sEiCuQ4WVJ6sIvjDHrZzG+rmNWiQwOo13PR0nBmOX0M88DNR X-Google-Smtp-Source: AGHT+IF4+0o1w71ygV45SN/wxMtTz0uSaifloqRwNikQhCoJIgzJqwgBBWc1yFAzUUCoq4f0nqHhWA== X-Received: by 2002:a05:6359:4c0e:b0:17b:ee7d:f957 with SMTP id kj14-20020a0563594c0e00b0017bee7df957mr4313511rwc.15.1709352983352; Fri, 01 Mar 2024 20:16:23 -0800 (PST) Original-Received: from localhost.localdomain (dsl-151-94.b2b2c.ca. [66.158.151.94]) by smtp.gmail.com with ESMTPSA id t5-20020ac87605000000b0042e93e97957sm2328836qtq.34.2024.03.01.20.16.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 01 Mar 2024 20:16:22 -0800 (PST) X-Mailer: git-send-email 2.41.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::22f; envelope-from=maxim.cournoyer@gmail.com; helo=mail-oi1-x22f.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: guile-devel@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Developers list for Guile, the GNU extensibility library" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guile-devel-bounces+guile-devel=m.gmane-mx.org@gnu.org Original-Sender: guile-devel-bounces+guile-devel=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.lisp.guile.devel:22332 Archived-At: * src/logging/logger.scm (): Add new optional flush-after-each-emit? slot, initialized to #t. (accept-log) [flush-after-each-emit?]: Flush log when condition is true. * unit-tests/logging.logger.scm (call-with-temporary-file): New procedure. (test-log-with-flush-after-emit-disabled): New test. (test-log-with-flush-after-emit): Likewise. Suggested-by: David Pirotte --- src/logging/logger.scm | 21 ++++++++++++++++----- unit-tests/logging.logger.scm | 31 +++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/src/logging/logger.scm b/src/logging/logger.scm index 6e488f6..0bec407 100644 --- a/src/logging/logger.scm +++ b/src/logging/logger.scm @@ -309,7 +309,7 @@ message was logged from." str))) (define-class-with-docs () -"This is the base class for all of the log handlers, and encompasses + "This is the base class for all of the log handlers, and encompasses the basic functionality that all handlers are expected to have. Keyword arguments recognized by the @code{} at creation time are: @@ -328,9 +328,18 @@ output looks like: \"The servers are melting!\") ==> \"2003/12/29 14:53:02 (CRITICAL): The servers are melting!\" @end lisp +@item #:flush-after-emit? +This optional parameter defaults to @code{#t}, to ensure users can +tail the logs output in real time. In some cases, such as when +logging very large output to a file, it may be preferable to set this +to @code{#f}, to let the default block buffering mode of the +associated file port reduce write pressure on the file system. @end table" - (formatter #:init-value default-log-formatter #:getter log-formatter #:init-keyword #:formatter) - (levels #:init-form (make-hash-table 17) #:getter levels)) + (formatter #:init-value default-log-formatter #:getter log-formatter + #:init-keyword #:formatter) + (levels #:init-form (make-hash-table 17) #:getter levels) + (flush-after-emit? #:init-value #t #:getter flush-after-emit? + #:init-keyword #:flush-after-emit?)) (define-generic-with-docs add-handler! "@code{add-handler! lgr handler}. Adds @var{handler} to @var{lgr}'s list of handlers. All subsequent @@ -364,7 +373,8 @@ override this behavior.") ;; Legacy variant without source-properties argument. (when (level-enabled? self level) (emit-log self ((log-formatter self) level time str)) - (flush-log self))) + (when (flush-after-emit? self) + (flush-log self)))) (define-method (accept-log (self ) level time str source-properties proc-name) @@ -372,7 +382,8 @@ override this behavior.") (emit-log self ((log-formatter self) level time str #:source-properties source-properties #:proc-name proc-name)) - (flush-log self))) + (when (flush-after-emit? self) + (flush-log self)))) ;; This should be overridden by all log handlers to actually ;; write out a string. diff --git a/unit-tests/logging.logger.scm b/unit-tests/logging.logger.scm index 534c65e..2cead80 100644 --- a/unit-tests/logging.logger.scm +++ b/unit-tests/logging.logger.scm @@ -21,8 +21,15 @@ (use-modules (unit-test) (logging logger) (logging port-log) + (ice-9 textual-ports) (oop goops)) +(define* (call-with-temporary-file proc #:key (mode "w+")) + "Open a temporary file name and pass it to PROC, a procedure of one +argument. The port is automatically closed." + (let ((port (mkstemp "file-XXXXXX" mode))) + (call-with-port port proc))) + (define-class ()) (define-method (test-log-to-one-port (self )) @@ -65,4 +72,28 @@ (assert (string-contains (get-output-string strport) " unit-tests/logging.logger.scm:63:4: ")))) +(define-method (test-log-with-flush-after-emit-disabled (self )) + "Test the case where flush-after-emit? on the handler is false." + (call-with-temporary-file + (lambda (port) + (setvbuf port 'block 1000000) ;large 1MB buffer + (let ((lgr (make + #:handlers (list (make #:port port + #:flush-after-emit? #f))))) + (log-msg lgr 'ERROR "this should be buffered, i.e. not written yet") + (assert (string-null? + (call-with-input-file (port-filename port) get-string-all))))))) + +(define-method (test-log-with-flush-after-emit (self )) + "Test the default case where flush-after-emit? on the handler is true." + (call-with-temporary-file + (lambda (port) + (setvbuf port 'block 1000000) ;large 1MB buffer + (let ((lgr (make + #:handlers (list (make #:port port))))) + (log-msg lgr 'ERROR "this should be flushed to disk after emit") + (assert (string-contains + (call-with-input-file (port-filename port) get-string-all) + "this should be flushed to disk after emit")))))) + (exit-with-summary (run-all-defined-test-cases)) base-commit: af929893752b076f367d9d18d2b5e0e8ac12bf7b -- 2.41.0