~ruther/guix-local

4cef56587a874d0e2cdd372b8887415cadbaedcc — Ludovic Courtès 1 year, 3 months ago 3f33cb0
services: Add ‘log-rotation-service-type’.

* gnu/services/admin.scm (%default-log-rotation-calendar-event): New
variable.
(<log-rotation-configuration>): New record type.
(log-rotation-shepherd-services): New procedure.
(log-rotation-service-type): New variable.

Change-Id: I4400035f3b6065ec147ac932110b690120d739c2
2 files changed, 187 insertions(+), 11 deletions(-)

M doc/guix.texi
M gnu/services/admin.scm
M doc/guix.texi => doc/guix.texi +78 -4
@@ 395,7 395,7 @@ Services

* Base Services::               Essential system services.
* Scheduled Job Execution::     The mcron service.
* Log Rotation::                The rottlog service.
* Log Rotation::                Archiving and deleting old logs.
* Networking Setup::            Setting up network interfaces.
* Networking Services::         Firewall, SSH daemon, etc.
* Unattended Upgrades::         Automated system upgrades.


@@ 19230,7 19230,7 @@ declaration.
@menu
* Base Services::               Essential system services.
* Scheduled Job Execution::     The mcron service.
* Log Rotation::                The rottlog service.
* Log Rotation::                Archiving and deleting old logs.
* Networking Setup::            Setting up network interfaces.
* Networking Services::         Firewall, SSH daemon, etc.
* Unattended Upgrades::         Automated system upgrades.


@@ 20873,8 20873,82 @@ is also prefixed by a timestamp by GNU Shepherd.
Log files such as those found in @file{/var/log} tend to grow endlessly,
so it's a good idea to @dfn{rotate} them once in a while---i.e., archive
their contents in separate files, possibly compressed.  The @code{(gnu
services admin)} module provides an interface to GNU@tie{}Rot[t]log, a
log rotation tool (@pxref{Top,,, rottlog, GNU Rot[t]log Manual}).
services admin)} module provides an interface to the log rotation
service provided by the Shepherd (@pxref{Log Rotation,,, shepherd, The
GNU Shepherd Manual}).

This log rotation service is made available through
@code{log-rotation-service-type}, which takes a
@code{log-rotation-configuration} record has its value.  By default,
this provides @code{log-rotation}, a Shepherd ``timed service'' that
runs periodically---once a week by default.  It automatically knows
about the log files produced by Shepherd services and can be taught
about external log files.  You can inspect the service and see when it's
going to run the usual way:

@example
$ sudo herd status log-rotation
Status of log-rotation:
  It is running since Mon 09 Dec 2024 03:27:47 PM CET (2 days ago).
  @dots{}

Upcoming timer alarms:
  Sun 15 Dec 2024 10:00:00 PM CET (in 4 days)
  Sun 22 Dec 2024 10:00:00 PM CET (in 11 days)
  Sun 29 Dec 2024 10:00:00 PM CET (in 18 days)
@end example

You can also list files subject to rotation with @command{herd files
log-rotation} and trigger rotation manually with @command{herd trigger
log-rotation}.

@defvar log-rotation-service-type
This is the type of the log rotation service.  Its associated value must
be a @code{log-rotation-configuration} record, as discussed below.
@end defvar

@c %start of fragment

@deftp {Data Type} log-rotation-configuration
Available @code{log-rotation-configuration} fields are:

@table @asis
@item @code{provision} (default: @code{(log-rotation)}) (type: list-of-symbols)
The name(s) of the log rotation Shepherd service.

@item @code{requirement} (default: @code{(user-processes)}) (type: list-of-symbols)
Dependencies of the log rotation Shepherd service.

@item @code{calendar-event} (type: gexp)
Gexp containing the @dfn{calendar event} when log rotation occurs.
@xref{Timers,,,shepherd,The GNU Shepherd Manual}, for more information
on calendar events.

@item @code{external-log-files} (default: @code{()}) (type: list-of-strings)
List of file names, external log files that should also be rotated.

@item @code{compression} (default: @code{zstd}) (type: symbol)
The compression method used for rotated log files, one of @code{'none},
@code{'gzip}, and @code{'zstd}.

@item @code{expiry} (type: gexp-or-integer)
Age in seconds after which a log file is deleted.

@item @code{size-threshold} (type: gexp-or-integer)
Size in bytes below which a log file is @emph{not} rotated.

@end table

@end deftp


@c %end of fragment

@subheading Rottlog

An alternative log rotation service relying on GNU@tie{}Rot[t]log, a log
rotation tool (@pxref{Top,,, rottlog, GNU Rot[t]log Manual}), is also
provided.

This service is part of @code{%base-services}, and thus enabled by
default, with the default settings, for commonly encountered log files.

M gnu/services/admin.scm => gnu/services/admin.scm +109 -7
@@ 1,6 1,6 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2016 Jan Nieuwenhuizen <janneke@gnu.org>
;;; Copyright © 2016-2024 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2016-2025 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2020 Brice Waegeneire <brice@waegenei.re>
;;; Copyright © 2023 Giacomo Leidi <goodoldpaul@autistici.org>
;;; Copyright © 2024 Gabriel Wicki <gabriel@erlikon.ch>


@@ 45,7 45,18 @@
  #:use-module (srfi srfi-1)
  #:use-module (ice-9 match)
  #:use-module (ice-9 vlist)
  #:export (%default-rotations
  #:export (log-rotation-configuration
            log-rotation-configuration?
            log-rotation-configuration-provision
            log-rotation-configuration-requirement
            log-rotation-configuration-calendar-event
            log-rotation-configuration-external-log-files
            log-rotation-configuration-compression
            log-rotation-configuration-expiry
            log-rotation-configuration-size-threshold
            log-rotation-service-type

            %default-rotations
            %rotated-files

            log-rotation


@@ 112,14 123,105 @@

;;; Commentary:
;;;
;;; This module implements configuration of rottlog by writing
;;; /etc/rottlog/{rc,hourly|daily|weekly}.  Example usage
;;;
;;;     (mcron-service)
;;;     (service rottlog-service-type)
;;; This module provides basic system administration tools: log rotation,
;;; unattended upgrades, etc.
;;;
;;; Code:


;;;
;;; Shepherd's log rotation service.
;;;

(define %default-log-rotation-calendar-event
  ;; Default calendar event when log rotation is triggered.
  #~(calendar-event #:minutes '(0)
                    #:hours '(22)
                    #:days-of-week '(sunday)))

(define (gexp-or-integer? x)
  (or (gexp? x) (integer? x)))

(define-configuration log-rotation-configuration
  (provision
   (list-of-symbols '(log-rotation))
   "The name(s) of the log rotation Shepherd service."
   empty-serializer)
  (requirement
   (list-of-symbols (if for-home? '() '(user-processes)))
   "Dependencies of the log rotation Shepherd service."
   empty-serializer)
  (calendar-event
   (gexp %default-log-rotation-calendar-event)
   "Gexp containing the @dfn{calendar event} when log rotation occurs.
@xref{Timers,,, shepherd, The GNU Shepherd Manual}, for more information on
calendar events."
   empty-serializer)
  (external-log-files
   (list-of-strings '())
   "List of file names, external log files that should also be
rotated."
   empty-serializer)
  (compression
   (symbol 'zstd)
   "The compression method used for rotated log files, one of
@code{'none}, @code{'gzip}, and @code{'zstd}."
   empty-serializer)
  (expiry
   (gexp-or-integer #~(%default-log-expiry))
   "Age in seconds after which a log file is deleted."
   empty-serializer)
  (size-threshold
   (gexp-or-integer #~(%default-rotation-size-threshold))
   "Size in bytes below which a log file is @emph{not} rotated."
   empty-serializer))

(define (log-rotation-shepherd-services config)
  (list (shepherd-service
         (provision (log-rotation-configuration-provision config))
         (requirement (log-rotation-configuration-requirement config))
         (modules '((shepherd service timer)      ;for 'calendar-event'
                    (shepherd service log-rotation)))
         (free-form #~(log-rotation-service
                       #$(log-rotation-configuration-calendar-event config)
                       #:provision
                       '#$(log-rotation-configuration-provision config)
                       #:requirement
                       '#$(log-rotation-configuration-requirement config)
                       #:external-log-files
                       '#$(log-rotation-configuration-external-log-files
                           config)
                       #:compression
                       '#$(log-rotation-configuration-compression config)
                       #:expiry
                       #$(log-rotation-configuration-expiry config)
                       #:rotation-size-threshold
                       #$(log-rotation-configuration-size-threshold
                          config))))))

(define log-rotation-service-type
  (service-type
   (name 'log-rotation)
   (description
    "Periodically rotate log files using the Shepherd's log rotation service.
Run @command{herd status log-rotation} to view its status, @command{herd files
log-rotation} to list files subject to log rotation.")
   (extensions (list (service-extension shepherd-root-service-type
                                        log-rotation-shepherd-services)))
   (compose concatenate)
   (extend (lambda (config log-files)
             (log-rotation-configuration
              (inherit config)
              (external-log-files
               (append (log-rotation-configuration-external-log-files config)
                       log-files)))))
   (default-value (log-rotation-configuration))))


;;;
;;; Rottlog + mcron.
;;;

(define-record-type* <log-rotation> log-rotation make-log-rotation
  log-rotation?
  (files       log-rotation-files)                ;list of strings