mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-21 20:46:30 -05:00
commands: Add an option to print memory usage at intervals
Use it with `hugo --print-mem
This commit is contained in:
parent
f0266e2ef3
commit
48dbb593f7
2 changed files with 56 additions and 0 deletions
|
@ -212,6 +212,7 @@ type hugoBuilderCommon struct {
|
||||||
memprofile string
|
memprofile string
|
||||||
mutexprofile string
|
mutexprofile string
|
||||||
traceprofile string
|
traceprofile string
|
||||||
|
printm bool
|
||||||
|
|
||||||
// TODO(bep) var vs string
|
// TODO(bep) var vs string
|
||||||
logging bool
|
logging bool
|
||||||
|
@ -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().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.cpuprofile, "profile-cpu", "", "", "write cpu profile to `file`")
|
||||||
cmd.Flags().StringVarP(&cc.memprofile, "profile-mem", "", "", "write memory 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.mutexprofile, "profile-mutex", "", "", "write Mutex profile to `file`")
|
||||||
cmd.Flags().StringVarP(&cc.traceprofile, "trace", "", "", "write trace to `file` (not useful in general)")
|
cmd.Flags().StringVarP(&cc.traceprofile, "trace", "", "", "write trace to `file` (not useful in general)")
|
||||||
|
|
||||||
|
|
|
@ -82,6 +82,7 @@ func (r Response) IsUserError() bool {
|
||||||
// Execute adds all child commands to the root command HugoCmd and sets flags appropriately.
|
// Execute adds all child commands to the root command HugoCmd and sets flags appropriately.
|
||||||
// The args are usually filled with os.Args[1:].
|
// The args are usually filled with os.Args[1:].
|
||||||
func Execute(args []string) Response {
|
func Execute(args []string) Response {
|
||||||
|
|
||||||
hugoCmd := newCommandsBuilder().addAll().build()
|
hugoCmd := newCommandsBuilder().addAll().build()
|
||||||
cmd := hugoCmd.getCommand()
|
cmd := hugoCmd.getCommand()
|
||||||
cmd.SetArgs(args)
|
cmd.SetArgs(args)
|
||||||
|
@ -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) {
|
func (c *commandeer) initProfiling() (func(), error) {
|
||||||
|
|
||||||
stopCPUProf, err := c.initCPUProfile()
|
stopCPUProf, err := c.initCPUProfile()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -443,6 +474,11 @@ func (c *commandeer) initProfiling() (func(), error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var stopMemTicker func()
|
||||||
|
if c.h.printm {
|
||||||
|
stopMemTicker = c.initMemTicker()
|
||||||
|
}
|
||||||
|
|
||||||
return func() {
|
return func() {
|
||||||
c.initMemProfile()
|
c.initMemProfile()
|
||||||
|
|
||||||
|
@ -456,6 +492,10 @@ func (c *commandeer) initProfiling() (func(), error) {
|
||||||
if stopTraceProf != nil {
|
if stopTraceProf != nil {
|
||||||
stopTraceProf()
|
stopTraceProf()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if stopMemTicker != nil {
|
||||||
|
stopMemTicker()
|
||||||
|
}
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1175,3 +1215,17 @@ func pickOneWriteOrCreatePath(events []fsnotify.Event) string {
|
||||||
|
|
||||||
return name
|
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])
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue