Rackonsole: Lightweight Operator Console for Racket Server Processes
(require (planet neil/rackonsole:1:0)) |
1 Introduction
ProTip: In 2012, spelling “server” as “cloud server” gets you more money.
1.1 Features
View logging information from the application, including ability to change both what levels of log messages are captured and which are displayed on the screen. So, for example, Rackonsole might be capturing all log levels at the moment, but the operator can temporarily narrow the display to only errors. The operator can also increase and lower the level of messages captured dynamically, to adjust the balance between information and performance.
Quit the application in a manner specified by the developer, rather than merely Ctrl-C-ing or sending other signals that might not cause an orderly shutdown. The application can specify a shutdown procedure in the code, in the call to rackonsole.
Generate debugging information to provide to a developer who does not have access to the server. In the current version, this is via gdbdump.
A sense that the application is running. Also, by default, the title includes the application name and server name, for ease when dealing with multiple applications and servers.
1.2 Easy to Add
"myserver.rkt"
#lang racket (require "myinternals.rkt") (for ((request (my-start-server))) (with-handlers ((exn:fail? (lambda (exn) (log-error (string-append "Request failed: " (exn-message exn)))))) (my-handle-request request)))
Talk about rapid agile development!
"myserver.rkt"
#lang racket (require "myinternals.rkt" (planet neil/rackonsole)) (thread rackonsole) (for ((request (my-start-server))) (with-handlers ((exn:fail? (lambda (exn) (log-error (string-append "Request failed: " (exn-message exn)))))) (my-handle-request request)))
"myserver.rkt"
#lang racket (require "myinternals.rkt" (planet neil/rackonsole)) (thread (lambda () (rackonsole #:title "MyApp 2000" #:capture-level 'warning #:quit-proc (lambda () (display "Farewell!\n") (exit))))) (for ((request (my-start-server))) (with-handlers ((exn:fail? (lambda (exn) (log-error (string-append "Request failed: " (exn-message exn)))))) (my-handle-request request)))
1.3 See a Demo
2 User Interface
Title —
The Title is usually the upper-left corner, in reverse-video, and usually identifies the application and/or server. Status —
The Status is usually the upper-right corner, and displays the current state of the capture level and view level. (If the terminal is not wide enough to put both the Title and Status on the same row, such as if the Title is long, then both are centered on their own rows.) Menu —
The Menu is centered below the Title and Status, and usually underlined. It identifies which menu it is, and shows a list of keys that can be pressed, with each key surrounded by square brackets. Menus that are not the Main menu can generally be escaped out of by pressing the - (minus), Backspace, Esc key. (Additionally, the Quit menu is escaped by any key that is not the Y key, to decrease the likelihood of quitting the application accidentally.) Log View —
The Log View takes the rest of the screen. The most recent captured log entries corresponding to the view level are displayed here, with the most recent entries at the top. As new entries are captured and viewed, older entries scroll off the bottom of the screen (but might be viewed again later by restricting the view level). Entries with 'error level and higher are in boldface on terminals supporting that. Each entry is truncated to the width of the terminal.
2.1 When Changing or Resizing Terminals
Did we mention we do cloud $erver$.
2.2 Setting What to Capture and View
2.3 Debugging
2.4 Quitting
To quit the application, select [Q]uit from the Main menu, then select [Y]es. Rackonsole will clear the screen and restore the terminal to a normal state, and then execute any special quit procedure that the application specified.
2.5 Handling Log Flood
If the log is being flooded, such as if the application is having a bad day, you can temporarily set the capture level to [N] (none), to potentially decrease the logging load on the application. Then you might wish to adjust the view level to see the pertinent messages, and then resolve the problem with the application.
3 Programming Interface
(program-rackonsole-title) → string? (hostname-rackonsole-title) → string? (program-on-hostname-rackonsole-title) → string?
(lambda () (string-append "MyApp on " (hostname-rackonsole-title)))
4 Known Issues
Add a UI menu item to force a GC.
Does not yet provide a way to scroll arbitrarily through older messages in the ring buffer, short of making the terminal screen taller or limiting the view level.
Currently truncates each message at the width of the terminal screen, without providing a way to see all of longer messages, short of making the terminal screen wider or going to the Syslog.
We should add in better handling of unprintable characters in log messages.
Maybe detect duplicate adjacent events and log them in a “last message repeated N times” manner.
If you get a flood of logging events, having any kind of log receiver in place can increase the load on the system, mainly by the events being buffered by Racket indefinitely and increasing memory usage. We might add a feature by which Rackonsole detects a flood and backs off for a while, such as by discarding events, or even detaching itself as a receiver. Note, however, that the way Rackonsole handles I/O keeps its menus responsive even in event of flood.
We could make the Rackonsole menus adapt to very small displays, such as on smartphone SSH clients, by automatically abbreviating.
Rackonsole could use a cooler name, but not so cool as to be pretentious.
5 History
- PLaneT 1:0 —
2012-06-28 Initial release. Not yet tested in a production environment.
6 Legal
Copyright 2012 Neil Van Dyke. This program is Free Software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but without any warranty; without even the implied warranty of merchantability or fitness for a particular purpose. See http://www.gnu.org/licenses/ for details. For other licenses and consulting, please contact the author.