// Copyright (c) 2012-2014 Jeremy Latt // Copyright (c) 2016 Daniel Oaks // released under the MIT license package irc import ( "fmt" "os" "runtime" "runtime/debug" "runtime/pprof" "time" "github.com/DanielOaks/girc-go/ircmsg" ) // DEBUG GCSTATS/NUMGOROUTINE/etc func debugHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool { if !client.flags[Operator] { return false } switch msg.Params[0] { case "GCSTATS": stats := debug.GCStats{ Pause: make([]time.Duration, 10), PauseQuantiles: make([]time.Duration, 5), } debug.ReadGCStats(&stats) 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])) case "NUMGOROUTINE": count := runtime.NumGoroutine() client.Notice(fmt.Sprintf("num goroutines: %d", count)) case "PROFILEHEAP": profFile := "ergonomadic.mprof" file, err := os.Create(profFile) if err != nil { client.Notice(fmt.Sprintf("error: %s", err)) break } defer file.Close() pprof.Lookup("heap").WriteTo(file, 0) client.Notice(fmt.Sprintf("written to %s", profFile)) case "STARTCPUPROFILE": profFile := "ergonomadic.prof" file, err := os.Create(profFile) if err != nil { client.Notice(fmt.Sprintf("error: %s", err)) break } if err := pprof.StartCPUProfile(file); err != nil { defer file.Close() client.Notice(fmt.Sprintf("error: %s", err)) break } client.Notice(fmt.Sprintf("CPU profile writing to %s", profFile)) case "STOPCPUPROFILE": pprof.StopCPUProfile() client.Notice(fmt.Sprintf("CPU profiling stopped")) } return false }