mirror of
https://github.com/ergochat/ergo.git
synced 2024-12-22 18:52:41 +01:00
expose various go internals as a DEBUG command
This commit is contained in:
parent
f482b6b82f
commit
3b56b5bf42
@ -22,6 +22,7 @@ var (
|
|||||||
parseCommandFuncs = map[StringCode]parseCommandFunc{
|
parseCommandFuncs = map[StringCode]parseCommandFunc{
|
||||||
AWAY: NewAwayCommand,
|
AWAY: NewAwayCommand,
|
||||||
CAP: NewCapCommand,
|
CAP: NewCapCommand,
|
||||||
|
DEBUG: NewDebugCommand,
|
||||||
ISON: NewIsOnCommand,
|
ISON: NewIsOnCommand,
|
||||||
JOIN: NewJoinCommand,
|
JOIN: NewJoinCommand,
|
||||||
KICK: NewKickCommand,
|
KICK: NewKickCommand,
|
||||||
@ -863,3 +864,18 @@ func NewNamesCommand(args []string) (editableCommand, error) {
|
|||||||
}
|
}
|
||||||
return cmd, nil
|
return cmd, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type DebugCommand struct {
|
||||||
|
BaseCommand
|
||||||
|
subCommand string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDebugCommand(args []string) (editableCommand, error) {
|
||||||
|
if len(args) == 0 {
|
||||||
|
return nil, NotEnoughArgsError
|
||||||
|
}
|
||||||
|
|
||||||
|
return &DebugCommand{
|
||||||
|
subCommand: strings.ToUpper(args[0]),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
@ -34,6 +34,7 @@ const (
|
|||||||
// string codes
|
// string codes
|
||||||
AWAY StringCode = "AWAY"
|
AWAY StringCode = "AWAY"
|
||||||
CAP StringCode = "CAP"
|
CAP StringCode = "CAP"
|
||||||
|
DEBUG StringCode = "DEBUG"
|
||||||
ERROR StringCode = "ERROR"
|
ERROR StringCode = "ERROR"
|
||||||
INVITE StringCode = "INVITE"
|
INVITE StringCode = "INVITE"
|
||||||
ISON StringCode = "ISON"
|
ISON StringCode = "ISON"
|
||||||
|
@ -9,6 +9,9 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
|
"runtime"
|
||||||
|
"runtime/debug"
|
||||||
|
"runtime/pprof"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@ -717,3 +720,47 @@ func (msg *NamesCommand) HandleServer(server *Server) {
|
|||||||
channel.Names(client)
|
channel.Names(client)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (server *Server) Reply(target *Client, format string, args ...interface{}) {
|
||||||
|
target.Reply(RplPrivMsg(server, target, fmt.Sprintf(format, args...)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (msg *DebugCommand) HandleServer(server *Server) {
|
||||||
|
client := msg.Client()
|
||||||
|
if !client.flags[Operator] {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch msg.subCommand {
|
||||||
|
case "GC":
|
||||||
|
runtime.GC()
|
||||||
|
server.Reply(client, "OK")
|
||||||
|
|
||||||
|
case "GCSTATS":
|
||||||
|
stats := &debug.GCStats{
|
||||||
|
PauseQuantiles: make([]time.Duration, 5),
|
||||||
|
}
|
||||||
|
server.Reply(client, "last GC: %s", stats.LastGC.Format(time.RFC1123))
|
||||||
|
server.Reply(client, "num GC: %d", stats.NumGC)
|
||||||
|
server.Reply(client, "pause total: %s", stats.PauseTotal)
|
||||||
|
server.Reply(client, "pause quantiles min%%: %s", stats.PauseQuantiles[0])
|
||||||
|
server.Reply(client, "pause quantiles 25%%: %s", stats.PauseQuantiles[1])
|
||||||
|
server.Reply(client, "pause quantiles 50%%: %s", stats.PauseQuantiles[2])
|
||||||
|
server.Reply(client, "pause quantiles 75%%: %s", stats.PauseQuantiles[3])
|
||||||
|
server.Reply(client, "pause quantiles max%%: %s", stats.PauseQuantiles[4])
|
||||||
|
|
||||||
|
case "NUMGOROUTINE":
|
||||||
|
count := runtime.NumGoroutine()
|
||||||
|
server.Reply(client, "num goroutines: %d", count)
|
||||||
|
|
||||||
|
case "PROFILEHEAP":
|
||||||
|
file, err := os.Create("ergonomadic.heap.prof")
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("error: %s", err)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
pprof.Lookup("heap").WriteTo(file, 0)
|
||||||
|
server.Reply(client, "written to ergonomadic-heap.prof")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -74,6 +74,9 @@ func (socket *Socket) Read() <-chan string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (socket *Socket) Write(lines ...string) (err error) {
|
func (socket *Socket) Write(lines ...string) (err error) {
|
||||||
|
if socket.closed {
|
||||||
|
return io.EOF
|
||||||
|
}
|
||||||
for _, line := range lines {
|
for _, line := range lines {
|
||||||
err = socket.WriteLine(line)
|
err = socket.WriteLine(line)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user