Add call trace command
This commit is contained in:
parent
ef509eb308
commit
6bb932212c
@ -34,8 +34,6 @@ import (
|
|||||||
func init() {
|
func init() {
|
||||||
gob.Register(map[string]interface{}{})
|
gob.Register(map[string]interface{}{})
|
||||||
gob.Register([]interface{}{})
|
gob.Register([]interface{}{})
|
||||||
gob.Register(&Room{})
|
|
||||||
gob.Register(0)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type RoomNameSource int
|
type RoomNameSource int
|
||||||
|
@ -109,6 +109,7 @@ func NewCommandProcessor(parent *MainView) *CommandProcessor {
|
|||||||
"invite": cmdInvite,
|
"invite": cmdInvite,
|
||||||
"hprof": cmdHeapProfile,
|
"hprof": cmdHeapProfile,
|
||||||
"cprof": cmdCPUProfile,
|
"cprof": cmdCPUProfile,
|
||||||
|
"trace": cmdTrace,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,10 +19,12 @@ package ui
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
dbg "runtime/debug"
|
dbg "runtime/debug"
|
||||||
"runtime/pprof"
|
"runtime/pprof"
|
||||||
|
"runtime/trace"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@ -92,38 +94,37 @@ func cmdHeapProfile(cmd *Command) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func cmdCPUProfile(cmd *Command) {
|
func runTimedProfile(cmd *Command, start func(writer io.Writer) error, stop func(), task, file string) {
|
||||||
if len(cmd.Args) == 0 {
|
if len(cmd.Args) == 0 {
|
||||||
cmd.Reply("Usage: /cprof <seconds>")
|
cmd.Reply("Usage: /%s <seconds>", cmd.Command)
|
||||||
return
|
} else if dur, err := strconv.Atoi(cmd.Args[0]); err != nil || dur < 0 {
|
||||||
}
|
cmd.Reply("Usage: /%s <seconds>", cmd.Command)
|
||||||
dur, err := strconv.Atoi(cmd.Args[0])
|
} else if cpuProfile, err := os.Create(file); err != nil {
|
||||||
if err != nil || dur < 0 {
|
debug.Printf("Failed to open %s: %v", file, err)
|
||||||
cmd.Reply("Usage: /cprof <seconds>")
|
} else if err = start(cpuProfile); err != nil {
|
||||||
return
|
|
||||||
}
|
|
||||||
cpuProfile, err := os.Create("gomuks.cpu.prof")
|
|
||||||
if err != nil {
|
|
||||||
debug.Print("Failed to open gomuks.cpu.prof:", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
err = pprof.StartCPUProfile(cpuProfile)
|
|
||||||
if err != nil {
|
|
||||||
_ = cpuProfile.Close()
|
_ = cpuProfile.Close()
|
||||||
debug.Print("CPU profile error:", err)
|
debug.Print(task, "error:", err)
|
||||||
return
|
} else {
|
||||||
}
|
cmd.Reply("Started %s for %d seconds", task, dur)
|
||||||
cmd.Reply("Started CPU profiling for %d seconds", dur)
|
|
||||||
go func() {
|
go func() {
|
||||||
time.Sleep(time.Duration(dur) * time.Second)
|
time.Sleep(time.Duration(dur) * time.Second)
|
||||||
pprof.StopCPUProfile()
|
stop()
|
||||||
cmd.Reply("CPU profiling finished.")
|
cmd.Reply("%s finished.", task)
|
||||||
|
|
||||||
err := cpuProfile.Close()
|
err := cpuProfile.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
debug.Print("Failed to close gomuks.cpu.prof:", err)
|
debug.Print("Failed to close gomuks.cpu.prof:", err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func cmdCPUProfile(cmd *Command) {
|
||||||
|
runTimedProfile(cmd, pprof.StartCPUProfile, pprof.StopCPUProfile, "CPU profiling", "gomuks.cpu.prof")
|
||||||
|
}
|
||||||
|
|
||||||
|
func cmdTrace(cmd *Command) {
|
||||||
|
runTimedProfile(cmd, trace.Start, trace.Stop, "Call tracing", "gomuks.trace")
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO this command definitely belongs in a plugin once we have a plugin system.
|
// TODO this command definitely belongs in a plugin once we have a plugin system.
|
||||||
|
Loading…
Reference in New Issue
Block a user