ctop/cwidgets/single/logs.go

84 lines
1.6 KiB
Go

package single
import (
"time"
"github.com/bcicen/ctop/models"
ui "github.com/gizak/termui"
)
type LogLines struct {
ts []time.Time
data []string
}
func NewLogLines(max int) *LogLines {
ll := &LogLines{
ts: make([]time.Time, max),
data: make([]string, max),
}
return ll
}
func (ll *LogLines) tail(n int) []string {
lines := make([]string, n)
for i := 0; i < n; i++ {
lines = append(lines, ll.data[len(ll.data)-i])
}
return lines
}
func (ll *LogLines) getLines(start, end int) []string {
if end < 0 {
return ll.data[start:]
}
return ll.data[start:end]
}
func (ll *LogLines) add(l models.Log) {
if len(ll.data) == cap(ll.data) {
ll.data = append(ll.data[:0], ll.data[1:]...)
ll.ts = append(ll.ts[:0], ll.ts[1:]...)
}
ll.ts = append(ll.ts, l.Timestamp)
ll.data = append(ll.data, l.Message)
log.Debugf("recorded log line: %v", l)
}
type Logs struct {
*ui.List
lines *LogLines
}
func NewLogs(stream chan models.Log) *Logs {
p := ui.NewList()
p.Y = ui.TermHeight() / 2
p.X = 0
p.Height = ui.TermHeight() - p.Y
p.Width = ui.TermWidth()
//p.Overflow = "wrap"
p.ItemFgColor = ui.ThemeAttr("par.text.fg")
i := &Logs{p, NewLogLines(4098)}
go func() {
for line := range stream {
i.lines.add(line)
ui.Render(i)
}
}()
return i
}
func (w *Logs) Align() {
w.X = colWidth[0]
w.List.Align()
}
func (w *Logs) Buffer() ui.Buffer {
maxLines := w.Height - 2
offset := len(w.lines.data) - maxLines
w.Items = w.lines.getLines(offset, -1)
return w.List.Buffer()
}
// number of rows a line will occupy at current panel width
func (w *Logs) lineHeight(s string) int { return (len(s) / w.InnerWidth()) + 1 }