From 79a3f361a729bf83e5faeaaefae26c40f38aeb4e Mon Sep 17 00:00:00 2001 From: Bradley Cicenas Date: Tue, 4 Jul 2017 12:32:25 +0000 Subject: [PATCH] add container log struct to models, collectors --- connector/collector/docker_logs.go | 20 +++++++++++++++++--- connector/collector/main.go | 2 +- connector/collector/mock_logs.go | 8 +++++--- cwidgets/expanded/logs.go | 17 ++++++++++------- models/main.go | 7 +++++++ 5 files changed, 40 insertions(+), 14 deletions(-) diff --git a/connector/collector/docker_logs.go b/connector/collector/docker_logs.go index 33d47a3..4a8946e 100644 --- a/connector/collector/docker_logs.go +++ b/connector/collector/docker_logs.go @@ -4,7 +4,10 @@ import ( "bufio" "context" "io" + "strings" + "time" + "github.com/bcicen/ctop/models" api "github.com/fsouza/go-dockerclient" ) @@ -14,9 +17,9 @@ type DockerLogs struct { done chan bool } -func (l *DockerLogs) Stream() chan string { +func (l *DockerLogs) Stream() chan models.Log { r, w := io.Pipe() - logCh := make(chan string) + logCh := make(chan models.Log) ctx, cancel := context.WithCancel(context.Background()) opts := api.LogsOptions{ @@ -35,7 +38,9 @@ func (l *DockerLogs) Stream() chan string { go func() { scanner := bufio.NewScanner(r) for scanner.Scan() { - logCh <- scanner.Text() + parts := strings.Split(scanner.Text(), " ") + ts := l.parseTime(parts[0]) + logCh <- models.Log{ts, strings.Join(parts[1:], " ")} } }() @@ -58,3 +63,12 @@ func (l *DockerLogs) Stream() chan string { } func (l *DockerLogs) Stop() { l.done <- true } + +func (l *DockerLogs) parseTime(s string) time.Time { + ts, err := time.Parse("2006-01-02T15:04:05.000000000Z", s) + if err != nil { + log.Errorf("failed to parse container log: %s", err) + ts = time.Now() + } + return ts +} diff --git a/connector/collector/main.go b/connector/collector/main.go index 5be6218..7c5649b 100644 --- a/connector/collector/main.go +++ b/connector/collector/main.go @@ -10,7 +10,7 @@ import ( var log = logging.Init() type LogCollector interface { - Stream() chan string + Stream() chan models.Log Stop() } diff --git a/connector/collector/mock_logs.go b/connector/collector/mock_logs.go index f9a74b3..fc79463 100644 --- a/connector/collector/mock_logs.go +++ b/connector/collector/mock_logs.go @@ -2,6 +2,8 @@ package collector import ( "time" + + "github.com/bcicen/ctop/models" ) const mockLog = "Cura ob pro qui tibi inveni dum qua fit donec amare illic mea, regem falli contexo pro peregrinorum heremo absconditi araneae meminerim deliciosas actionibus facere modico dura sonuerunt psalmi contra rerum, tempus mala anima volebant dura quae o modis." @@ -10,15 +12,15 @@ type MockLogs struct { done chan bool } -func (l *MockLogs) Stream() chan string { - logCh := make(chan string) +func (l *MockLogs) Stream() chan models.Log { + logCh := make(chan models.Log) go func() { for { select { case <-l.done: break default: - logCh <- mockLog + logCh <- models.Log{time.Now(), mockLog} time.Sleep(250 * time.Millisecond) } } diff --git a/cwidgets/expanded/logs.go b/cwidgets/expanded/logs.go index 356d225..25bf367 100644 --- a/cwidgets/expanded/logs.go +++ b/cwidgets/expanded/logs.go @@ -1,17 +1,20 @@ package expanded import ( + "time" + + "github.com/bcicen/ctop/models" ui "github.com/gizak/termui" ) type LogLines struct { - ts []string + ts []time.Time data []string } func NewLogLines(max int) *LogLines { ll := &LogLines{ - ts: make([]string, max), + ts: make([]time.Time, max), data: make([]string, max), } return ll @@ -31,14 +34,14 @@ func (ll *LogLines) getLines(start, end int) []string { return ll.data[start:end] } -func (ll *LogLines) add(s string) { +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, "timestamp") - ll.data = append(ll.data, s) - log.Debugf("recorded log line: %v", s) + ll.ts = append(ll.ts, l.Timestamp) + ll.data = append(ll.data, l.Message) + log.Debugf("recorded log line: %v", l) } type Logs struct { @@ -46,7 +49,7 @@ type Logs struct { lines *LogLines } -func NewLogs(stream chan string) *Logs { +func NewLogs(stream chan models.Log) *Logs { p := ui.NewList() p.Y = ui.TermHeight() / 2 p.X = 0 diff --git a/models/main.go b/models/main.go index ff20a6a..feb23ce 100644 --- a/models/main.go +++ b/models/main.go @@ -1,5 +1,12 @@ package models +import "time" + +type Log struct { + Timestamp time.Time + Message string +} + type Metrics struct { CPUUtil int NetTx int64