unofficial mirror of guix-patches@gnu.org 
 help / color / mirror / code / Atom feed
* [bug#44460] [PATCH] processes: Optionally normalize recutils output.
@ 2020-11-05  4:31 John Soo
  2020-11-05 15:49 ` [bug#44460] processes: Don't normalize Locks John Soo
                   ` (2 more replies)
  0 siblings, 3 replies; 14+ messages in thread
From: John Soo @ 2020-11-05  4:31 UTC (permalink / raw)
  To: 44460

[-- Attachment #1: Type: text/plain, Size: 1473 bytes --]

Hi Guix,

Please let me know if there is already a way to do what I want without
this patch :). I really don't know a whole lot of recutils beyond what I
learned this morning.

I was trying to extract PIDs of the child processes of sessions from the
output of guix processes.  I ran into the following problem: the PID and
the command are on the same line.

---- Begin ----
$ guix processes
SessionPID: 4278
ClientPID: 4268
ClientCommand: /gnu/store/...
ChildProcess: 4435: /gnu/store/...
ChildProcess: 4554: /gnu/store/...
ChildProcess: 4646: guile --no-auto-compile ...
---- End ----

I ended up having to use sed to remove the trailing command for the
child process.  After reading the documentation for recutils I found out
that records can also be expressed in separate record sets that can be
joined together. 

This patch adds a --normalize flag that specifies the
recutils output be put in separate record sets for Locks, Sessions, and
ChildProcesses.  For example:

---- Begin ----
PAGER=cat ./pre-inst-env guix processes --normalize
%rec: Session
%type: PID int
%type: ClientPID int
%key: PID

PID: 4278
ClientPID: 4268
ClientCommand: /gnu/store/...

%rec: Lock
%type: Session rec Session

%rec: ChildProcess
%type: Session rec Session
%type: PID int
%key: PID

Session: 4278
PID: 4435
Command: /gnu/store/...

Session: 4278
PID: 4554
Command: /gnu/store/...

Session: 4278
PID: 4646
Command: guile --no-auto-compile ...

---- End ----

What do you think?

John


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-processes-Optionally-normalize-recutils-output.patch --]
[-- Type: text/x-patch, Size: 7068 bytes --]

From 9c04e2d184977c95090ec237a6bc0334ee14a8e7 Mon Sep 17 00:00:00 2001
From: John Soo <jsoo1@asu.edu>
Date: Wed, 4 Nov 2020 07:51:52 -0800
Subject: [PATCH] processes: Optionally normalize recutils output.

* guix/scripts/processes.scm: Add "normalize" flag
---
 doc/guix.texi              |  26 ++++++++
 guix/scripts/processes.scm | 121 +++++++++++++++++++++++++++++++++----
 2 files changed, 135 insertions(+), 12 deletions(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index 5e3e0435b4..ed54c26072 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -12691,6 +12691,32 @@ ClientPID: 19419
 ClientCommand: cuirass --cache-directory /var/cache/cuirass @dots{}
 @end example
 
+Additional options are listed below.
+
+@table @code
+@item --normalize
+Normalize the output records into record sets (@pxref{Record Sets,,,
+recutils, GNU recutils manual}).  Normalizing into record sets allows
+joins across record types.
+
+@example
+$ guix processes --normalize | \
+    recsel \
+    -j Session \
+    -t ChildProcess \
+    -p Session.PID,PID \
+    -e 'Session.ClientCommand ~ build'
+Session_PID: 4278
+PID: 4435
+
+Session_PID: 4278
+PID: 4554
+
+Session_PID: 4278
+PID: 4646
+@end example
+@end table
+
 @node System Configuration
 @chapter System Configuration
 
diff --git a/guix/scripts/processes.scm b/guix/scripts/processes.scm
index b4ca7b1687..11cfd561b9 100644
--- a/guix/scripts/processes.scm
+++ b/guix/scripts/processes.scm
@@ -176,6 +176,9 @@ active sessions, and the master 'guix-daemon' process."
     (values (filter-map child-process->session children)
             master)))
 
+(define (lock->record lock port)
+  (format port "LockHeld: ~a~%" lock))
+
 (define (daemon-session->recutils session port)
   "Display SESSION information in recutils format on PORT."
   (format port "SessionPID: ~a~%"
@@ -184,8 +187,7 @@ active sessions, and the master 'guix-daemon' process."
           (process-id (daemon-session-client session)))
   (format port "ClientCommand:~{ ~a~}~%"
           (process-command (daemon-session-client session)))
-  (for-each (lambda (lock)
-              (format port "LockHeld: ~a~%" lock))
+  (for-each (lambda (lock) (lock->record lock port))
             (daemon-session-locks-held session))
   (for-each (lambda (process)
               (format port "ChildProcess: ~a:~{ ~a~}~%"
@@ -193,6 +195,98 @@ active sessions, and the master 'guix-daemon' process."
                       (process-command process)))
             (daemon-session-children session)))
 
+(define (format-single-record port)
+  "Display denormalized session information to PORT."
+  (for-each (lambda (session)
+              (daemon-session->recutils session port)
+                (newline port))
+            (daemon-sessions)))
+
+(define session-rec-type
+  ;; Also includes ClientCommand but it doesn't seem to be possible to express
+  ;; a plain string field (the default) without further restrictions
+  "%rec: Session
+%type: PID int
+%type: ClientPID int
+%key: PID")
+
+(define lock-rec-type
+  ;; Also includes LockHeld but it doesn't seem to be possible to express
+  ;; a plain string field (the default) without further restrictions
+  "%rec: Lock
+%type: Session rec Session")
+
+(define child-process-rec-type
+  ;; Also includes Command but it doesn't seem to be possible to
+  ;; express a plain string field (the default) without further restrictions
+  "%rec: ChildProcess
+%type: Session rec Session
+%type: PID int
+%key: PID")
+
+(define (session-pid-key->field session port)
+  "Display SESSION PID as field on PORT."
+  (format
+   port "Session: ~a"
+   (process-id (daemon-session-process session))))
+
+(define (session-scalars->normalized-record session port)
+  "Display SESSION scalar fields to PORT in normalized form."
+  (format port "PID: ~a~%"
+          (process-id (daemon-session-process session)))
+  (format port "ClientPID: ~a~%"
+          (process-id (daemon-session-client session)))
+  (format port "ClientCommand:~{ ~a~}~%"
+          (process-command (daemon-session-client session))))
+
+(define (child-process->normalized-record process port)
+  "Display PROCESS record on PORT in normalized form"
+  (format port "PID: ~a" (process-id process))
+  (newline port)
+  (format port "Command:~{ ~a~}" (process-command process)))
+
+(define (format-normalized port)
+  (define sessions (daemon-sessions))
+
+  (format port session-rec-type)
+  (newline port)
+  (newline port)
+  (for-each
+   (lambda (session)
+     (session-scalars->normalized-record session port))
+   sessions)
+  (newline port)
+
+  (format port lock-rec-type)
+  (newline port)
+  (newline port)
+  (for-each
+   (lambda (session)
+     (for-each
+      (lambda (lock)
+        (session-pid-key->field session port)
+        (newline port)
+        (lock->record lock port)
+        (newline port)
+        (newline port))
+      (daemon-session-locks-held session)))
+   sessions)
+
+  (format port child-process-rec-type)
+  (newline port)
+  (newline port)
+  (for-each
+   (lambda (session)
+     (for-each
+      (lambda (process)
+        (session-pid-key->field session port)
+        (newline port)
+        (child-process->normalized-record process port)
+        (newline port)
+        (newline port))
+      (daemon-session-children session)))
+   sessions))
+
 \f
 ;;;
 ;;; Options.
@@ -205,7 +299,10 @@ active sessions, and the master 'guix-daemon' process."
                   (exit 0)))
         (option '(#\V "version") #f #f
                 (lambda args
-                  (show-version-and-exit "guix processes")))))
+                  (show-version-and-exit "guix processes")))
+        (option '("normalize") #f #f
+                (lambda (opt name arg result)
+                  (alist-cons 'normalize #t result)))))
 
 (define (show-help)
   (display (G_ "Usage: guix processes
@@ -216,8 +313,13 @@ List the current Guix sessions and their processes."))
   (display (G_ "
   -V, --version          display version information and exit"))
   (newline)
+  (display (G_ "
+  --normalize            display results as normalized record sets"))
+  (newline)
   (show-bug-report-information))
 
+(define %default-options '())
+
 \f
 ;;;
 ;;; Entry point.
@@ -227,17 +329,12 @@ List the current Guix sessions and their processes."))
   (category plumbing)
   (synopsis "list currently running sessions")
   (define options
-    (args-fold* args %options
-                (lambda (opt name arg result)
-                  (leave (G_ "~A: unrecognized option~%") name))
-                cons
-                '()))
+    (parse-command-line args %options (list %default-options)))
 
   (with-paginated-output-port port
-    (for-each (lambda (session)
-                (daemon-session->recutils session port)
-                (newline port))
-              (daemon-sessions))
+    (match (assoc-ref options 'normalize)
+      (#t (format-normalized port))
+      (_ (format-single-record port)))
 
     ;; Pass 'R' (instead of 'r') so 'less' correctly estimates line length.
     #:less-options "FRX"))
-- 
2.29.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2020-11-29 22:51 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-05  4:31 [bug#44460] [PATCH] processes: Optionally normalize recutils output John Soo
2020-11-05 15:49 ` [bug#44460] processes: Don't normalize Locks John Soo
2020-11-05 16:01 ` [bug#44460] Fixup the output of Session John Soo
2020-11-06 23:34 ` [bug#44460] Add copyright lines John Soo
2020-11-10 22:15   ` Ludovic Courtès
2020-11-11 17:51     ` John Soo
2020-11-11 17:59       ` John Soo
2020-11-11 18:47         ` John Soo
2020-11-12 10:58       ` Ludovic Courtès
2020-11-12 15:37         ` John Soo
2020-11-12 20:29           ` Ludovic Courtès
2020-11-13  5:33             ` John Soo
2020-11-13 16:16               ` John Soo
2020-11-29 22:49                 ` bug#44460: " Ludovic Courtès

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

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).