概要
通常コンソールにはテキストしか表示できないと思い込んでいました。紹介するtermdashを使えばコンソール上にGUIもどきのものが表示できます。
機能
下記の画像はデモをWindowsで実行したものです。
次が画面の中央にある白いボタンのsparklines
をマウスでクリックしたときの画面です
下記のURLではグラフが時間変化する動画が見られます。
- Github URL
- レイアウト
- Binary tree layout
- https://github.com/mum4k/termdash/wiki/Binary-tree-layout
- 縦や横を2分割します。それらをそれぞれさらに2分割する方法で画面が構成されます。
- これをメインで試しました
- 画面のリサイズにも対応しています。
- Grid layout
- https://github.com/mum4k/termdash/wiki/Grid-layout
- 一般的なGridだと思います。まだ試していません。
- Binary tree layout
- Widget
- BarChart 棒グラフ (画像の右上)
- Button ボタン (画像の中央4ボタンと右下の2ボタン)
- Donut ドーナツグラフ (画像のBarChartの下)
- Gauge ゲージ (画像の中央の緑の帯)
- LineChart グラフ(画像の下、マウスによるズーム機能)
- SegmentDisplay 未調査
- Sparkline ミニグラフ (画像の中央)
- Text (画像の中央)
- スクロール
- マウスやキーボードでスクロールできます。
- テキストの折り返し
- はみ出し分を省略
- スクロール
各 OS上での実行
- Windows 上記画像の通り問題なし
- 日本語や中国語などを表示するときは
chcp 65001
でUTF-8にしないと画面が乱れる
- 日本語や中国語などを表示するときは
- Mac ほぼ問題はなかったが
Sparkline
に横筋が入っていた - Linux (ubuntu 18.04)
- Linux画面を直接操作することはないので以下のsshで試しました。
- Mac ssh ではMac上と同じでした
- Windows (おすすめは
git bash
のssh)- git bash のssh
- 一番良かった
- ボタンも押せます
- sparklineの表示で塗りつぶされていない四角文字がでる(気にしなければ問題ない)
- Scroll textでスクロールの特殊文字が表示されない
- putty
- グラフは出たが 枠の罫線が乱れている
- ボタンが押せない
- openssh
- 時間変化させたグラフ等が乱れる。
- ボタンが押せない
- 一部枠の罫線が乱れる
- WSL(ubuntu 18.04) のssh
- LineChartが乱れる
- Donutが乱れる
- 中央の白いボタンが出ない
- 右下のボタンは表示されて、クリックも出来る。
- git bash のssh
Scroll textが2つのログコンソール画面の実装
次のような画面です。左がFatalログで右がInformationログです。下記の画面は右側をクリックしたので枠の色が黄色?になっていますのでマウスの中ボタンやキーボードのカーソルキーで上下にスクロールできます。ログの文字が折り返されたら画面を横に広げればリサイズされます。 Fatalの時刻は赤にして、Informationはシアンにしました。
ソースコード
デモのソースを簡単に改造しただけです。Fatalかどうかは乱数によって決めました。実際はログファイルやデータベース、ネットワークから取得すると思います。
container.SplitVertical
を使って画面を縦に2分割しました。
package main
import (
"context"
"fmt"
"math/rand"
"time"
"github.com/mum4k/termdash"
"github.com/mum4k/termdash/cell"
"github.com/mum4k/termdash/container"
"github.com/mum4k/termdash/linestyle"
"github.com/mum4k/termdash/terminal/termbox"
"github.com/mum4k/termdash/terminal/terminalapi"
"github.com/mum4k/termdash/widgets/text"
)
func writeLines(ctx context.Context, fatal, info *text.Text, delay time.Duration) {
s := rand.NewSource(time.Now().Unix())
r := rand.New(s)
ticker := time.NewTicker(delay)
defer ticker.Stop()
fatalCount := 0
infoCount := 0
for {
select {
case <-ticker.C:
var err error
d := time.Now().Format("03:04:05")
i := r.Intn(3)
if i == 0 {
fatal.Write(d, text.WriteCellOpts(cell.FgColor(cell.ColorRed)))
if err == nil {
fatalCount++
log := fmt.Sprintf(" %d fatal fatal fatal\n", fatalCount)
err = fatal.Write(log)
}
} else {
err = info.Write(d, text.WriteCellOpts(cell.FgColor(cell.ColorCyan)))
if err == nil {
infoCount++
log := fmt.Sprintf(" %d information information information\n", infoCount)
err = info.Write(log)
}
}
if err != nil {
panic(err)
}
case <-ctx.Done():
return
}
}
}
func main() {
t, err := termbox.New()
if err != nil {
panic(err)
}
defer t.Close()
ctx, cancel := context.WithCancel(context.Background())
rolledFatal, err := text.New(text.RollContent(), text.WrapAtWords())
if err != nil {
panic(err)
}
rolledInfo, err := text.New(text.RollContent(), text.WrapAtWords())
if err != nil {
panic(err)
}
go writeLines(ctx, rolledFatal, rolledInfo, 1*time.Second)
c, err := container.New(
t,
container.Border(linestyle.Light),
container.BorderTitle("PRESS Q TO QUIT"),
container.SplitVertical(
container.Left(
container.Border(linestyle.Light),
container.BorderTitle(" Fatal ログ"),
container.PlaceWidget(rolledFatal),
),
container.Right(
container.Border(linestyle.Light),
container.BorderTitle(" Information ログ"),
container.PlaceWidget(rolledInfo),
),
),
)
if err != nil {
panic(err)
}
quitter := func(k *terminalapi.Keyboard) {
if k.Key == 'q' || k.Key == 'Q' {
cancel()
}
}
if err := termdash.Run(ctx, t, c, termdash.KeyboardSubscriber(quitter)); err != nil {
panic(err)
}
}
まとめ
サーバー系のモニタ画面に使えるのではないかと思います。 まさかコンソールでマウスが使えるとは思いませんでした。
各Layout, Widgetの使い方をQIITAに載せて頂けると嬉しいです。
git bashのsshよりもっと最適なWindowsのSSHソフトが有ったら教えてほしいです。