Skip to content

Commit

Permalink
添加无需额外配置直接打印stack的功能
Browse files Browse the repository at this point in the history
*unix: kill -USR1 <gocq_pid>
windows: echo dumpstack >\\.\pipe\go-cqhttp-<pid>

stackdump将直接以<exec_name>.<pid>.stacks.<timestamp>.log
的文件名保存在当前工作目录下
  • Loading branch information
povsister committed Jun 26, 2021
1 parent 499108c commit e2cafbd
Show file tree
Hide file tree
Showing 6 changed files with 181 additions and 5 deletions.
52 changes: 52 additions & 0 deletions global/signal.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package global

import (
"fmt"
"os"
"path/filepath"
"runtime"
"sync"
"time"

log "github.com/sirupsen/logrus"
)

var (
mainStopCh chan struct{}
mainOnce sync.Once

dumpMutex sync.Mutex
)

func dumpStack() {
dumpMutex.Lock()
defer dumpMutex.Unlock()

log.Info("开始 dump 当前 goroutine stack 信息")

buf := make([]byte, 1024)
for {
n := runtime.Stack(buf, true)
if n < len(buf) {
buf = buf[:n]
break
}
buf = make([]byte, 2*len(buf))
}

fileName := fmt.Sprintf("%s.%d.stacks.%d.log", filepath.Base(os.Args[0]), os.Getpid(), time.Now().Unix())
fd, err := os.Create(fileName)
if err != nil {
log.Errorf("保存 stackdump 到文件时出现错误: %v", err)
log.Warnf("无法保存 stackdump. 将直接打印\n %s", buf)
return
}
defer fd.Close()
_, err = fd.Write(buf)
if err != nil {
log.Errorf("写入 stackdump 失败: %v", err)
log.Warnf("无法保存 stackdump. 将直接打印\n %s", buf)
return
}
log.Infof("stackdump 已保存至 %s", fileName)
}
34 changes: 34 additions & 0 deletions global/signal_unix.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//+build !windows

package global

import (
"os"
"os/signal"
"sync"
"syscall"
)

func SetupMainSignalHandler() <-chan struct{} {
mainOnce.Do(func() {
mc := make(chan os.Signal, 2)
closeOnce := sync.Once{}
signal.Notify(mc, os.Interrupt, syscall.SIGTERM, syscall.SIGUSR1)
go func() {
for {
s := <-mc
switch s {
case os.Interrupt, syscall.SIGTERM:
closeOnce.Do(func() {
close(mc)
})
case syscall.SIGUSR1:
dumpStack()
}
}
}()

mainStopCh = make(chan struct{})
})
return mainStopCh
}
86 changes: 86 additions & 0 deletions global/signal_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
//+build windows

package global

import (
"fmt"
"os"
"os/signal"
"sync"
"syscall"
"time"

"github.com/Microsoft/go-winio"
log "github.com/sirupsen/logrus"
)

var (
validTasks = []string{
"dumpstack",
}
)

func SetupMainSignalHandler() <-chan struct{} {
mainOnce.Do(func() {
// for stack trace collecting on windows
pipeName := fmt.Sprintf(`\\.\pipe\go-cqhttp-%d`, os.Getpid())
pipe, err := winio.ListenPipe(pipeName, &winio.PipeConfig{})
if err != nil {
log.Error("创建 named pipe 失败. 将无法使用 dumpstack 功能")
} else {
maxTaskLen := 0
for i := range validTasks {
if l := len(validTasks[i]); l > maxTaskLen {
maxTaskLen = l
}
}
go func() {
for {
c, err := pipe.Accept()
if err != nil {
log.Errorf("accept named pipe 失败: %v", err)
continue
}
go func() {
defer c.Close()
_ = c.SetReadDeadline(time.Now().Add(5 * time.Second))
buf := make([]byte, maxTaskLen)
n, err := c.Read(buf)
if err != nil {
log.Errorf("读取 named pipe 失败: %v", err)
return
}
cmd := string(buf[:n])
switch cmd {
case "dumpstack":
dumpStack()
default:
log.Warnf("named pipe 读取到未知指令: %q", cmd)
}
}()
}
}()
}

mc := make(chan os.Signal, 2)
closeOnce := sync.Once{}
signal.Notify(mc, os.Interrupt, syscall.SIGTERM)
go func() {
for {
s := <-mc
switch s {
case os.Interrupt, syscall.SIGTERM:
closeOnce.Do(func() {
close(mc)
if pipe != nil {
_ = pipe.Close()
}
})
}
}
}()

mainStopCh = make(chan struct{})
})
return mainStopCh
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ go 1.16

require (
github.com/Baozisoftware/qrcode-terminal-go v0.0.0-20170407111555-c0650d8dff0f
github.com/Microsoft/go-winio v0.5.0 // indirect
github.com/Mrs4s/MiraiGo v0.0.0-20210611054116-d61d3d491ec7
github.com/dustin/go-humanize v1.0.0
github.com/gin-gonic/gin v1.7.1 // indirect
Expand Down
5 changes: 5 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
github.com/Baozisoftware/qrcode-terminal-go v0.0.0-20170407111555-c0650d8dff0f h1:2dk3eOnYllh+wUOuDhOoC2vUVoJF/5z478ryJ+wzEII=
github.com/Baozisoftware/qrcode-terminal-go v0.0.0-20170407111555-c0650d8dff0f/go.mod h1:4a58ifQTEe2uwwsaqbh3i2un5/CBPg+At/qHpt18Tmk=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/Microsoft/go-winio v0.5.0 h1:Elr9Wn+sGKPlkaBvwu4mTrxtmOp3F3yV9qhaHbXGjwU=
github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
github.com/Mrs4s/MiraiGo v0.0.0-20210611054116-d61d3d491ec7 h1:aW4SXcVqktrcyfYlGiAZ3oDPk0m3yG3y5KQIfQFyyG8=
github.com/Mrs4s/MiraiGo v0.0.0-20210611054116-d61d3d491ec7/go.mod h1:emmgsvc5Mt7yIvR7XOL59pFrKS0Cegrp09s/tZTtzj0=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
Expand Down Expand Up @@ -101,6 +103,7 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk=
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0=
Expand Down Expand Up @@ -164,6 +167,8 @@ golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201126233918-771906719818 h1:f1CIuDlJhwANEC2MM87MBEVMr3jl5bifgsfj90XAF9c=
golang.org/x/sys v0.0.0-20201126233918-771906719818/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c h1:VwygUrnw9jn88c4u8GD3rZQbqrP/tgas88tPUbBxQrk=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210422114643-f5beecf764ed h1:Ei4bQjjpYUsS4efOUz+5Nz++IVkHk87n2zBA0NxBWc0=
golang.org/x/term v0.0.0-20210422114643-f5beecf764ed/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
Expand Down
8 changes: 3 additions & 5 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,10 @@ import (
"io/ioutil"
"os"
"os/exec"
"os/signal"
"path"
"runtime"
"strings"
"sync"
"syscall"
"time"

"github.com/Mrs4s/go-cqhttp/coolq"
Expand Down Expand Up @@ -434,10 +432,10 @@ func main() {
}
log.Info("资源初始化完成, 开始处理信息.")
log.Info("アトリは、高性能ですから!")
c := make(chan os.Signal, 1)

go checkUpdate()
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
<-c

<-global.SetupMainSignalHandler()
}

// PasswordHashEncrypt 使用key加密给定passwordHash
Expand Down

0 comments on commit e2cafbd

Please sign in to comment.