allow setting maximum duration on the graph

pull/1/head
Jesse Duffield 5 years ago
parent 69b11cbfd2
commit a017067824

@ -39,6 +39,7 @@ type Container struct {
type RecordedStats struct {
ClientStats ContainerStats
DerivedStats DerivedStats
RecordedAt time.Time
}
type DerivedStats struct {
@ -353,3 +354,18 @@ func (c *Container) Attach() (*exec.Cmd, error) {
func (c *Container) Top() (types.ContainerProcessList, error) {
return c.Client.ContainerTop(context.Background(), c.ID, []string{})
}
// EraseOldHistory removes any history before the user-specified max duration
func (c *Container) EraseOldHistory() {
c.Log.Warn(c.Config.UserConfig.Stats.MaxDuration)
if c.Config.UserConfig.Stats.MaxDuration == 0 {
return
}
for i, stat := range c.StatHistory {
if time.Since(stat.RecordedAt) < c.Config.UserConfig.Stats.MaxDuration {
c.StatHistory = c.StatHistory[i:]
return
}
}
}

@ -197,15 +197,38 @@ func (c *Container) RenderStats(viewWidth int) (string, error) {
// PlotGraph returns the plotted graph based on the graph spec and the stat history
func (c *Container) PlotGraph(spec config.GraphConfig, width int) (string, error) {
data := make([]float64, len(c.StatHistory))
max := spec.Max
min := spec.Min
for i, stats := range c.StatHistory {
value, err := lookup.LookupString(stats, spec.StatPath)
if err != nil {
return "", err
return "Could not find key: " + spec.StatPath, nil
}
floatValue, err := getFloat(value.Interface())
if err != nil {
return "", err
}
if spec.MinType == "" {
if i == 0 {
min = floatValue
} else {
if floatValue < min {
min = floatValue
}
}
}
if spec.MaxType == "" {
if i == 0 {
max = floatValue
} else {
if floatValue > max {
max = floatValue
}
}
}
data[i] = floatValue
}
@ -213,8 +236,8 @@ func (c *Container) PlotGraph(spec config.GraphConfig, width int) (string, error
data,
asciigraph.Height(spec.Height),
asciigraph.Width(width),
asciigraph.Min(spec.Min),
asciigraph.Max(spec.Max),
asciigraph.Min(min),
asciigraph.Max(max),
asciigraph.Caption(spec.Caption),
), nil
}

@ -130,11 +130,12 @@ func (c *DockerCommand) createClientStatMonitor(container *Container) {
CPUPercentage: stats.CalculateContainerCPUPercentage(),
MemoryPercentage: stats.CalculateContainerMemoryUsage(),
},
RecordedAt: time.Now(),
}
c.ContainerMutex.Lock()
// TODO: for now we never truncate the recorded stats, and we should
container.StatHistory = append(container.StatHistory, recordedStats)
container.EraseOldHistory()
c.ContainerMutex.Unlock()
}

@ -3,6 +3,7 @@ package config
import (
"io/ioutil"
"path/filepath"
"time"
"github.com/shibukawa/configdir"
yaml "gopkg.in/yaml.v2"
@ -123,10 +124,14 @@ type GraphConfig struct {
Caption string `yaml:"caption,omitempty"`
StatPath string `yaml:"statPath,omitempty"`
Color string `yaml:"color,omitempty"`
// MinType and MaxType are each one of "", "static". blank means the min/max of the data set will be used. "static" means the min/max specified will be used
MinType string `yaml:"minType,omitempty"`
MaxType string `yaml:"maxType,omitempty"`
}
type StatsConfig struct {
Graphs []GraphConfig
Graphs []GraphConfig
MaxDuration time.Duration `yaml:"maxDuration,omitempty"`
}
// GetDefaultConfig returns the application default configuration

@ -122,6 +122,7 @@ func (gui *Gui) renderContainerConfig(mainView *gocui.View, container *commands.
func (gui *Gui) renderContainerStats(mainView *gocui.View, container *commands.Container) error {
mainView.Autoscroll = false
mainView.Title = "Stats"
mainView.Wrap = false
return gui.T.NewTickerTask(time.Second, func() {
width, _ := mainView.Size()

Loading…
Cancel
Save