package util import ( "os" "runtime/debug" "sync" "time" "github.com/bytedance/gopkg/util/gopool" "github.com/go-kratos/kratos/v2/log" ) var ( logger *log.Helper once sync.Once ) // getLogger 懒加载获取日志器 func getLogger() *log.Helper { once.Do(func() { // 如果没有手动初始化,使用默认的标准输出日志器 if logger == nil { stdLogger := log.With(log.NewStdLogger(os.Stdout), "ts", log.DefaultTimestamp, "caller", log.DefaultCaller, "component", "safe_pool", ) logger = log.NewHelper(stdLogger) } }) return logger } // InitSafePool 初始化安全协程池(可选,如果不调用会使用默认日志器) func InitSafePool(l log.Logger) { logger = log.NewHelper(l) } // SafeGo 安全执行协程 // taskName: 协程任务名称,用于日志记录 // fn: 要执行的函数 func SafeGo(taskName string, fn func()) { gopool.Go(func() { defer func() { if r := recover(); r != nil { stack := debug.Stack() getLogger().Errorf("协程 [%s] 发生panic: %v\n堆栈信息:\n%s", taskName, r, string(stack)) } }() // 记录协程开始执行 getLogger().Infof("协程 [%s] 开始执行", taskName) start := time.Now() // 执行用户函数 fn() // 记录协程执行完成 duration := time.Since(start) getLogger().Infof("协程 [%s] 执行完成,耗时: %v", taskName, duration) }) }