Skip to content

Commit

Permalink
Update to version v1.1.0! (#51)
Browse files Browse the repository at this point in the history
* Add feature for more CPU info (#46)

* added code for additional cpu info

* added cpu rates to CPULoad type

* Made UI for CPU info

* Cleaned use fo sync.once variables for faster UI rendering

Co-authored-by: Madhav Jivrajani <[email protected]>

* added cpuinfo in README

* removed stray comment

* Update README

* Add extra comments

* Refactored printStats, becoming serveStats! (#50)

Co-authored-by: lrb <[email protected]>

* Readme update

Co-authored-by: Madhav Jivrajani <[email protected]>
Co-authored-by: mattharwood <[email protected]>
Co-authored-by: lrb <[email protected]>
  • Loading branch information
4 people authored Sep 13, 2020
1 parent 78f9b7b commit 53c6133
Show file tree
Hide file tree
Showing 12 changed files with 418 additions and 23 deletions.
26 changes: 24 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ Grofer

A clean system monitor and profiler written purely in golang using [termui](https://github.com/gizak/termui) and [gopsutil](https://github.com/shirou/gopsutil)!

Currently compatible with Linux only.

Installation
------------

Expand Down Expand Up @@ -35,6 +37,8 @@ cd grofer
go build grofer.go
```

---

Usage
-----

Expand All @@ -52,6 +56,7 @@ Available Commands:
Flags:
--config string config file (default is $HOME/.grofer.yaml)
-c, --cpuinfo Info about the CPU Load over all CPUs
-h, --help help for grofer
-r, --refresh int32 Overall stats UI refreshes rate in milliseconds greater than 1000 (default 1000)
-t, --toggle Help message for toggle
Expand All @@ -60,11 +65,13 @@ Use "grofer [command] --help" for more information about a command.
```

---

Examples
--------

`grofer [-r refreshRate]`
-------------------------
`grofer [-r refreshRate] [-c]`
------------------------------

This gives overall utilization stats refreshed every `refreshRate` milliseconds. Default and minimum value of the refresh rate is `1000 ms`.

Expand All @@ -76,6 +83,21 @@ Information provided:
- Network usage
- Disk storage

The `-c, --cpuinfo` flag displays finer details about the CPU load such as percentage of the time spent servicing software interrupts, hardware interrupts, etc.

![grofer-cpu](images/README/cpuload.png)

Information provided:
- Usr : % of time spent executing user level applications.
- Sys : % of time spent executing kernel level processes.
- Irq : % of time spent servicing hardware interrupts.
- Idle : % of time CPU was idle.
- Nice : % of time spent by CPU executing user level processes with a nice priority.
- Iowait: % of time spent by CPU waiting for an outstanding disk I/O.
- Soft : % of time spent by the CPU servicing software interrupts.

- Steal : % of time spent in involuntary waiting by logical CPUs.

---

`grofer proc [-p PID] [-r refreshRate]`
Expand Down
32 changes: 25 additions & 7 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (

overallGraph "github.com/pesos/grofer/src/display/general"
"github.com/pesos/grofer/src/general"
info "github.com/pesos/grofer/src/general"
"github.com/pesos/grofer/src/utils"
)

Expand All @@ -40,22 +41,38 @@ var rootCmd = &cobra.Command{
Use: "grofer",
Short: "grofer is a system profiler written in golang",
RunE: func(cmd *cobra.Command, args []string) error {

overallRefreshRate, _ := cmd.Flags().GetInt32("refresh")
if overallRefreshRate < 1000 {
return fmt.Errorf("invalid refresh rate: minimum refresh rate is 1000(ms)")
}

var wg sync.WaitGroup
endChannel := make(chan os.Signal, 1)
dataChannel := make(chan utils.DataStats, 1)

wg.Add(2)
cpuLoadFlag, _ := cmd.Flags().GetBool("cpuinfo")
if cpuLoadFlag {
cpuLoad := info.NewCPULoad()
dataChannel := make(chan *info.CPULoad, 1)
endChannel := make(chan os.Signal, 1)

wg.Add(2)

go info.GetCPULoad(cpuLoad, dataChannel, endChannel, int32(4*overallRefreshRate/5), &wg)

go overallGraph.RenderCPUinfo(endChannel, dataChannel, overallRefreshRate, &wg)

go general.GlobalStats(endChannel, dataChannel, int32(4*overallRefreshRate/5), &wg)
go overallGraph.RenderCharts(endChannel, dataChannel, overallRefreshRate, &wg)
wg.Wait()

wg.Wait()
} else {
endChannel := make(chan os.Signal, 1)
dataChannel := make(chan utils.DataStats, 1)

wg.Add(2)

go general.GlobalStats(endChannel, dataChannel, int32(4*overallRefreshRate/5), &wg)
go overallGraph.RenderCharts(endChannel, dataChannel, overallRefreshRate, &wg)

wg.Wait()
}

return nil
},
Expand All @@ -73,6 +90,7 @@ func init() {
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.grofer.yaml)")

rootCmd.Flags().Int32P("refresh", "r", DefaultOverallRefreshRate, "Overall stats UI refreshes rate in milliseconds greater than 1000")
rootCmd.Flags().BoolP("cpuinfo", "c", false, "Info about the CPU Load over all CPUs")
rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}

Expand Down
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,7 @@ require (
github.com/shirou/gopsutil v2.20.6+incompatible
github.com/spf13/cobra v1.0.0
github.com/spf13/viper v1.7.0
github.com/thedevsaddam/gojsonq/v2 v2.5.2
github.com/tidwall/gjson v1.6.0
golang.org/x/sys v0.0.0-20200722175500-76b94024e4b6 // indirect
)
10 changes: 10 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,16 @@ github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/thedevsaddam/gojsonq v1.9.1 h1:zQulEP43nwmq5EKrNWyIgJVbqDeMdC1qzXM/f5O15a0=
github.com/thedevsaddam/gojsonq v2.3.0+incompatible h1:i2lFTvGY4LvoZ2VUzedsFlRiyaWcJm3Uh6cQ9+HyQA8=
github.com/thedevsaddam/gojsonq/v2 v2.5.2 h1:CoMVaYyKFsVj6TjU6APqAhAvC07hTI6IQen8PHzHYY0=
github.com/thedevsaddam/gojsonq/v2 v2.5.2/go.mod h1:bv6Xa7kWy82uT0LnXPE2SzGqTj33TAEeR560MdJkiXs=
github.com/tidwall/gjson v1.6.0 h1:9VEQWz6LLMUsUl6PueE49ir4Ka6CzLymOAZDxpFsTDc=
github.com/tidwall/gjson v1.6.0/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls=
github.com/tidwall/match v1.0.1 h1:PnKP62LPNxHKTwvHHZZzdOAOCtsJTjo6dZLCwpKm5xc=
github.com/tidwall/match v1.0.1/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E=
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
Expand Down
Binary file added images/README/cpuload.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
116 changes: 116 additions & 0 deletions src/display/general/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,19 @@ type MainPage struct {
NetPara *widgets.Paragraph
}

type CPUPage struct {
Grid *ui.Grid
UsrChart *widgets.Gauge
NiceChart *widgets.Gauge
SysChart *widgets.Gauge
IowaitChart *widgets.Gauge
IrqChart *widgets.Gauge
SoftChart *widgets.Gauge
IdleChart *widgets.Gauge
StealChart *widgets.Gauge
CPUChart *widgets.Table
}

// NewPage returns a new page initialized from the MainPage struct
func NewPage(numCores int) *MainPage {
page := &MainPage{
Expand All @@ -46,6 +59,23 @@ func NewPage(numCores int) *MainPage {
return page
}

func NewCPUPage(numCores int) *CPUPage {
page := &CPUPage{
Grid: ui.NewGrid(),
UsrChart: widgets.NewGauge(),
NiceChart: widgets.NewGauge(),
SysChart: widgets.NewGauge(),
IowaitChart: widgets.NewGauge(),
IrqChart: widgets.NewGauge(),
SoftChart: widgets.NewGauge(),
IdleChart: widgets.NewGauge(),
StealChart: widgets.NewGauge(),
CPUChart: widgets.NewTable(),
}
page.InitCPU(numCores)
return page
}

// InitGeneral initializes all ui elements for the ui rendered by the grofer command
func (page *MainPage) InitGeneral(numCores int) {

Expand Down Expand Up @@ -108,3 +138,89 @@ func (page *MainPage) InitGeneral(numCores int) {
w, h := ui.TerminalDimensions()
page.Grid.SetRect(w/2, 0, w, h)
}

func (page *CPUPage) InitCPU(numCores int) {
page.UsrChart.Title = " Usr "
page.UsrChart.Percent = 0
page.UsrChart.BarColor = ui.ColorBlue
page.UsrChart.BorderStyle.Fg = ui.ColorCyan
page.UsrChart.TitleStyle.Fg = ui.ColorWhite

page.NiceChart.Title = " Nice "
page.NiceChart.Percent = 0
page.NiceChart.BarColor = ui.ColorBlue
page.NiceChart.BorderStyle.Fg = ui.ColorCyan
page.NiceChart.TitleStyle.Fg = ui.ColorWhite

page.SysChart.Title = " Sys "
page.SysChart.Percent = 0
page.SysChart.BarColor = ui.ColorBlue
page.SysChart.BorderStyle.Fg = ui.ColorCyan
page.SysChart.TitleStyle.Fg = ui.ColorWhite

page.IowaitChart.Title = " Iowait "
page.IowaitChart.Percent = 0
page.IowaitChart.BarColor = ui.ColorBlue
page.IowaitChart.BorderStyle.Fg = ui.ColorCyan
page.IowaitChart.TitleStyle.Fg = ui.ColorWhite

page.IrqChart.Title = " Irq "
page.IrqChart.Percent = 0
page.IrqChart.BarColor = ui.ColorBlue
page.IrqChart.BorderStyle.Fg = ui.ColorCyan
page.IrqChart.TitleStyle.Fg = ui.ColorWhite

page.SoftChart.Title = " Soft "
page.SoftChart.Percent = 0
page.SoftChart.BarColor = ui.ColorBlue
page.SoftChart.BorderStyle.Fg = ui.ColorCyan
page.SoftChart.TitleStyle.Fg = ui.ColorWhite

page.IdleChart.Title = " Idle "
page.IdleChart.Percent = 0
page.IdleChart.BarColor = ui.ColorBlue
page.IdleChart.BorderStyle.Fg = ui.ColorCyan
page.IdleChart.TitleStyle.Fg = ui.ColorWhite

page.StealChart.Title = " Steal "
page.StealChart.Percent = 0
page.StealChart.BarColor = ui.ColorBlue
page.StealChart.BorderStyle.Fg = ui.ColorCyan
page.StealChart.TitleStyle.Fg = ui.ColorWhite

page.CPUChart.Title = " CPU "
page.CPUChart.TextStyle = ui.NewStyle(ui.ColorWhite)
page.CPUChart.TextAlignment = ui.AlignCenter
page.CPUChart.RowSeparator = true

columnWidths := []int{}
for i := 0; i < numCores; i++ {
columnWidths = append(columnWidths, 9)
}

page.CPUChart.ColumnWidths = columnWidths

page.Grid.Set(
ui.NewRow(0.17,
ui.NewCol(0.5, page.UsrChart),
ui.NewCol(0.5, page.NiceChart),
),
ui.NewRow(0.17,
ui.NewCol(0.5, page.SysChart),
ui.NewCol(0.5, page.IowaitChart),
),
ui.NewRow(0.17,
ui.NewCol(0.5, page.IrqChart),
ui.NewCol(0.5, page.SoftChart),
),
ui.NewRow(0.17,
ui.NewCol(0.5, page.IdleChart),
ui.NewCol(0.5, page.StealChart),
),
ui.NewRow(0.30, page.CPUChart),
)

w, h := ui.TerminalDimensions()
page.Grid.SetRect(0, 0, w, h)

}
Loading

0 comments on commit 53c6133

Please sign in to comment.