mirror of
https://github.com/bcicen/ctop.git
synced 2025-12-06 23:26:45 +08:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b28beed3ee | ||
|
|
2e51406d00 | ||
|
|
c84b52ce40 | ||
|
|
4ee8cf621a | ||
|
|
192298c045 | ||
|
|
258536740d | ||
|
|
ef69744249 | ||
|
|
07f95a04b0 | ||
|
|
b2184bbc6d | ||
|
|
96b01eb3b9 | ||
|
|
03d4869361 | ||
|
|
4b7257908f | ||
|
|
1875013a76 | ||
|
|
dab2f926b9 | ||
|
|
ddce54f991 | ||
|
|
168e8f3aae |
7
Dockerfile
Normal file
7
Dockerfile
Normal file
@@ -0,0 +1,7 @@
|
||||
FROM quay.io/vektorcloud/glibc:latest
|
||||
|
||||
RUN ctop_url=$(wget -q -O - https://api.github.com/repos/bcicen/ctop/releases/latest | grep 'browser_' | cut -d\" -f4 |grep 'linux-amd64') && \
|
||||
wget -q $ctop_url -O /ctop && \
|
||||
chmod +x /ctop
|
||||
|
||||
ENTRYPOINT ["/ctop"]
|
||||
17
README.md
17
README.md
@@ -3,12 +3,12 @@
|
||||
|
||||
Top-like interface for container metrics
|
||||
|
||||
ctop provides a concise and condensed overview of real-time metrics for multiple containers:
|
||||
`ctop` provides a concise and condensed overview of real-time metrics for multiple containers:
|
||||
<p align="center"><img src="_docs/img/grid.gif" alt="ctop"/></p>
|
||||
|
||||
as well as an [expanded view][expanded_view] for inspecting a specific container.
|
||||
|
||||
ctop currently comes with built-in support for Docker; connectors for other container and cluster systems are planned for future releases.
|
||||
`ctop` currently comes with built-in support for Docker; connectors for other container and cluster systems are planned for future releases.
|
||||
|
||||
## Install
|
||||
|
||||
@@ -17,7 +17,7 @@ Fetch the [latest release](https://github.com/bcicen/ctop/releases) for your pla
|
||||
#### Linux
|
||||
|
||||
```bash
|
||||
wget https://github.com/bcicen/ctop/releases/download/v0.4/ctop-0.4-linux-amd64 -O ctop
|
||||
wget https://github.com/bcicen/ctop/releases/download/v0.4.1/ctop-0.4.1-linux-amd64 -O ctop
|
||||
sudo mv ctop /usr/local/bin/
|
||||
sudo chmod +x /usr/local/bin/ctop
|
||||
```
|
||||
@@ -25,14 +25,21 @@ sudo chmod +x /usr/local/bin/ctop
|
||||
#### OS X
|
||||
|
||||
```bash
|
||||
curl -Lo ctop https://github.com/bcicen/ctop/releases/download/v0.4/ctop-0.4-darwin-amd64
|
||||
curl -Lo ctop https://github.com/bcicen/ctop/releases/download/v0.4.1/ctop-0.4.1-darwin-amd64
|
||||
sudo mv ctop /usr/local/bin/
|
||||
sudo chmod +x /usr/local/bin/ctop
|
||||
```
|
||||
|
||||
or run via Docker:
|
||||
```bash
|
||||
docker run -ti -v /var/run/docker.sock:/var/run/docker.sock quay.io/vektorlab/ctop:latest
|
||||
```
|
||||
|
||||
`ctop` is also available for Arch in the [AUR](https://aur.archlinux.org/packages/ctop/)
|
||||
|
||||
## Usage
|
||||
|
||||
ctop requires no arguments and will configure itself using the `DOCKER_HOST` environment variable
|
||||
`ctop` requires no arguments and will configure itself using the `DOCKER_HOST` environment variable
|
||||
```bash
|
||||
export DOCKER_HOST=tcp://127.0.0.1:4243
|
||||
ctop
|
||||
|
||||
24
circle.yml
Normal file
24
circle.yml
Normal file
@@ -0,0 +1,24 @@
|
||||
machine:
|
||||
services:
|
||||
- docker
|
||||
|
||||
dependencies:
|
||||
override:
|
||||
- docker info
|
||||
- |
|
||||
if [[ "$CIRCLE_BRANCH" == "master" ]]; then
|
||||
docker build -t quay.io/vektorlab/ctop:latest .
|
||||
else
|
||||
docker build -t quay.io/vektorlab/ctop:${CIRCLE_BRANCH} .
|
||||
fi
|
||||
|
||||
test:
|
||||
override:
|
||||
- docker run -t --entrypoint /bin/sh quay.io/vektorlab/ctop:latest -v
|
||||
|
||||
deployment:
|
||||
hub:
|
||||
branch: master
|
||||
commands:
|
||||
- docker login -e $DOCKER_EMAIL -u $DOCKER_USER -p $DOCKER_PASS quay.io
|
||||
- docker push quay.io/vektorlab/ctop:latest
|
||||
@@ -2,11 +2,6 @@ package config
|
||||
|
||||
// defaults
|
||||
var params = []*Param{
|
||||
&Param{
|
||||
Key: "dockerHost",
|
||||
Val: getEnv("DOCKER_HOST", "unix:///var/run/docker.sock"),
|
||||
Label: "Docker API URL",
|
||||
},
|
||||
&Param{
|
||||
Key: "filterStr",
|
||||
Val: "",
|
||||
|
||||
@@ -17,7 +17,14 @@ func NewGridCursor() *GridCursor {
|
||||
}
|
||||
|
||||
func (gc *GridCursor) Len() int { return len(gc.filtered) }
|
||||
func (gc *GridCursor) Selected() *Container { return gc.filtered[gc.Idx()] }
|
||||
|
||||
func (gc *GridCursor) Selected() *Container {
|
||||
idx := gc.Idx()
|
||||
if idx < gc.Len() {
|
||||
return gc.filtered[idx]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Refresh containers from source
|
||||
func (gc *GridCursor) RefreshContainers() (lenChanged bool) {
|
||||
|
||||
@@ -16,7 +16,7 @@ func NewInfo(id string) *Info {
|
||||
p.Height = 4
|
||||
p.Width = colWidth[0]
|
||||
p.FgColor = ui.ThemeAttr("par.text.fg")
|
||||
p.Seperator = false
|
||||
p.Separator = false
|
||||
i := &Info{p, make(map[string]string)}
|
||||
i.Set("id", id)
|
||||
return i
|
||||
|
||||
@@ -3,8 +3,8 @@ package main
|
||||
import (
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/bcicen/ctop/config"
|
||||
"github.com/bcicen/ctop/metrics"
|
||||
"github.com/fsouza/go-dockerclient"
|
||||
)
|
||||
@@ -18,11 +18,12 @@ type DockerContainerSource struct {
|
||||
client *docker.Client
|
||||
containers map[string]*Container
|
||||
needsRefresh chan string // container IDs requiring refresh
|
||||
lock sync.RWMutex
|
||||
}
|
||||
|
||||
func NewDockerContainerSource() *DockerContainerSource {
|
||||
// init docker client
|
||||
client, err := docker.NewClient(config.GetVal("dockerHost"))
|
||||
client, err := docker.NewClientFromEnv()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@@ -30,6 +31,7 @@ func NewDockerContainerSource() *DockerContainerSource {
|
||||
client: client,
|
||||
containers: make(map[string]*Container),
|
||||
needsRefresh: make(chan string, 60),
|
||||
lock: sync.RWMutex{},
|
||||
}
|
||||
go cm.Loop()
|
||||
cm.refreshAll()
|
||||
@@ -113,28 +115,36 @@ func (cm *DockerContainerSource) MustGet(id string) *Container {
|
||||
collector := metrics.NewDocker(cm.client, id)
|
||||
// create container
|
||||
c = NewContainer(id, collector)
|
||||
cm.lock.Lock()
|
||||
cm.containers[id] = c
|
||||
cm.lock.Unlock()
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
// Get a single container, by ID
|
||||
func (cm *DockerContainerSource) Get(id string) (*Container, bool) {
|
||||
cm.lock.Lock()
|
||||
c, ok := cm.containers[id]
|
||||
cm.lock.Unlock()
|
||||
return c, ok
|
||||
}
|
||||
|
||||
// Remove containers by ID
|
||||
func (cm *DockerContainerSource) delByID(id string) {
|
||||
cm.lock.Lock()
|
||||
delete(cm.containers, id)
|
||||
cm.lock.Unlock()
|
||||
log.Infof("removed dead container: %s", id)
|
||||
}
|
||||
|
||||
// Return array of all containers, sorted by field
|
||||
func (cm *DockerContainerSource) All() (containers Containers) {
|
||||
cm.lock.Lock()
|
||||
for _, c := range cm.containers {
|
||||
containers = append(containers, c)
|
||||
}
|
||||
cm.lock.Unlock()
|
||||
sort.Sort(containers)
|
||||
containers.Filter()
|
||||
return containers
|
||||
|
||||
7
grid.go
7
grid.go
@@ -28,7 +28,7 @@ func RedrawRows(clr bool) {
|
||||
log.Debugf("screen cleared")
|
||||
}
|
||||
if config.GetSwitchVal("enableHeader") {
|
||||
header.Render()
|
||||
ui.Render(header)
|
||||
}
|
||||
cGrid.Align()
|
||||
ui.Render(cGrid)
|
||||
@@ -132,7 +132,10 @@ func Display() bool {
|
||||
return false
|
||||
}
|
||||
if expand {
|
||||
ExpandView(cursor.Selected())
|
||||
c := cursor.Selected()
|
||||
if c != nil {
|
||||
ExpandView(c)
|
||||
}
|
||||
return false
|
||||
}
|
||||
return true
|
||||
|
||||
@@ -23,10 +23,14 @@ func NewCTopHeader() *CTopHeader {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *CTopHeader) Render() {
|
||||
func (c *CTopHeader) Buffer() ui.Buffer {
|
||||
buf := ui.NewBuffer()
|
||||
c.Time.Text = timeStr()
|
||||
ui.Render(c.bg)
|
||||
ui.Render(c.Time, c.Count, c.Filter)
|
||||
buf.Merge(c.bg.Buffer())
|
||||
buf.Merge(c.Time.Buffer())
|
||||
buf.Merge(c.Count.Buffer())
|
||||
buf.Merge(c.Filter.Buffer())
|
||||
return buf
|
||||
}
|
||||
|
||||
func (c *CTopHeader) Align() {
|
||||
|
||||
Reference in New Issue
Block a user