Added 'view logs binding'

This commit is contained in:
Peter Reisinger 2017-11-25 18:30:50 +00:00
parent a826859202
commit a0e0da1da9
4 changed files with 141 additions and 0 deletions

View File

@ -76,6 +76,8 @@ H | Toggle ctop header
h | Open help dialog
s | Select container sort field
r | Reverse container sort order
m | Manage container (start, stop and/or remove)
l | View container logs
q | Quit ctop
[build]: _docs/build.md

View File

@ -97,6 +97,10 @@ func Display() bool {
menu = ContainerMenu
ui.StopLoop()
})
ui.Handle("/sys/kbd/l", func(ui.Event) {
menu = LogMenu
ui.StopLoop()
})
ui.Handle("/sys/kbd/<enter>", func(ui.Event) {
single = true
ui.StopLoop()

View File

@ -144,3 +144,47 @@ func ContainerMenu() {
})
ui.Loop()
}
func LogMenu() {
c := cursor.Selected()
if c == nil {
return
}
ui.DefaultEvtStream.ResetHandlers()
defer ui.DefaultEvtStream.ResetHandlers()
logs, quit := logReader(c)
m := widgets.NewTextView(logs)
m.BorderLabel = "Logs"
ui.Render(m)
ui.Handle("/sys/kbd/", func(ui.Event) {
quit <- true
ui.StopLoop()
})
ui.Loop()
}
func logReader(container *container.Container) (logs chan string, quit chan bool) {
logCollector := container.Logs()
stream := logCollector.Stream()
logs = make(chan string)
quit = make(chan bool)
go func() {
for {
select {
case log := <- stream:
logs <- log.Message
case <- quit:
logCollector.Stop()
close(logs)
return
}
}
}()
return
}

91
widgets/view.go Normal file
View File

@ -0,0 +1,91 @@
package widgets
import (
ui "github.com/gizak/termui"
"fmt"
)
type TextView struct {
ui.Block
inputStream <- chan string
render chan bool
Text []string // all the text
TextOut []string // text to be displayed
TextFgColor ui.Attribute
TextBgColor ui.Attribute
padding Padding
}
func NewTextView(lines <- chan string) *TextView {
i := &TextView{
Block: *ui.NewBlock(),
inputStream: lines,
render: make(chan bool),
Text: []string{},
TextOut: []string{},
TextFgColor: ui.ThemeAttr("menu.text.fg"),
TextBgColor: ui.ThemeAttr("menu.text.bg"),
padding: Padding{4, 2},
}
i.BorderFg = ui.ThemeAttr("menu.border.fg")
i.BorderLabelFg = ui.ThemeAttr("menu.label.fg")
ui.Clear()
i.Height = ui.TermHeight()
i.Width = ui.TermWidth()
i.readInputLoop()
i.renderLoop()
return i
}
func (i *TextView) Buffer() ui.Buffer {
var cell ui.Cell
buf := i.Block.Buffer()
x := i.Block.X + i.padding[0]
y := i.Block.Y + i.padding[1]
for _, line := range i.TextOut {
for _, ch := range line {
cell = ui.Cell{Ch: ch, Fg: i.TextFgColor, Bg: i.TextBgColor}
buf.Set(x, y, cell)
x++
}
x = i.Block.X + i.padding[0]
y++
}
return buf
}
func (i *TextView) renderLoop() {
go func() {
for range i.render {
size := i.Height - (i.padding[1] * 2)
if size > len(i.Text) {
size = len(i.Text)
}
i.TextOut = i.Text[len(i.Text) - size:]
width := i.Width - (i.padding[0] * 2)
for n := range i.TextOut {
if len(i.TextOut[n]) > width {
i.TextOut[n] = fmt.Sprintf("%s...", i.TextOut[n][:width - 3])
}
}
ui.Render(i)
}
}()
}
func (i *TextView) readInputLoop() {
go func() {
for line := range i.inputStream {
i.Text = append(i.Text, line)
i.render <- true
}
close(i.render)
}()
}