fox/ksync/ksync.go

77 lines
1.9 KiB
Go
Raw Normal View History

2025-05-25 20:02:15 +08:00
package ksync
import (
"fmt"
"github.com/fox/fox/log"
"github.com/wanghuiyt/ding"
"runtime/debug"
"strings"
)
// 辅助函数列表
var (
DingAccessToken = "" // 钉钉token
DingSecret = "" // 钉钉加签
lastAttributeCode = "" // 最近一条error信息
)
func getAttributeCode(stackErr string) string {
lines := strings.Split(stackErr, "\n")
// 检查是否有足够的行数并提取第9行索引为8因为索引从0开始
if len(lines) >= 9 {
goIndex := strings.LastIndex(lines[8], ".go")
if goIndex != -1 {
filteredStr := lines[8][:goIndex]
filteredStr = strings.TrimLeft(filteredStr, "\t ")
return filteredStr
}
}
return ""
}
// 发送消息给钉钉
func sendMessage(msg interface{}, stackErr string, dingToken, dingSecret string) {
if dingToken != "" {
d := ding.Webhook{
AccessToken: dingToken, // 上面获取的 access_token
Secret: dingSecret, // 上面获取的加签的值
}
_ = d.SendMessageText(fmt.Sprintf("Recover panic:%v\n%v", msg, stackErr), "13145922265", "17353003985")
}
}
func Recover(recoverFunc func()) {
if msg := recover(); msg != nil {
stackErr := string(debug.Stack())
attributeCode := getAttributeCode(stackErr)
if lastAttributeCode != attributeCode {
lastAttributeCode = attributeCode
log.ErrorF("Recover panic:%v", msg)
log.Error(stackErr)
sendMessage(msg, stackErr, DingAccessToken, DingSecret)
}
if recoverFunc != nil {
recoverFunc()
}
}
}
// RunSafe runs the given fn, recovers if fn panics.
func RunSafe(fn func(), recoverFunc func()) {
defer Recover(recoverFunc)
fn()
}
// GoSafe runs the given fn using another goroutine, recovers if fn panics.
func GoSafe(fn func(), recoverFunc func()) {
go RunSafe(fn, recoverFunc)
}
// WrapSafe return a RunSafe wrap func
func WrapSafe(fn func(), recoverFunc func()) func() {
return func() {
RunSafe(fn, recoverFunc)
}
}