Skip to content

Commit

Permalink
commands: Add an option to print memory usage at intervals
Browse files Browse the repository at this point in the history
Use it with `hugo --print-mem
  • Loading branch information
bep committed Jun 25, 2020
1 parent f0266e2 commit 48dbb59
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 0 deletions.
2 changes: 2 additions & 0 deletions commands/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ type hugoBuilderCommon struct {
memprofile string
mutexprofile string
traceprofile string
printm bool

// TODO(bep) var vs string
logging bool
Expand Down Expand Up @@ -299,6 +300,7 @@ func (cc *hugoBuilderCommon) handleFlags(cmd *cobra.Command) {
cmd.Flags().BoolP("path-warnings", "", false, "print warnings on duplicate target paths etc.")
cmd.Flags().StringVarP(&cc.cpuprofile, "profile-cpu", "", "", "write cpu profile to `file`")
cmd.Flags().StringVarP(&cc.memprofile, "profile-mem", "", "", "write memory profile to `file`")
cmd.Flags().BoolVarP(&cc.printm, "print-mem", "", false, "print memory usage to screen at intervals")
cmd.Flags().StringVarP(&cc.mutexprofile, "profile-mutex", "", "", "write Mutex profile to `file`")
cmd.Flags().StringVarP(&cc.traceprofile, "trace", "", "", "write trace to `file` (not useful in general)")

Expand Down
54 changes: 54 additions & 0 deletions commands/hugo.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ func (r Response) IsUserError() bool {
// Execute adds all child commands to the root command HugoCmd and sets flags appropriately.
// The args are usually filled with os.Args[1:].
func Execute(args []string) Response {

hugoCmd := newCommandsBuilder().addAll().build()
cmd := hugoCmd.getCommand()
cmd.SetArgs(args)
Expand Down Expand Up @@ -427,7 +428,37 @@ func (c *commandeer) initMutexProfile() (func(), error) {

}

func (c *commandeer) initMemTicker() func() {
memticker := time.NewTicker(5 * time.Second)
quit := make(chan struct{})
printMem := func() {
var m runtime.MemStats
runtime.ReadMemStats(&m)
fmt.Printf("\n\nAlloc = %v\nTotalAlloc = %v\nSys = %v\nNumGC = %v\n\n", formatByteCount(m.Alloc), formatByteCount(m.TotalAlloc), formatByteCount(m.Sys), m.NumGC)

}

go func() {
for {
select {
case <-memticker.C:
printMem()
case <-quit:
memticker.Stop()
printMem()
return
}

}
}()

return func() {
close(quit)
}
}

func (c *commandeer) initProfiling() (func(), error) {

stopCPUProf, err := c.initCPUProfile()
if err != nil {
return nil, err
Expand All @@ -443,6 +474,11 @@ func (c *commandeer) initProfiling() (func(), error) {
return nil, err
}

var stopMemTicker func()
if c.h.printm {
stopMemTicker = c.initMemTicker()
}

return func() {
c.initMemProfile()

Expand All @@ -456,6 +492,10 @@ func (c *commandeer) initProfiling() (func(), error) {
if stopTraceProf != nil {
stopTraceProf()
}

if stopMemTicker != nil {
stopMemTicker()
}
}, nil
}

Expand Down Expand Up @@ -1175,3 +1215,17 @@ func pickOneWriteOrCreatePath(events []fsnotify.Event) string {

return name
}

func formatByteCount(b uint64) string {
const unit = 1000
if b < unit {
return fmt.Sprintf("%d B", b)
}
div, exp := int64(unit), 0
for n := b / unit; n >= unit; n /= unit {
div *= unit
exp++
}
return fmt.Sprintf("%.1f %cB",
float64(b)/float64(div), "kMGTPE"[exp])
}

0 comments on commit 48dbb59

Please sign in to comment.