From c984b270dbebe7359a034dd9d6b7b57789827262 Mon Sep 17 00:00:00 2001 From: Sergey Ponomarev Date: Mon, 26 Oct 2020 16:32:51 +0200 Subject: [PATCH] #135 Add uptime column --- config/columns.go | 5 +++++ config/param.go | 2 +- connector/docker.go | 16 +++++++++++++--- container/sort.go | 9 +++++++++ cwidgets/compact/column.go | 1 + cwidgets/compact/text.go | 12 ++++++++++++ cwidgets/single/info.go | 2 +- 7 files changed, 42 insertions(+), 5 deletions(-) diff --git a/config/columns.go b/config/columns.go index b59a50e..651c33e 100644 --- a/config/columns.go +++ b/config/columns.go @@ -46,6 +46,11 @@ var defaultColumns = []Column{ Label: "Container PID Count", Enabled: true, }, + Column{ + Name: "uptime", + Label: "Running uptime duration", + Enabled: true, + }, } type Column struct { diff --git a/config/param.go b/config/param.go index dc334f5..76cdd6a 100644 --- a/config/param.go +++ b/config/param.go @@ -19,7 +19,7 @@ var defaultParams = []*Param{ }, &Param{ Key: "columns", - Val: "status,name,id,cpu,mem,net,io,pids", + Val: "status,name,id,cpu,mem,net,io,pids,uptime", Label: "Enabled Columns", }, } diff --git a/connector/docker.go b/connector/docker.go index 6595059..0106a88 100644 --- a/connector/docker.go +++ b/connector/docker.go @@ -2,13 +2,13 @@ package connector import ( "fmt" - "strings" - "sync" - "github.com/bcicen/ctop/connector/collector" "github.com/bcicen/ctop/connector/manager" "github.com/bcicen/ctop/container" api "github.com/fsouza/go-dockerclient" + "strings" + "sync" + "time" ) func init() { enabled["docker"] = NewDocker } @@ -123,6 +123,7 @@ func (cm *Docker) refresh(c *container.Container) { c.SetMeta("IPs", ipsFormat(insp.NetworkSettings.Networks)) c.SetMeta("ports", portsFormat(insp.NetworkSettings.Ports)) c.SetMeta("created", insp.Created.Format("Mon Jan 2 15:04:05 2006")) + c.SetMeta("uptime", calcUptime(insp)) c.SetMeta("health", insp.State.Health.Status) for _, env := range insp.Config.Env { c.SetMeta("[ENV-VAR]", env) @@ -140,6 +141,15 @@ func (cm *Docker) inspect(id string) *api.Container { return c } +func calcUptime(insp *api.Container) string { + endTime := insp.State.FinishedAt + if endTime.IsZero() { + endTime = time.Now() + } + uptime := endTime.Sub(insp.State.StartedAt) + return uptime.Truncate(time.Second).String() +} + // Mark all container IDs for refresh func (cm *Docker) refreshAll() { opts := api.ListContainersOptions{All: true} diff --git a/container/sort.go b/container/sort.go index 65b6c2b..2d91910 100644 --- a/container/sort.go +++ b/container/sort.go @@ -79,6 +79,15 @@ var Sorters = map[string]sortMethod{ } return stateMap[c1state] > stateMap[c2state] }, + "uptime": func(c1, c2 *Container) bool { + // Use secondary sort method if equal values + c1Uptime := c1.GetMeta("uptime") + c2Uptime := c2.GetMeta("uptime") + if c1Uptime == c2Uptime { + return nameSorter(c1, c2) + } + return c1Uptime > c2Uptime + }, } func SortFields() (fields []string) { diff --git a/cwidgets/compact/column.go b/cwidgets/compact/column.go index c997a68..816d641 100644 --- a/cwidgets/compact/column.go +++ b/cwidgets/compact/column.go @@ -17,6 +17,7 @@ var ( "net": NewNetCol, "io": NewIOCol, "pids": NewPIDCol, + "uptime": NewUptimeCol, } ) diff --git a/cwidgets/compact/text.go b/cwidgets/compact/text.go index 3a6aa44..84378ee 100644 --- a/cwidgets/compact/text.go +++ b/cwidgets/compact/text.go @@ -80,6 +80,18 @@ func (w *PIDCol) SetMetrics(m models.Metrics) { w.Text = fmt.Sprintf("%d", m.Pids) } +type UptimeCol struct { + *TextCol +} + +func NewUptimeCol() CompactCol { + return &UptimeCol{NewTextCol("UPTIME")} +} + +func (w *UptimeCol) SetMeta(m models.Meta) { + w.Text = m.Get("uptime") +} + type TextCol struct { *ui.Par header string diff --git a/cwidgets/single/info.go b/cwidgets/single/info.go index 5b67717..3dc8d76 100644 --- a/cwidgets/single/info.go +++ b/cwidgets/single/info.go @@ -6,7 +6,7 @@ import ( ui "github.com/gizak/termui" ) -var displayInfo = []string{"id", "name", "image", "ports", "IPs", "state", "created", "health"} +var displayInfo = []string{"id", "name", "image", "ports", "IPs", "state", "created", "uptime", "health"} type Info struct { *ui.Table