Newlisp and Dzen2
Posted: Fri Apr 06, 2012 2:26 am
Hi again
It's been a while, but I still use new lisp for various things as time permit. In this case this is more of a study in system or utilities than anything else.
One piece of software I've been dabbling of late is called dzen2. For more information you can go to http://sites.google.com/site/gotmor/dzen. Dzen2 is a generic information application akin to conky, but it does not contain any intelligence in terms of monitoring. It accepts information from system input and display them in X. It has some auxiliary programs available for use that are used to create bars and menus.
What I did was to write a small monitoring application for dzen in newlisp in which gathers monitoring data and display them into dzen through the use of pipes. The annotated code is here and hopefully it will make sense.
One thing I noticed while writing this even though I've used perl and dabbled with scsh, newlisp is not slouch when it comes of handling output from command line tools in which a lot of output manipulation can be effectively done with fairly little code. Hopefully it'll be evident in the enclosed program.
It's been a while, but I still use new lisp for various things as time permit. In this case this is more of a study in system or utilities than anything else.
One piece of software I've been dabbling of late is called dzen2. For more information you can go to http://sites.google.com/site/gotmor/dzen. Dzen2 is a generic information application akin to conky, but it does not contain any intelligence in terms of monitoring. It accepts information from system input and display them in X. It has some auxiliary programs available for use that are used to create bars and menus.
What I did was to write a small monitoring application for dzen in newlisp in which gathers monitoring data and display them into dzen through the use of pipes. The annotated code is here and hopefully it will make sense.
One thing I noticed while writing this even though I've used perl and dabbled with scsh, newlisp is not slouch when it comes of handling output from command line tools in which a lot of output manipulation can be effectively done with fairly little code. Hopefully it'll be evident in the enclosed program.
Code: Select all
#!/opt/home/papo/bin/newlisp
;; Appareance
;; NOTE: Although these can be used, the only one really in use is
;; SEPARATOR.
(define BACKGROUND-COLOR "'#2c2c32'")
(define ALTERNATE-BACKGROUND-COLOR "'#494b4f'")
(define FOREGROUND-COLOR "'grey70'")
(define SEPARATOR "^p(3)^r(3x3)^p(3)")
(define FONT "fixed")
;; DZEN requires to have regular updates. Even though this is not use
;; right now it is set up every 10 seconds.
;; Main loop interval in seconds
(define SLEEP-INTERVAL 1)
;; Signal handler to exit and not to get stuck in debug mode.
(constant 'SIGINT 2)
(define (ctrlC-handler)
(exit)
)
(signal SIGINT 'ctrlC-handler)
;; This gets the results of df
(define (get-disk)
(setq df-results (exec "df"))
; The map is used to get the attributes that we want to monitor.
(map (fn (x)
(let ((y (parse x)))
(list (nth 0 y) (nth 4 y))
))
; Using rest removes the header in one swoop.
(rest df-results))
)
;; There is a better way by writing using format, but I'm being lazy
;; This executes gdbar and get a graphical representation of a dzen bar.
;;
(define (get-dbar fs per)
; By duing first, we get the string needed to write the bar
(first (exec (append "echo " per "| gdbar -l " fs) ))
)
;
; This will iterate from the df results and only
; get the bar to the ones we care about. In this case
; only the ones mounted in cemnt. This can be changed, of course.
(define (get-dbar-results)
(let ((df-result (get-disk)) )
(map (fn (x)
(if (not (nil? (find "cemnt" (first x)) ))
(get-dbar (last (parse (first x) "/")) (nth 1 x)) ))
df-result))
)
;;
;; Same for the memory, get the results from free;
;;
(define (get-free)
(setq free-results (exec "free"))
; We only need the totals that are at the end.
(parse (last free-results))
)
;;
;; We get the bar by computing the percentage of
;; Free / Total
;; And get the resultant bar representation.
;;
(define (get-mem-dbar-results)
(setq free-result (get-free))
(get-dbar "MEM:"
(string (round (mul
(div
(float (nth 2 free-result))
(float (nth 1 free-result))) 100 ) 0) ) )
)
;
; Main
;
(define (main)
; These pipes are used to communicate the results to the dzen2 process
; This way results are display without annoying blinks.
;
(map set '(myin bcout) (pipe))
(map set '(bcin myout) (pipe))
; Call dzen2 in the background, we only need bcin pipe.
(setq pid (process "dzen2 -bg gray10 -x 200 -p -ta r " bcin 0))
; Main loop, what it does is
; get the statistics and write them into
; the dzen2 process
(while (not nil)
(map (fn (x)
(if (not (nil? (find "sd" x)))
(write myout (format "%s " x))) )
(get-dbar-results))
(write myout SEPARATOR)
(write myout " ")
(write myout (get-mem-dbar-results))
(write myout " ")
;
; dzen2 provides a gcpu bar. In linux, you can create a process
; that reads from /proc. But I'm being lazy being program does the work.
; gcpubar works akin as vmstat, you need to get the second one
; to get an actual measure. In this case, there are 5 iterations
; and the last one is selected.
(write myout (last (exec "gcpubar -i 1 -c 5 ")))
(write-line myout)
; Wait 10 seconds
(sleep 10000)
)
; Probably these should be moved in the signal handler.
(destroy pid)
)
;Start here.
(main)