2016-06-15 13:50:56 +02:00
|
|
|
// Copyright (c) 2012-2014 Jeremy Latt
|
2017-03-27 14:15:02 +02:00
|
|
|
// Copyright (c) 2016 Daniel Oaks <daniel@danieloaks.net>
|
2016-06-15 13:50:56 +02:00
|
|
|
// released under the MIT license
|
|
|
|
|
2014-04-15 17:49:52 +02:00
|
|
|
package irc
|
|
|
|
|
|
|
|
import (
|
2016-06-19 02:01:30 +02:00
|
|
|
"fmt"
|
2014-04-15 17:49:52 +02:00
|
|
|
"os"
|
|
|
|
"runtime"
|
|
|
|
"runtime/debug"
|
|
|
|
"runtime/pprof"
|
|
|
|
"time"
|
2016-06-17 14:17:42 +02:00
|
|
|
|
2017-06-15 18:14:19 +02:00
|
|
|
"github.com/goshuirc/irc-go/ircmsg"
|
2014-04-15 17:49:52 +02:00
|
|
|
)
|
|
|
|
|
2016-06-19 02:01:30 +02:00
|
|
|
// DEBUG GCSTATS/NUMGOROUTINE/etc
|
2016-06-17 14:17:42 +02:00
|
|
|
func debugHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
|
2014-04-15 17:49:52 +02:00
|
|
|
if !client.flags[Operator] {
|
2016-06-19 02:01:30 +02:00
|
|
|
return false
|
2014-04-15 17:49:52 +02:00
|
|
|
}
|
|
|
|
|
2016-06-17 14:17:42 +02:00
|
|
|
switch msg.Params[0] {
|
2014-04-15 17:49:52 +02:00
|
|
|
case "GCSTATS":
|
|
|
|
stats := debug.GCStats{
|
|
|
|
Pause: make([]time.Duration, 10),
|
|
|
|
PauseQuantiles: make([]time.Duration, 5),
|
|
|
|
}
|
|
|
|
debug.ReadGCStats(&stats)
|
|
|
|
|
2016-06-19 02:01:30 +02:00
|
|
|
client.Notice(fmt.Sprintf("last GC: %s", stats.LastGC.Format(time.RFC1123)))
|
|
|
|
client.Notice(fmt.Sprintf("num GC: %d", stats.NumGC))
|
|
|
|
client.Notice(fmt.Sprintf("pause total: %s", stats.PauseTotal))
|
|
|
|
client.Notice(fmt.Sprintf("pause quantiles min%%: %s", stats.PauseQuantiles[0]))
|
|
|
|
client.Notice(fmt.Sprintf("pause quantiles 25%%: %s", stats.PauseQuantiles[1]))
|
|
|
|
client.Notice(fmt.Sprintf("pause quantiles 50%%: %s", stats.PauseQuantiles[2]))
|
|
|
|
client.Notice(fmt.Sprintf("pause quantiles 75%%: %s", stats.PauseQuantiles[3]))
|
|
|
|
client.Notice(fmt.Sprintf("pause quantiles max%%: %s", stats.PauseQuantiles[4]))
|
2014-04-15 17:49:52 +02:00
|
|
|
|
|
|
|
case "NUMGOROUTINE":
|
|
|
|
count := runtime.NumGoroutine()
|
2016-06-19 02:01:30 +02:00
|
|
|
client.Notice(fmt.Sprintf("num goroutines: %d", count))
|
2014-04-15 17:49:52 +02:00
|
|
|
|
|
|
|
case "PROFILEHEAP":
|
|
|
|
profFile := "ergonomadic.mprof"
|
|
|
|
file, err := os.Create(profFile)
|
|
|
|
if err != nil {
|
2016-06-19 02:01:30 +02:00
|
|
|
client.Notice(fmt.Sprintf("error: %s", err))
|
2014-04-15 17:49:52 +02:00
|
|
|
break
|
|
|
|
}
|
|
|
|
defer file.Close()
|
|
|
|
pprof.Lookup("heap").WriteTo(file, 0)
|
2016-06-19 02:01:30 +02:00
|
|
|
client.Notice(fmt.Sprintf("written to %s", profFile))
|
2014-04-15 17:49:52 +02:00
|
|
|
|
|
|
|
case "STARTCPUPROFILE":
|
|
|
|
profFile := "ergonomadic.prof"
|
|
|
|
file, err := os.Create(profFile)
|
|
|
|
if err != nil {
|
2016-06-19 02:01:30 +02:00
|
|
|
client.Notice(fmt.Sprintf("error: %s", err))
|
2014-04-15 17:49:52 +02:00
|
|
|
break
|
|
|
|
}
|
|
|
|
if err := pprof.StartCPUProfile(file); err != nil {
|
|
|
|
defer file.Close()
|
2016-06-19 02:01:30 +02:00
|
|
|
client.Notice(fmt.Sprintf("error: %s", err))
|
2014-04-15 17:49:52 +02:00
|
|
|
break
|
|
|
|
}
|
|
|
|
|
2016-06-19 02:01:30 +02:00
|
|
|
client.Notice(fmt.Sprintf("CPU profile writing to %s", profFile))
|
2014-04-15 17:49:52 +02:00
|
|
|
|
|
|
|
case "STOPCPUPROFILE":
|
|
|
|
pprof.StopCPUProfile()
|
2016-06-19 02:01:30 +02:00
|
|
|
client.Notice(fmt.Sprintf("CPU profiling stopped"))
|
2014-04-15 17:49:52 +02:00
|
|
|
}
|
2016-06-19 02:01:30 +02:00
|
|
|
return false
|
2014-04-15 17:49:52 +02:00
|
|
|
}
|