Skip to content

Commit

Permalink
add: logs streaming.
Browse files Browse the repository at this point in the history
  • Loading branch information
arshamalh committed Nov 8, 2023
1 parent 228a852 commit 67066b8
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 32 deletions.
1 change: 1 addition & 0 deletions 2do.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
- [x] Zero stats problem
- [x] Container Start Stop handlers and functionality
- [x] Welcome message should have button and better message
- [x] Logs streaming
- [x] Add image handlers, next, prev, back
- [x] Image size should be in human readable units
- [ ] Image ID should be shorted (trimmed)
Expand Down
69 changes: 69 additions & 0 deletions models/queue.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package models

import "fmt"

type Node struct {
Value string
Next *Node
}

func newNode(value string, next *Node) *Node {
return &Node{
Value: value,
Next: next,
}
}

type Queue struct {
Length int
head *Node
tail *Node
}

// Add to the end, remove from the beginning
func NewQueue() *Queue {
return &Queue{}
}

func (q *Queue) isZeroOrOneNode() (bool, *Node) {
if q.Length == 0 {
return true, nil
} else if q.Length == 1 {
value := q.head
q.head = nil
q.tail = nil
q.Length--
return true, value
}
return false, nil
}

func (q *Queue) Push(value string) *Queue {
new_node := newNode(value, nil)
if q.Length == 0 {
q.head = new_node
} else {
q.tail.Next = new_node
}
q.tail = new_node
q.Length++
return q
}

func (q *Queue) Pop() *Node {
if ok, node := q.isZeroOrOneNode(); ok {
return node
}
node := q.head
q.head = q.head.Next
q.Length--
return node
}

func (q *Queue) String() string {
printable_list := ""
for node := q.head; node != nil; node = node.Next {
printable_list += fmt.Sprintln(node.Value)
}
return printable_list
}
47 changes: 25 additions & 22 deletions telegram/handlers/containers.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ func (h *handler) ContainersList(ctx telebot.Context) error {
)
}

func (h *handler) Logs(ctx telebot.Context) error {
// TODO: A list (queue) of logs, append to the end and remove from the beginning
func (h *handler) ContainerLogs(ctx telebot.Context) error {
// TODO: Starting from the beginning might cause confusion in long stream of errors, we should have a navigate till to the end button.
userID := ctx.Chat().ID
index, err := strconv.Atoi(ctx.Data())
if err != nil {
Expand All @@ -91,31 +91,31 @@ func (h *handler) Logs(ctx telebot.Context) error {
}

streamer := bufio.NewScanner(stream)
latestMsg := ""
queue := models.NewQueue()
for streamer.Scan() {
select {
case <-quit:
return nil
default:
if newMsg := streamer.Text(); newMsg != latestMsg {
err := ctx.Edit(
newMsg,
keyboards.Back(index, true),
)
if err != nil {
log.Gl.Error(err.Error())
}
latestMsg = newMsg
} else {
log.Gl.Debug("same info")
newMsg := streamer.Text()
queue.Push(newMsg)
if queue.Length > 10 { // TODO: 10 should not be hard-coded
queue.Pop()
}
time.Sleep(time.Second)

// Omitted error by purpose (the error is just about not modified message because of repetitive content)
ctx.Edit(
queue.String(),
keyboards.Back(index, true),
)
time.Sleep(time.Millisecond * 500)
// TODO: sleeping time, not hardcoded, not too much, not so little (under 500 millisecond would be annoying)
}
}
return ctx.Respond()
}

func (h *handler) Stats(ctx telebot.Context) error {
func (h *handler) ContainerStats(ctx telebot.Context) error {
userID := ctx.Chat().ID
index, err := strconv.Atoi(ctx.Data())
if err != nil {
Expand All @@ -129,26 +129,29 @@ func (h *handler) Stats(ctx telebot.Context) error {
log.Gl.Error(err.Error())
}
streamer := bufio.NewScanner(stream)
latest_msg := ""
latestMsg := ""
for streamer.Scan() {
select {
case <-quit:
log.Gl.Debug("end of streaming stats for user", zap.Int64("used_id", userID))
return nil
default:
stats := models.Stats{}
json.Unmarshal(streamer.Bytes(), &stats)
msg := msgs.FmtStats(stats)
if msg != latest_msg {
err := json.Unmarshal(streamer.Bytes(), &stats)
if err != nil {
log.Gl.Error(err.Error())
}

if newMsg := msgs.FmtStats(stats); newMsg != latestMsg {
err := ctx.Edit(
msg,
newMsg,
keyboards.Back(index, true),
telebot.ModeMarkdownV2,
)
if err != nil {
log.Gl.Error(err.Error())
}
latest_msg = msg
latestMsg = newMsg
}
time.Sleep(time.Second)
}
Expand Down
4 changes: 2 additions & 2 deletions telegram/handlers/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ func Register(bot *telebot.Bot, docker contracts.Docker, session repo.Session) {

h.bot.Handle(btns.ContNext.Key(), h.ContainersNavBtn)
h.bot.Handle(btns.ContPrev.Key(), h.ContainersNavBtn)
h.bot.Handle(btns.ContLogs.Key(), h.Logs)
h.bot.Handle(btns.ContStats.Key(), h.Stats)
h.bot.Handle(btns.ContLogs.Key(), h.ContainerLogs)
h.bot.Handle(btns.ContStats.Key(), h.ContainerStats)
h.bot.Handle(btns.ContBack.Key(), h.ContainersBackBtn)
h.bot.Handle(btns.ContStop.Key(), h.ContainerStop)
h.bot.Handle(btns.ContStart.Key(), h.ContainerStart)
Expand Down
16 changes: 8 additions & 8 deletions telegram/keyboards/keyboards.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,17 @@ func ContainersList(index int, containerIsOn bool) *telebot.ReplyMarkup {

keyboard.Inline(
telebot.Row{
keyboard.Data("⬅", btns.ContPrev.String(), fmt.Sprint(index-1)),
keyboard.Data("➡", btns.ContNext.String(), fmt.Sprint(index+1)),
keyboard.Data("Prev ⬅", btns.ContPrev.String(), fmt.Sprint(index-1)),
keyboard.Data("Next ➡", btns.ContNext.String(), fmt.Sprint(index+1)),
},
telebot.Row{
switchBtn(keyboard, index, containerIsOn),
keyboard.Data("Remove", btns.ContRemove.String(), fmt.Sprint(index)),
keyboard.Data("Rename", btns.ContRename.String(), fmt.Sprint(index)),
keyboard.Data("Remove 🗑", btns.ContRemove.String(), fmt.Sprint(index)),
keyboard.Data("Rename ✏️", btns.ContRename.String(), fmt.Sprint(index)),
},
telebot.Row{
keyboard.Data("Logs", btns.ContLogs.String(), fmt.Sprint(index)),
keyboard.Data("Stats", btns.ContStats.String(), fmt.Sprint(index)),
keyboard.Data("Logs 🪵", btns.ContLogs.String(), fmt.Sprint(index)),
keyboard.Data("Stats 📊", btns.ContStats.String(), fmt.Sprint(index)),
},
)

Expand Down Expand Up @@ -74,8 +74,8 @@ func Back(index int, containerIsOn bool) *telebot.ReplyMarkup {

func switchBtn(keyboard *telebot.ReplyMarkup, index int, containerIsOn bool) telebot.Btn {
if containerIsOn {
return keyboard.Data("Stop", btns.ContStop.String(), fmt.Sprint(index))
return keyboard.Data("Stop 🛑", btns.ContStop.String(), fmt.Sprint(index))
} else {
return keyboard.Data("Start", btns.ContStart.String(), fmt.Sprint(index))
return keyboard.Data("Start 🏃", btns.ContStart.String(), fmt.Sprint(index))
}
}

0 comments on commit 67066b8

Please sign in to comment.