diff --git a/dice/config.go b/dice/config.go index a10a3591..9f48ecd4 100644 --- a/dice/config.go +++ b/dice/config.go @@ -2613,11 +2613,11 @@ func (d *Dice) Save(isAuto bool) { } d.LastUpdatedTime = 0 } else if err1 != nil && err2 != nil { - d.Logger.Errorln("保存 serve.yaml 和 advanced.yaml 出错", err2) + d.Logger.Error("保存 serve.yaml 和 advanced.yaml 出错", err2) } else if err1 != nil { - d.Logger.Errorln("保存 serve.yaml 出错", err1) + d.Logger.Error("保存 serve.yaml 出错", err1) } else { - d.Logger.Errorln("保存 advanced.yaml 出错", err2) + d.Logger.Error("保存 advanced.yaml 出错", err2) } } } diff --git a/dice/dice.go b/dice/dice.go index 960040de..82b91a1d 100644 --- a/dice/dice.go +++ b/dice/dice.go @@ -19,8 +19,6 @@ import ( "github.com/robfig/cron/v3" ds "github.com/sealdice/dicescript" "github.com/tidwall/buntdb" - "go.uber.org/zap" - rand2 "golang.org/x/exp/rand" "golang.org/x/exp/slices" "golang.org/x/time/rate" @@ -28,6 +26,7 @@ import ( "sealdice-core/dice/censor" "sealdice-core/dice/logger" "sealdice-core/dice/model" + log "sealdice-core/utils/kratos" ) type CmdExecuteResult struct { @@ -104,10 +103,10 @@ type ExtInfo struct { OnLoad func() `yaml:"-" json:"-" jsbind:"onLoad"` } +// DiceConfig TODO:历史遗留问题,由于不输出DICE日志效果过差,已经抹除日志输出选项,剩余两个选项,私以为可以想办法也抹除掉。 type DiceConfig struct { //nolint:revive - Name string `yaml:"name"` // 名称,默认为default - DataDir string `yaml:"dataDir"` // 数据路径,为./data/{name},例如data/default - IsLogPrint bool `yaml:"isLogPrint"` // 是否在控制台打印log + Name string `yaml:"name"` // 名称,默认为default + DataDir string `yaml:"dataDir"` // 数据路径,为./data/{name},例如data/default } type ExtDefaultSettingItem struct { @@ -138,8 +137,8 @@ type Dice struct { BaseConfig DiceConfig `yaml:"-"` DBData *sqlx.DB `yaml:"-"` // 数据库对象 DBLogs *sqlx.DB `yaml:"-"` // 数据库对象 - Logger *zap.SugaredLogger `yaml:"-"` // 日志 - LogWriter *logger.WriterX `yaml:"-"` // 用于api的log对象 + Logger *log.Helper `yaml:"-"` // 日志 + LogWriter *log.WriterX `yaml:"-"` // 用于api的log对象 IsDeckLoading bool `yaml:"-"` // 正在加载中 DeckList []*DeckInfo `yaml:"deckList" jsbind:"deckList"` // 牌堆信息 CommandPrefix []string `yaml:"commandPrefix" jsbind:"commandPrefix"` // 指令前导 @@ -314,7 +313,7 @@ func (d *Dice) Init() { _ = os.MkdirAll(filepath.Join(d.BaseConfig.DataDir, "extra"), 0o755) _ = os.MkdirAll(filepath.Join(d.BaseConfig.DataDir, "scripts"), 0o755) - log := logger.Init(filepath.Join(d.BaseConfig.DataDir, "record.log"), d.BaseConfig.Name, d.BaseConfig.IsLogPrint) + log := logger.Init() d.Logger = log.Logger d.LogWriter = log.WX diff --git a/dice/dice_attrs_manager.go b/dice/dice_attrs_manager.go index ba7e4019..c1a9e8a8 100644 --- a/dice/dice_attrs_manager.go +++ b/dice/dice_attrs_manager.go @@ -8,14 +8,14 @@ import ( "github.com/jmoiron/sqlx" ds "github.com/sealdice/dicescript" - "go.uber.org/zap" "sealdice-core/dice/model" + log "sealdice-core/utils/kratos" ) type AttrsManager struct { db *sqlx.DB - logger *zap.SugaredLogger + logger *log.Helper m SyncMap[string, *AttributesItem] } diff --git a/dice/dice_backup.go b/dice/dice_backup.go index 8ce8c138..bcb0e52e 100644 --- a/dice/dice_backup.go +++ b/dice/dice_backup.go @@ -226,20 +226,20 @@ func (dm *DiceManager) Backup(sel BackupSelection, fromAuto bool) (string, error err := model.FlushWAL(d.DBData) if err != nil { - d.Logger.Warnln("备份时data数据库flush出错", err.Error()) + d.Logger.Errorf("备份时data数据库flush出错 错误为:%v", err.Error()) } else { backup(d, filepath.Join(dataDir, "data.db")) } err = model.FlushWAL(d.DBLogs) if err != nil { - d.Logger.Warnln("备份时logs数据库flush出错", err.Error()) + d.Logger.Errorf("备份时logs数据库flush出错 错误为:%v", err.Error()) } else { backup(d, filepath.Join(dataDir, "data-logs.db")) } if d.CensorManager != nil && d.CensorManager.DB != nil { err = model.FlushWAL(d.CensorManager.DB) if err != nil { - d.Logger.Warnln("备份时censor数据库flush出错", err.Error()) + d.Logger.Errorf("备份时censor数据库flush出错 %v", err.Error()) } else { backup(d, filepath.Join(dataDir, "data-censor.db")) } diff --git a/dice/dice_jsvm.go b/dice/dice_jsvm.go index cc27debd..8fc7974a 100644 --- a/dice/dice_jsvm.go +++ b/dice/dice_jsvm.go @@ -28,12 +28,12 @@ import ( "github.com/pkg/errors" "github.com/robfig/cron/v3" "github.com/samber/lo" - "go.uber.org/zap" "gopkg.in/elazarl/goproxy.v1" "gopkg.in/yaml.v3" "sealdice-core/static" "sealdice-core/utils/crypto" + log "sealdice-core/utils/kratos" ) var ( @@ -1335,7 +1335,7 @@ type JsScriptTask struct { entryID *cron.EntryID lock *sync.Mutex - logger *zap.SugaredLogger + logger *log.Helper } type JsScriptTaskCtx struct { diff --git a/dice/dice_manager.go b/dice/dice_manager.go index 612a97f5..2d0a9ad4 100644 --- a/dice/dice_manager.go +++ b/dice/dice_manager.go @@ -8,8 +8,9 @@ import ( "github.com/dop251/goja_nodejs/require" "github.com/robfig/cron/v3" - "go.uber.org/zap" "gopkg.in/yaml.v3" + + log "sealdice-core/utils/kratos" ) type VersionInfo struct { @@ -75,7 +76,7 @@ type DiceManager struct { //nolint:revive ServiceName string JustForTest bool JsRegistry *require.Registry - UpdateSealdiceByFile func(packName string, log *zap.SugaredLogger) bool // 使用指定压缩包升级海豹,如果出错返回false,如果成功进程会自动结束 + UpdateSealdiceByFile func(packName string, log *log.Helper) bool // 使用指定压缩包升级海豹,如果出错返回false,如果成功进程会自动结束 ContainerMode bool // 容器模式:禁用内置适配器,不允许使用内置Lagrange和旧的内置Gocq CleanupFlag atomic.Uint32 // 1 为正在清理,0为普通状态 @@ -325,7 +326,6 @@ func (dm *DiceManager) TryCreateDefault() { if len(dm.Dice) == 0 { defaultDice := new(Dice) defaultDice.BaseConfig.Name = "default" - defaultDice.BaseConfig.IsLogPrint = true defaultDice.MessageDelayRangeStart = 0.4 defaultDice.MessageDelayRangeEnd = 0.9 defaultDice.MarkModified() diff --git a/dice/dice_name_generator.go b/dice/dice_name_generator.go index cc0c0924..63f08cdc 100644 --- a/dice/dice_name_generator.go +++ b/dice/dice_name_generator.go @@ -9,6 +9,8 @@ import ( wr "github.com/mroth/weightedrand" "github.com/xuri/excelize/v2" + + log "sealdice-core/utils/kratos" ) type NamesGenerator struct { @@ -24,7 +26,7 @@ func (ng *NamesGenerator) Load() { for _, fn := range []string{"./data/names/names.xlsx", "./data/names/names-dnd.xlsx"} { f, err := excelize.OpenFile(fn) if err != nil { - fmt.Println("加载names信息出错", fn, err) + log.Warn("加载names信息出错", fn, err) continue } diff --git a/dice/js_api.go b/dice/js_api.go index a9cf539a..70fff6e7 100644 --- a/dice/js_api.go +++ b/dice/js_api.go @@ -8,10 +8,10 @@ import ( "os" "path/filepath" - "go.uber.org/zap" + log "sealdice-core/utils/kratos" ) -func Base64ToImageFunc(logger *zap.SugaredLogger) func(string) (string, error) { +func Base64ToImageFunc(logger *log.Helper) func(string) (string, error) { return func(b64 string) (string, error) { // 解码 Base64 值 data, e := base64.StdEncoding.DecodeString(b64) diff --git a/dice/logger/logger.go b/dice/logger/logger.go index 7a0359cf..a6b0ae93 100644 --- a/dice/logger/logger.go +++ b/dice/logger/logger.go @@ -1,113 +1,20 @@ package logger import ( - "encoding/json" - "os" - - "github.com/natefinch/lumberjack" - "go.uber.org/zap" - "go.uber.org/zap/zapcore" + log "sealdice-core/utils/kratos" ) -var enabledLevel = zap.InfoLevel - -func SetEnableLevel(level zapcore.Level) { - switch level { - case zapcore.DebugLevel, zapcore.InfoLevel, zapcore.WarnLevel, zapcore.ErrorLevel, - zapcore.DPanicLevel, zapcore.PanicLevel, zapcore.FatalLevel: - { - enabledLevel = level - } - default: // no-op - } -} - -type LogItem struct { - Level string `json:"level"` - TS float64 `json:"ts"` - Caller string `json:"caller"` - Msg string `json:"msg"` -} - -type WriterX struct { - LogLimit int64 - Items []*LogItem -} - type LogInfo struct { - LoggerRaw *zap.Logger - Logger *zap.SugaredLogger - WX *WriterX + Logger *log.Helper + WX *log.WriterX } -var logLimitDefault int64 = 100 - -func (w *WriterX) Write(p []byte) (n int, err error) { - var a LogItem - err2 := json.Unmarshal(p, &a) - if err2 == nil { - w.Items = append(w.Items, &a) - limit := w.LogLimit - if limit == 0 { - w.LogLimit = logLimitDefault - } - if len(w.Items) > int(limit) { - w.Items = w.Items[1:] - } - } - return len(p), nil -} - -func Init(path string, name string, enableConsoleLog bool) *LogInfo { - lumlog := &lumberjack.Logger{ - Filename: path, - MaxSize: 10, // megabytes - MaxBackups: 3, // number of log files - MaxAge: 7, // days - } - - encoder := getEncoder() - - pe := zap.NewProductionEncoderConfig() - wx := &WriterX{} - - cores := []zapcore.Core{ - zapcore.NewCore(encoder, zapcore.AddSync(lumlog), enabledLevel), - - // This outputs to WebUI, DO NOT apply enabledLevel - zapcore.NewCore(zapcore.NewJSONEncoder(pe), zapcore.AddSync(wx), zapcore.InfoLevel), - } - - if enableConsoleLog { - pe2 := zap.NewProductionEncoderConfig() - pe2.EncodeTime = zapcore.ISO8601TimeEncoder - - consoleEncoder := zapcore.NewConsoleEncoder(pe2) - consoleEncoder.AddString("dice", name) - cores = append(cores, zapcore.NewCore(consoleEncoder, zapcore.AddSync(os.Stdout), enabledLevel)) - } - - core := zapcore.NewTee(cores...) - - loggerRaw := zap.New(core, zap.AddCaller()) - defer func(loggerRaw *zap.Logger) { - _ = loggerRaw.Sync() - }(loggerRaw) // flushes buffer, if any - - logger := loggerRaw.Sugar() - logger.Infow("Dice日志开始记录") - +func Init() *LogInfo { + // KV输出 + loghelper := log.NewCustomHelper(log.LOG_DICE, false, nil) + loghelper.Info("Dice日志开始记录") return &LogInfo{ - LoggerRaw: loggerRaw, - Logger: logger, - WX: wx, + Logger: loghelper, + WX: log.GetWriterX(), } } - -func getEncoder() zapcore.Encoder { - encoderConfig := zap.NewProductionEncoderConfig() - encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder - encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder - - return zapcore.NewConsoleEncoder(encoderConfig) -} diff --git a/dice/model/group_info.go b/dice/model/group_info.go index b13230ba..0dfa213a 100644 --- a/dice/model/group_info.go +++ b/dice/model/group_info.go @@ -25,7 +25,6 @@ func GroupInfoListGet(db *sqlx.DB, callback func(id string, updatedAt int64, dat err = rows.Scan(&id, &pUpdatedAt, &data) if err != nil { - fmt.Println("!!!", err.Error()) return err } diff --git a/dice/model/log.go b/dice/model/log.go index 1732fde5..b38e7b5d 100644 --- a/dice/model/log.go +++ b/dice/model/log.go @@ -9,6 +9,8 @@ import ( "time" "github.com/jmoiron/sqlx" + + log "sealdice-core/utils/kratos" ) type LogOne struct { @@ -480,7 +482,7 @@ func LogMarkDeleteByMsgID(db *sqlx.DB, groupID string, logName string, rawID int // fmt.Printf("log delete %v %d\n", rawId, logId) _, err = db.Exec("DELETE FROM log_items WHERE log_id=? AND raw_msg_id=?", logID, rid) if err != nil { - fmt.Println("log delete error", err.Error()) + log.Error("log delete error", err.Error()) return err } diff --git a/dice/platform_adapter_gocq.go b/dice/platform_adapter_gocq.go index 223afc58..2479de4b 100644 --- a/dice/platform_adapter_gocq.go +++ b/dice/platform_adapter_gocq.go @@ -18,10 +18,10 @@ import ( "github.com/labstack/echo/v4" "github.com/sacOO7/gowebsocket" "github.com/samber/lo" - "go.uber.org/zap" "gopkg.in/yaml.v3" "sealdice-core/message" + log "sealdice-core/utils/kratos" "sealdice-core/utils/procs" ) @@ -273,7 +273,7 @@ func FormatDiceIDQQChGroup(guildID, channelID string) string { return fmt.Sprintf("QQ-CH-Group:%s-%s", guildID, channelID) } -func tryParseOneBot11ArrayMessage(log *zap.SugaredLogger, message string, writeTo *MessageQQ) error { +func tryParseOneBot11ArrayMessage(log *log.Helper, message string, writeTo *MessageQQ) error { msgQQType2 := new(MessageQQArray) err := json.Unmarshal([]byte(message), msgQQType2) @@ -560,7 +560,7 @@ func (pa *PlatformAdapterGocq) Serve() int { } else { // TODO: 这玩意的创建是个专业活,等下来弄 // session.ServiceAtNew[groupId] = GroupInfo{} - fmt.Println("TODO create group") + log.Debug("TODO create group") } // 这句话太吵了 // log.Debug("群信息刷新: ", msgQQ.Data.GroupName) @@ -992,7 +992,7 @@ func (pa *PlatformAdapterGocq) Serve() int { if pa.riskAlertShieldCount > 0 { pa.riskAlertShieldCount-- } else { - fmt.Println("群消息发送失败: 账号可能被风控") + log.Warn("群消息发送失败: 账号可能被风控") _ = ctx.Dice.SendMail("群消息发送失败: 账号可能被风控", MailTypeCIAMLock) } } @@ -1050,7 +1050,7 @@ func (pa *PlatformAdapterGocq) Serve() int { } session.Execute(ep, msg, false) } else { - fmt.Println("Received message " + message) + log.Debug("Received message " + message) } } diff --git a/dice/platform_adapter_gocq_helper.go b/dice/platform_adapter_gocq_helper.go index 0a7f121e..78d67129 100644 --- a/dice/platform_adapter_gocq_helper.go +++ b/dice/platform_adapter_gocq_helper.go @@ -18,9 +18,9 @@ import ( "github.com/ShiraazMoollatjie/goluhn" "github.com/acarl005/stripansi" "github.com/google/uuid" - "go.uber.org/zap" "sealdice-core/utils" + log "sealdice-core/utils/kratos" "sealdice-core/utils/procs" ) @@ -881,7 +881,7 @@ func builtinGoCqhttpServe(dice *Dice, conn *EndPointInfo, loginInfo GoCqhttpLogi if strings.Contains(line, "请使用手机QQ扫描二维码以继续登录") { // TODO - fmt.Println("请使用手机QQ扫描二维码以继续登录") + log.Info("请使用手机QQ扫描二维码以继续登录") } if (pa.IsLoginSuccessed() && strings.Contains(line, "[ERROR]:") && strings.Contains(line, "Protocol -> sendPacket msg error: 120")) || strings.Contains(line, "账号可能被风控####2测试触发语句") { @@ -1036,7 +1036,7 @@ func builtinGoCqhttpServe(dice *Dice, conn *EndPointInfo, loginInfo GoCqhttpLogi var isGocqDownloading = false -func downloadGoCqhttp(logger *zap.SugaredLogger) { +func downloadGoCqhttp(logger *log.Helper) { fn := "go-cqhttp/go-cqhttp" if runtime.GOOS == "windows" { fn += ".exe" diff --git a/dice/platform_adapter_lagrange_helper.go b/dice/platform_adapter_lagrange_helper.go index 1827b9e5..8d89d641 100644 --- a/dice/platform_adapter_lagrange_helper.go +++ b/dice/platform_adapter_lagrange_helper.go @@ -15,6 +15,7 @@ import ( "github.com/google/uuid" + log "sealdice-core/utils/kratos" "sealdice-core/utils/procs" ) @@ -54,10 +55,10 @@ func LagrangeServe(dice *Dice, conn *EndPointInfo, loginInfo LagrangeLoginInfo) pa.GoCqhttpState = StateCodeInLogin if pa.UseInPackClient && pa.BuiltinMode == "lagrange" { //nolint:nestif - log := dice.Logger + helper := log.NewCustomHelper(log.LOG_LAGR, false, nil) if dice.ContainerMode { - log.Warn("onebot: 尝试启动内置客户端,但内置客户端在容器模式下被禁用") + helper.Warn("onebot: 尝试启动内置客户端,但内置客户端在容器模式下被禁用") conn.State = 3 pa.GoCqhttpState = StateCodeLoginFailed dice.Save(false) @@ -85,7 +86,7 @@ func LagrangeServe(dice *Dice, conn *EndPointInfo, loginInfo LagrangeLoginInfo) _ = os.Remove(qrcodeFilePath) } } - log.Info("onebot: 删除已存在的二维码文件") + helper.Info("onebot: 删除已存在的二维码文件") // 创建配置文件 pa.ConnectURL = "" @@ -116,7 +117,7 @@ func LagrangeServe(dice *Dice, conn *EndPointInfo, loginInfo LagrangeLoginInfo) if runtime.GOOS == "android" { for i, s := range os.Environ() { if strings.HasPrefix(s, "RUNNER_PATH=") { - log.Infof("RUNNER_PATH: %s", os.Environ()[i][12:]) + helper.Infof("RUNNER_PATH: %s", os.Environ()[i][12:]) command = os.Environ()[i][12:] break } @@ -127,7 +128,7 @@ func LagrangeServe(dice *Dice, conn *EndPointInfo, loginInfo LagrangeLoginInfo) } else { command = fmt.Sprintf(`"%s"`, exeFilePath) } - log.Info("onebot: 正在启动 onebot 客户端…… ", command) + helper.Info("onebot: 正在启动 onebot 客户端…… ", command) conn.State = 2 conn.Enable = true p := procs.NewProcess(command) @@ -143,7 +144,7 @@ func LagrangeServe(dice *Dice, conn *EndPointInfo, loginInfo LagrangeLoginInfo) if loginIndex != pa.CurLoginIndex { // 当前连接已经无用,进程自杀 if !isSelfKilling { - log.Infof("检测到新的连接序号 %d,当前连接 %d 将自动退出", pa.CurLoginIndex, loginIndex) + helper.Infof("检测到新的连接序号 %d,当前连接 %d 将自动退出", pa.CurLoginIndex, loginIndex) // 注: 这里不要调用kill isSelfKilling = true _ = p.Stop() @@ -162,7 +163,7 @@ func LagrangeServe(dice *Dice, conn *EndPointInfo, loginInfo LagrangeLoginInfo) if strings.Contains(line, "Success") || strings.Contains(line, "Bot Online: ") { pa.GoCqhttpState = StateCodeLoginSuccessed pa.GoCqhttpLoginSucceeded = true - log.Infof("onebot: 登录成功,账号:<%s>(%s)", conn.Nickname, conn.UserID) + helper.Infof("onebot: 登录成功,账号:<%s>(%s)", conn.Nickname, conn.UserID) dice.LastUpdatedTime = time.Now().Unix() dice.Save(false) isPrintLog = false @@ -175,20 +176,20 @@ func LagrangeServe(dice *Dice, conn *EndPointInfo, loginInfo LagrangeLoginInfo) if strings.Contains(line, "QrCode Expired, Please Fetch QrCode Again") { // 二维码过期,登录失败,杀掉进程 pa.GoCqhttpState = StateCodeLoginFailed - log.Infof("onebot: 二维码过期,登录失败,账号:%s", conn.UserID) + helper.Infof("onebot: 二维码过期,登录失败,账号:%s", conn.UserID) BuiltinQQServeProcessKill(dice, conn) } } if _type == "stderr" { - log.Error("onebot | ", line) + helper.Error("onebot | ", line) } else { isPrint := isPrintLog || pa.ForcePrintLog || strings.HasPrefix(line, "warn:") if isPrint { - log.Warn("onebot | ", line) + helper.Warn("onebot | ", line) } if regFatal.MatchString(line) { - log.Error("onebot | ", line) + helper.Error("onebot | ", line) } } @@ -199,12 +200,12 @@ func LagrangeServe(dice *Dice, conn *EndPointInfo, loginInfo LagrangeLoginInfo) <-chQrCode time.Sleep(3 * time.Second) if _, err := os.Stat(qrcodeFilePath); err == nil { - log.Info("onebot: 二维码已就绪") + helper.Info("onebot: 二维码已就绪") qrdata, err := os.ReadFile(qrcodeFilePath) if err == nil { pa.GoCqhttpState = StateCodeInLoginQrCode pa.GoCqhttpQrcodeData = qrdata - log.Info("onebot: 读取二维码成功") + helper.Info("onebot: 读取二维码成功") dice.LastUpdatedTime = time.Now().Unix() dice.Save(false) } else { @@ -213,7 +214,7 @@ func LagrangeServe(dice *Dice, conn *EndPointInfo, loginInfo LagrangeLoginInfo) pa.GocqhttpLoginFailedReason = "读取二维码失败" dice.LastUpdatedTime = time.Now().Unix() dice.Save(false) - log.Infof("onebot: 读取二维码失败:%s", err) + helper.Infof("onebot: 读取二维码失败:%s", err) } } }() @@ -221,7 +222,7 @@ func LagrangeServe(dice *Dice, conn *EndPointInfo, loginInfo LagrangeLoginInfo) run := func() { defer func() { if r := recover(); r != nil { - log.Errorf("onebot: 异常: %v 堆栈: %v", r, string(debug.Stack())) + helper.Errorf("onebot: 异常: %v 堆栈: %v", r, string(debug.Stack())) } }() @@ -249,7 +250,7 @@ func LagrangeServe(dice *Dice, conn *EndPointInfo, loginInfo LagrangeLoginInfo) } if err != nil { - log.Info("lagrange 进程异常退出: ", err) + helper.Info("lagrange 进程异常退出: ", err) pa.GoCqhttpState = StateCodeLoginFailed var exitErr *exec.ExitError @@ -259,21 +260,21 @@ func LagrangeServe(dice *Dice, conn *EndPointInfo, loginInfo LagrangeLoginInfo) case 137: // Failed to create CoreCLR, HRESULT: 0x8007054F // +++ exited with 137 +++ - log.Info("你的设备尚未被支持,请等待后续更新。") + helper.Info("你的设备尚未被支持,请等待后续更新。") case 134: // Resource temporarily unavailable // System.Net.Dns.GetHostEntryOrAddressesCore(String hostName, Boolean justAddresses, AddressFamily addressFamily, Int64 startingTimestamp) - log.Info("当前网络无法进行域名解析,请更换网络。") + helper.Info("当前网络无法进行域名解析,请更换网络。") default: if time.Now().Unix()-processStartTime < 10 { - log.Info("进程在启动后10秒内即退出,请检查配置是否正确") + helper.Info("进程在启动后10秒内即退出,请检查配置是否正确") } else { if pa.lagrangeRebootTimes > 5 { - log.Info("自动重启次数达到上限,放弃") + helper.Info("自动重启次数达到上限,放弃") } else { pa.lagrangeRebootTimes++ if conn.Enable { - log.Info("5秒后,尝试对其进行重启") + helper.Info("5秒后,尝试对其进行重启") time.Sleep(5 * time.Second) } if conn.Enable { @@ -284,7 +285,7 @@ func LagrangeServe(dice *Dice, conn *EndPointInfo, loginInfo LagrangeLoginInfo) } } } else { - log.Info("lagrange 进程退出") + helper.Info("lagrange 进程退出") } } diff --git a/dice/platform_adapter_official_qq.go b/dice/platform_adapter_official_qq.go index 2e4f6994..5b4a64bf 100644 --- a/dice/platform_adapter_official_qq.go +++ b/dice/platform_adapter_official_qq.go @@ -42,7 +42,7 @@ func (pa *PlatformAdapterOfficialQQ) Serve() int { d := pa.Session.Parent log.Debug("official qq server") - qqbot.SetLogger(NewDummyLogger(log.Desugar())) + qqbot.SetLogger(NewDummyLogger()) token := qqtoken.BotToken(pa.AppID, pa.Token) pa.Api = qqbot.NewOpenAPI(token).WithTimeout(3 * time.Second) pa.Ctx, pa.CancelFunc = context.WithCancel(context.Background()) diff --git a/dice/platform_adapter_official_qq_helper.go b/dice/platform_adapter_official_qq_helper.go index b0b0220f..15ce105c 100644 --- a/dice/platform_adapter_official_qq_helper.go +++ b/dice/platform_adapter_official_qq_helper.go @@ -9,7 +9,8 @@ import ( "time" "github.com/google/uuid" - "go.uber.org/zap" + + log "sealdice-core/utils/kratos" ) func NewOfficialQQConnItem(appID uint64, token string, appSecret string, onlyQQGuild bool) *EndPointInfo { @@ -45,12 +46,12 @@ func ServerOfficialQQ(d *Dice, ep *EndPointInfo) { } type DummyLogger struct { - logger *zap.Logger + logger *log.Helper } -func NewDummyLogger(logger *zap.Logger) DummyLogger { +func NewDummyLogger() DummyLogger { return DummyLogger{ - logger: logger, + logger: log.NewHelper(log.With(log.GetLogger(), "caller", "officialQQ")), } } diff --git a/dice/platform_adapter_walleq.go b/dice/platform_adapter_walleq.go index c1c041d0..54b88061 100644 --- a/dice/platform_adapter_walleq.go +++ b/dice/platform_adapter_walleq.go @@ -205,7 +205,7 @@ func (pa *PlatformAdapterWalleQ) Serve() int { // tempFriendInviteSent := map[string]int64{} // gocq会重新发送已经发过的邀请 socket.OnTextMessage = func(message string, socket gowebsocket.Socket) { - fmt.Println(message) + log.Debug(message) event := new(EventWalleQBase) err := json.Unmarshal([]byte(message), event) if err != nil { @@ -598,7 +598,7 @@ func (pa *PlatformAdapterWalleQ) Serve() int { // 事件都有 ID,没有就是响应 but 有几个元事件 ID 是 "" ;把响应处理放到最后吧 //nolint:nestif if event.ID == "" { - fmt.Println(message) + log.Debug(message) echo := new(EchoWalleQ) err = json.Unmarshal([]byte(message), echo) if err != nil { diff --git a/dice/platform_adapter_walleq_helper.go b/dice/platform_adapter_walleq_helper.go index 91f9ec2a..8ceaa986 100644 --- a/dice/platform_adapter_walleq_helper.go +++ b/dice/platform_adapter_walleq_helper.go @@ -13,6 +13,7 @@ import ( "github.com/google/uuid" "github.com/pelletier/go-toml/v2" + log2 "sealdice-core/utils/kratos" "sealdice-core/utils/procs" ) @@ -133,7 +134,7 @@ func WalleQServe(dice *Dice, conn *EndPointInfo, password string, protocol int, pa.CurLoginIndex++ loginIndex := pa.CurLoginIndex pa.WalleQState = WqStateCodeInLogin - fmt.Println("WalleQServe begin") + log2.Debug("WalleQServe begin") workDir := filepath.Join(dice.BaseConfig.DataDir, conn.RelWorkDir) _ = os.MkdirAll(workDir, 0o755) log := dice.Logger @@ -173,7 +174,7 @@ func WalleQServe(dice *Dice, conn *EndPointInfo, password string, protocol int, wqc := new(WalleQConfig) _, err = toml.DecodeFile(configFilePath,wqc) if err != nil { - dice.Logger.Error("读取 Walle-q 配置文件失败,请检查!") + dice.Zlogger.Error("读取 Walle-q 配置文件失败,请检查!") return } id, _ := pa.mustExtractId(conn.UserId) @@ -197,7 +198,7 @@ func WalleQServe(dice *Dice, conn *EndPointInfo, password string, protocol int, isSeldKilling := false p.OutputHandler = func(line string, _type string) string { - fmt.Println(line) + log.Debug(line) if loginIndex != pa.CurLoginIndex { // 当前连接已经无用,进程自杀 if !isSeldKilling { diff --git a/dice/rollvm_migrate.go b/dice/rollvm_migrate.go index b4762804..42679153 100644 --- a/dice/rollvm_migrate.go +++ b/dice/rollvm_migrate.go @@ -12,6 +12,8 @@ import ( "github.com/samber/lo" ds "github.com/sealdice/dicescript" + + log "sealdice-core/utils/kratos" ) func (v *VMValue) ConvertToV2() *ds.VMValue { @@ -138,7 +140,7 @@ func (ctx *MsgContext) EvalFString(expr string, flags *ds.RollConfig) *VMResultV // 隐藏的内置字符串符号 \x1e r := ctx.Eval("\x1e"+expr+"\x1e", flags) if r.vm.Error != nil { - fmt.Println("脚本执行出错: ", expr, "->", r.vm.Error) + log.Error("脚本执行出错: ", expr, "->", r.vm.Error) } return r } @@ -235,7 +237,7 @@ func DiceExprEvalBase(ctx *MsgContext, s string, flags RollExtraFlags) (*VMResul if flags.V2Only { return nil, "", err } - fmt.Println("脚本执行出错V2: ", strings.ReplaceAll(s, "\x1e", "`"), "->", err) + log.Error("脚本执行出错V2: ", strings.ReplaceAll(s, "\x1e", "`"), "->", err) errV2 := err // 某种情况下没有这个值,很奇怪 // 尝试一下V1 diff --git a/dice/storylog/storylog.go b/dice/storylog/storylog.go index 156c96ae..1741e026 100644 --- a/dice/storylog/storylog.go +++ b/dice/storylog/storylog.go @@ -10,15 +10,15 @@ import ( "strconv" "github.com/jmoiron/sqlx" - "go.uber.org/zap" "sealdice-core/dice/model" + log "sealdice-core/utils/kratos" ) type UploadEnv struct { Dir string Db *sqlx.DB - Log *zap.SugaredLogger + Log *log.Helper Backends []string Version StoryVersion diff --git a/dice/verify.go b/dice/verify.go index 2521556c..8ecf123d 100644 --- a/dice/verify.go +++ b/dice/verify.go @@ -10,6 +10,7 @@ import ( "github.com/vmihailenco/msgpack" "sealdice-core/utils/crypto" + log "sealdice-core/utils/kratos" ) var ( @@ -23,7 +24,7 @@ func initVerify() { if len(key) > 0 { SealTrustedClientPrivateKey = key } else { - fmt.Println("SEAL_TRUSTED_PRIVATE_KEY not found, maybe in development mode") + log.Warn("SEAL_TRUSTED_PRIVATE_KEY not found, maybe in development mode") } } diff --git a/go.mod b/go.mod index c7bbda3f..35a73eee 100644 --- a/go.mod +++ b/go.mod @@ -26,7 +26,6 @@ require ( github.com/go-creed/sat v1.0.3 github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1 github.com/golang-module/carbon v1.7.3 - github.com/gonutz/w32/v2 v2.11.1 github.com/google/uuid v1.6.0 github.com/gorilla/websocket v1.5.1 github.com/grokify/html-strip-tags-go v0.0.1 @@ -121,15 +120,15 @@ require ( github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/pprof v0.0.0-20230926050212-f7f687d19a98 // indirect - github.com/hhrutter/lzw v0.0.0-20230302233922-b0c9d7de54a7 // indirect - github.com/hhrutter/tiff v0.0.0-20230302235510-5b20711894ae // indirect + github.com/hhrutter/lzw v1.0.0 // indirect + github.com/hhrutter/tiff v1.0.1 // indirect github.com/joho/godotenv v1.3.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/labstack/gommon v0.4.2 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-runewidth v0.0.14 // indirect + github.com/mattn/go-runewidth v0.0.16 // indirect github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect @@ -137,14 +136,14 @@ require ( github.com/mschoch/smat v0.2.0 // indirect github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d // indirect github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c // indirect - github.com/pdfcpu/pdfcpu v0.4.0 // indirect + github.com/pdfcpu/pdfcpu v0.8.1 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/richardlehane/mscfb v1.0.4 // indirect github.com/richardlehane/msoleps v1.0.3 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/rogpeppe/go-internal v1.11.0 // indirect github.com/sacOO7/go-logger v0.0.0-20180719173527-9ac9add5a50d // indirect - github.com/sunshineplan/pdf v1.0.3 // indirect + github.com/sunshineplan/pdf v1.0.7 // indirect github.com/sunshineplan/tiff v0.0.0-20220128141034-29b9d69bd906 // indirect github.com/tadvi/systray v0.0.0-20190226123456-11a2b8fa57af // indirect github.com/tdewolff/parse/v2 v2.7.15 // indirect @@ -160,7 +159,7 @@ require ( github.com/xuri/efp v0.0.0-20231025114914-d1ff6096ae53 // indirect github.com/xuri/nfp v0.0.0-20230919160717-d98342af3f05 // indirect go.uber.org/multierr v1.10.0 // indirect - golang.org/x/image v0.18.0 // indirect + golang.org/x/image v0.19.0 // indirect golang.org/x/mod v0.18.0 // indirect golang.org/x/net v0.24.0 // indirect golang.org/x/sync v0.8.0 // indirect @@ -174,6 +173,7 @@ require ( modernc.org/mathutil v1.6.0 // indirect modernc.org/memory v1.7.2 // indirect modernc.org/sqlite v1.28.0 // indirect + moul.io/zapfilter v1.7.0 // indirect ) replace ( diff --git a/go.sum b/go.sum index 27aa379c..c4e36615 100644 --- a/go.sum +++ b/go.sum @@ -23,6 +23,7 @@ github.com/antlabs/strsim v0.0.3/go.mod h1:bIcymn+2jtt01korFun0bs8PsYZeQa82aHoYM github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= github.com/bits-and-blooms/bitset v1.2.2 h1:J5gbX05GpMdBjCvQ9MteIg2KKDExr7DrgK+Yc15FvIk= github.com/bits-and-blooms/bitset v1.2.2/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= @@ -177,8 +178,6 @@ github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/gonutz/w32/v2 v2.11.1 h1:plG738ZY7VIkPGf3adZ6lFeAf2evCKrULKyZT5GrPoc= -github.com/gonutz/w32/v2 v2.11.1/go.mod h1:MgtHx0AScDVNKyB+kjyPder4xIi3XAcHS6LDDU2DmdE= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= @@ -200,10 +199,10 @@ github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZH github.com/grokify/html-strip-tags-go v0.0.1 h1:0fThFwLbW7P/kOiTBs03FsJSV9RM2M/Q/MOnCQxKMo0= github.com/grokify/html-strip-tags-go v0.0.1/go.mod h1:2Su6romC5/1VXOQMaWL2yb618ARB8iVo6/DR99A6d78= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hhrutter/lzw v0.0.0-20230302233922-b0c9d7de54a7 h1:oYOKPR69u1kReWwnVhZlkduTrEtXRYJTDj5rUCMyPLY= -github.com/hhrutter/lzw v0.0.0-20230302233922-b0c9d7de54a7/go.mod h1:2HC6DJSn/n6iAZfgM3Pg+cP1KxeWc3ezG8bBqW5+WEo= -github.com/hhrutter/tiff v0.0.0-20230302235510-5b20711894ae h1:cpxrFNY+FIz7W4nuaG5McM/OyOBQt44Thl0Q/hFBhGo= -github.com/hhrutter/tiff v0.0.0-20230302235510-5b20711894ae/go.mod h1:zluYmeCkNexc8HFzfc2MTVwA8gcPuFQp/ngjvIQ0CFo= +github.com/hhrutter/lzw v1.0.0 h1:laL89Llp86W3rRs83LvKbwYRx6INE8gDn0XNb1oXtm0= +github.com/hhrutter/lzw v1.0.0/go.mod h1:2HC6DJSn/n6iAZfgM3Pg+cP1KxeWc3ezG8bBqW5+WEo= +github.com/hhrutter/tiff v1.0.1 h1:MIus8caHU5U6823gx7C6jrfoEvfSTGtEFRiM8/LOzC0= +github.com/hhrutter/tiff v1.0.1/go.mod h1:zU/dNgDm0cMIa8y8YwcYBeuEEveI4B0owqHyiPpJPHc= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= @@ -254,8 +253,8 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= -github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= +github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/mattn/go-sqlite3 v1.14.23 h1:gbShiuAP1W5j9UOksQ06aiiqPMxYecovVGwmTxWtuw0= github.com/mattn/go-sqlite3 v1.14.23/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= @@ -299,14 +298,16 @@ github.com/otiai10/copy v1.14.0/go.mod h1:ECfuL02W+/FkTWZWgQqXPWZgW9oeKCSQ5qVfSc github.com/otiai10/mint v1.5.1 h1:XaPLeE+9vGbuyEHem1JNk3bYc7KKqyI/na0/mLd/Kks= github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c h1:rp5dCmg/yLR3mgFuSOe4oEnDDmGLROTvMragMUXpTQw= github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c/go.mod h1:X07ZCGwUbLaax7L0S3Tw4hpejzu63ZrrQiUe6W0hcy0= -github.com/pdfcpu/pdfcpu v0.4.0 h1:381iGNvMeLP+GFqIAqgd0LSj36AsK3JH4UTaF6D5jRc= -github.com/pdfcpu/pdfcpu v0.4.0/go.mod h1:9NDeS6hrCheauxw6YUlzgL/q6At2+PMzUKyFcfUzLLY= +github.com/pdfcpu/pdfcpu v0.8.1 h1:AiWUb8uXlrXqJ73OmiYXBjDF0Qxt4OuM281eAfkAOMA= +github.com/pdfcpu/pdfcpu v0.8.1/go.mod h1:M5SFotxdaw0fedxthpjbA/PADytAo6wJnGH0SSBWJ7s= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/phuslu/log v1.0.80/go.mod h1:kzJN3LRifrepxThMjufQwS7S35yFAB+jAV1qgA7eBW4= github.com/phuslu/log v1.0.88 h1:kivXMpYQ2hd9BxiJNhRM5xnaEZaGunQYlnRQdk/aBw8= github.com/phuslu/log v1.0.88/go.mod h1:F8osGJADo5qLK/0F88djWwdyoZZ9xDJQL1HYRHFEkS0= +github.com/pkg/diff v0.0.0-20200914180035-5b29258ca4f7/go.mod h1:zO8QMzTeZd5cpnIkz/Gn6iK0jDfGicM1nynOkkPIl28= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -344,6 +345,7 @@ github.com/sealdice/dicescript v0.0.0-20240927083134-65269b7d051c h1:Z+H+yMma3Ic github.com/sealdice/dicescript v0.0.0-20240927083134-65269b7d051c/go.mod h1:uof752qJvEQ4Kze+NVag+RKGgj5C4K3kMHoK3e2vOLg= github.com/sealdice/kook v0.0.3 h1:STMtiKRMFjhSFmUxi0BU5ktNkCQ8qi7Y5EEfrmYKvWY= github.com/sealdice/kook v0.0.3/go.mod h1:WjHC7AmbmNjInT/U/etBVOmAw7T6EqdCwApceRGs1sk= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog= github.com/slack-go/slack v0.13.0 h1:7my/pR2ubZJ9912p9FtvALYpbt0cQPAqkRy2jaSI1PQ= @@ -363,6 +365,7 @@ github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpE github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -375,10 +378,13 @@ github.com/sunshineplan/imgconv v1.1.4 h1:lViOZUbDIgW8o74naySXJqZOFgXSW1AdU/cdzZ github.com/sunshineplan/imgconv v1.1.4/go.mod h1:Bc4qh4Z+nslcq+Csck01QZgzWvirKUdltRI7vnEAKd8= github.com/sunshineplan/pdf v1.0.3 h1:Ng+/f35i0jlB87STk6sXaINqhF0JsIyXLZntWWOcGhg= github.com/sunshineplan/pdf v1.0.3/go.mod h1:4JqkeywDS6kIsqODkNKZ847P2K8eRpSSzf12FTRmUVg= +github.com/sunshineplan/pdf v1.0.7 h1:62xlc079jh4tGLDjiihyyhwVFkn0IsxLyDpHplbG9Ew= +github.com/sunshineplan/pdf v1.0.7/go.mod h1:QsEmZCWBE3uFK8PCrM0pua1WDWLNU77YusiDEcY56OQ= github.com/sunshineplan/tiff v0.0.0-20220128141034-29b9d69bd906 h1:+yYRCj+PGQNnnen4+/Q7eKD2J87RJs+O39bjtHhPauk= github.com/sunshineplan/tiff v0.0.0-20220128141034-29b9d69bd906/go.mod h1:O+Ar7ouRbdfxLgoZLFz447/dvdM1NVKk1VpOQaijvAU= github.com/tadvi/systray v0.0.0-20190226123456-11a2b8fa57af h1:6yITBqGTE2lEeTPG04SN9W+iWHCRyHqlVYILiSXziwk= github.com/tadvi/systray v0.0.0-20190226123456-11a2b8fa57af/go.mod h1:4F09kP5F+am0jAwlQLddpoMDM+iewkxxt6nxUQ5nq5o= +github.com/tailscale/depaware v0.0.0-20210622194025-720c4b409502/go.mod h1:p9lPsd+cx33L3H9nNoecRRxPssFKUwwI50I3pZ0yT+8= github.com/tailscale/hujson v0.0.0-20221223112325-20486734a56a h1:SJy1Pu0eH1C29XwJucQo73FrleVK6t4kYz4NVhp34Yw= github.com/tailscale/hujson v0.0.0-20221223112325-20486734a56a/go.mod h1:DFSS3NAGHthKo1gTlmEcSBiZrRJXi28rLNd/1udP1c8= github.com/tdewolff/minify/v2 v2.20.37 h1:Q97cx4STXCh1dlWDlNHZniE8BJ2EBL0+2b0n92BJQhw= @@ -423,14 +429,21 @@ github.com/xuri/excelize/v2 v2.8.1/go.mod h1:oli1E4C3Pa5RXg1TBXn4ENCXDV5JUMlBluU github.com/xuri/nfp v0.0.0-20230919160717-d98342af3f05 h1:qhbILQo1K3mphbwKh1vNm4oGezE1eF9fQWmNiIpSfI4= github.com/xuri/nfp v0.0.0-20230919160717-d98342af3f05/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/goldmark v1.7.4 h1:BDXOHExt+A7gwPCJgPIIq7ENvceR7we7rOS9TNoLZeg= github.com/yuin/goldmark v1.7.4/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= go.etcd.io/bbolt v1.3.9 h1:8x7aARPEXiXbHmtUwAIv7eV2fQFHrLLavdiJ3uzJXoI= go.etcd.io/bbolt v1.3.9/go.mod h1:zaO32+Ti0PK1ivdPtgMESzuzL2VPoIG1PCQNvOdo/dE= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/atomic v1.8.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.20.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -446,9 +459,12 @@ golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt7 golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 h1:LoYXNGAShUG3m/ehNk4iFctuhGX/+R1ZpfJ4/ia80JM= golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.18.0 h1:jGzIakQa/ZXI1I0Fxvaa9W7yP25TqT6cHIHn+6CqvSQ= -golang.org/x/image v0.18.0/go.mod h1:4yyo5vMFQjVjUcVk4jEQcU9MGy/rulF5WvUILseCM2E= +golang.org/x/image v0.19.0 h1:D9FX4QWkLfkeqaC62SonffIIuYdOk/UE2XKUBgRIBIQ= +golang.org/x/image v0.19.0/go.mod h1:y0zrRqlQRWQ5PXaYCOMLTW2fpsxZ8Qh9I/ohnInJEys= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= @@ -472,6 +488,7 @@ golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= @@ -493,6 +510,7 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -531,9 +549,12 @@ golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190624180213-70d37148ca0c/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20201211185031-d93e913c1a58/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -570,10 +591,12 @@ gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24 gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= modernc.org/libc v1.37.6 h1:orZH3c5wmhIQFTXF+Nt+eeauyd+ZIt2BX6ARe+kD+aw= @@ -584,3 +607,5 @@ modernc.org/memory v1.7.2 h1:Klh90S215mmH8c9gO98QxQFsY+W451E8AnzjoE2ee1E= modernc.org/memory v1.7.2/go.mod h1:NO4NVCQy0N7ln+T9ngWqOQfi7ley4vpwvARR+Hjw95E= modernc.org/sqlite v1.28.0 h1:Zx+LyDDmXczNnEQdvPuEfcFVA2ZPyaD7UCZDjef3BHQ= modernc.org/sqlite v1.28.0/go.mod h1:Qxpazz0zH8Z1xCFyi5GSL3FzbtZ3fvbjmywNogldEW0= +moul.io/zapfilter v1.7.0 h1:7aFrG4N72bDH9a2BtYUuUaDS981Dxu3qybWfeqaeBDU= +moul.io/zapfilter v1.7.0/go.mod h1:M+N2s+qZiA+bzRoyKMVRxyuERijS2ovi2pnMyiOGMvc= diff --git a/logger.go b/logger.go deleted file mode 100644 index e882563c..00000000 --- a/logger.go +++ /dev/null @@ -1,51 +0,0 @@ -package main - -import ( - "os" - - "github.com/natefinch/lumberjack" - "go.uber.org/zap" - "go.uber.org/zap/zapcore" -) - -func MainLoggerInit(path string, enableConsoleLog bool) { - lumlog := &lumberjack.Logger{ - Filename: path, - MaxSize: 10, // megabytes - MaxBackups: 3, // number of log files - MaxAge: 7, // days - } - - encoder := getEncoder() - cores := []zapcore.Core{ - zapcore.NewCore(encoder, zapcore.AddSync(lumlog), zapcore.DebugLevel), - } - - if enableConsoleLog { - pe2 := zap.NewProductionEncoderConfig() - pe2.EncodeTime = zapcore.ISO8601TimeEncoder - - consoleEncoder := zapcore.NewConsoleEncoder(pe2) - cores = append(cores, zapcore.NewCore(consoleEncoder, zapcore.AddSync(os.Stdout), zapcore.InfoLevel)) - } - - core := zapcore.NewTee(cores...) - - loggerRaw := zap.New(core, zap.AddCaller()) - defer func(loggerRaw *zap.Logger) { - _ = loggerRaw.Sync() - }(loggerRaw) // flushes buffer, if any - - logger = loggerRaw.Sugar() - logger.Infow("核心日志开始记录") -} - -var logger *zap.SugaredLogger - -func getEncoder() zapcore.Encoder { - encoderConfig := zap.NewProductionEncoderConfig() - encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder - encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder - - return zapcore.NewConsoleEncoder(encoderConfig) -} diff --git a/main.go b/main.go index 932317a6..4e793662 100644 --- a/main.go +++ b/main.go @@ -20,16 +20,15 @@ import ( "github.com/jessevdk/go-flags" "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" - "go.uber.org/zap" "go.uber.org/zap/zapcore" "sealdice-core/api" "sealdice-core/dice" - diceLogger "sealdice-core/dice/logger" "sealdice-core/dice/model" "sealdice-core/migrate" "sealdice-core/static" "sealdice-core/utils/crypto" + log "sealdice-core/utils/kratos" ) /** @@ -43,11 +42,11 @@ extensions/ func cleanupCreate(diceManager *dice.DiceManager) func() { return func() { - logger.Info("程序即将退出,进行清理……") + log.Info("程序即将退出,进行清理……") err := recover() if err != nil { showWindow() - logger.Errorf("异常: %v\n堆栈: %v", err, string(debug.Stack())) + log.Errorf("异常: %v\n堆栈: %v", err, string(debug.Stack())) // 顺便修正一下上面这个,应该是木落忘了。 if runtime.GOOS == "windows" { exec.Command("pause") // windows专属 @@ -69,7 +68,7 @@ func cleanupCreate(diceManager *dice.DiceManager) func() { err := j.StorageClose() if err != nil { showWindow() - logger.Errorf("异常: %v\n堆栈: %v", err, string(debug.Stack())) + log.Errorf("异常: %v\n堆栈: %v", err, string(debug.Stack())) // 木落没有加该检查 补充上 if runtime.GOOS == "windows" { exec.Command("pause") // windows专属 @@ -219,7 +218,7 @@ func main() { deleteOldWrongFile() if opts.Delay != 0 { - fmt.Println("延迟启动", opts.Delay, "秒") + log.Infof("延迟启动 %d 秒", opts.Delay) time.Sleep(time.Duration(opts.Delay) * time.Second) } @@ -228,15 +227,15 @@ func main() { } _ = os.MkdirAll("./data", 0o755) - MainLoggerInit("./data/main.log", true) - diceLogger.SetEnableLevel(zapcore.Level(opts.LogLevel)) + // 初始化全局Kartos日志,由于DICE部分已经完全被砍掉了,所以原本的日志等级用来设置控制台展示的日志等级或许更合适 + log.InitZapWithKartosLog(zapcore.Level(opts.LogLevel)) // 提早初始化是为了读取ServiceName diceManager := &dice.DiceManager{} if opts.ContainerMode { - logger.Info("当前为容器模式,内置适配器与更新功能已被禁用") + log.Info("当前为容器模式,内置适配器与更新功能已被禁用") diceManager.ContainerMode = true } @@ -244,7 +243,7 @@ func main() { diceManager.IsReady = true if opts.Address != "" { - fmt.Println("由参数输入了服务地址:", opts.Address) + log.Infof("由参数输入了服务地址: %s", opts.Address) diceManager.ServeAddress = opts.Address } @@ -281,17 +280,17 @@ func main() { // 只有不同文件才进行校验 // windows平台旧版本到1.4.0流程 _ = os.WriteFile("./升级失败指引.txt", []byte("如果升级成功不用理会此文档,直接删除即可。\r\n\r\n如果升级后无法启动,或再次启动后恢复到旧版本,先不要紧张。\r\n你升级前的数据备份在backups目录。\r\n如果无法启动,请删除海豹目录中的\"update\"、\"auto_update.exe\"并手动进行升级。\n如果升级成功但在再次重启后回退版本,同上。\n\n如有其他问题可以加企鹅群询问:524364253 562897832"), 0o644) - logger.Warn("检测到 auto_update.exe,即将自动退出当前程序并进行升级") - logger.Warn("程序目录下会出现“升级日志.log”,这代表升级正在进行中,如果失败了请检查此文件。") + log.Warn("检测到 auto_update.exe,即将自动退出当前程序并进行升级") + log.Warn("程序目录下会出现“升级日志.log”,这代表升级正在进行中,如果失败了请检查此文件。") err := CheckUpdater(diceManager) if err != nil { - logger.Error("升级程序检查失败: ", err.Error()) + log.Error("升级程序检查失败: ", err.Error()) } else { _ = os.Remove("./auto_update.exe") // ui资源已经内置,删除旧的ui文件,这里有点风险,但是此时已经不考虑升级失败的情况 _ = os.RemoveAll("./frontend") - UpdateByFile(diceManager, nil, "./update/update.zip", true) + UpdateByFile(diceManager, "./update/update.zip", true) } return } @@ -308,12 +307,12 @@ func main() { if doNext { err := CheckUpdater(diceManager) if err != nil { - logger.Error("升级程序检查失败: ", err.Error()) + log.Error("升级程序检查失败: ", err.Error()) } else { _ = os.Remove("./auto_update") // ui资源已经内置,删除旧的ui文件,这里有点风险,但是此时已经不考虑升级失败的情况 _ = os.RemoveAll("./frontend") - UpdateByFile(diceManager, nil, "./update/update.tar.gz", true) + UpdateByFile(diceManager, "./update/update.tar.gz", true) } return } @@ -323,26 +322,25 @@ func main() { if opts.UpdateTest { err := CheckUpdater(diceManager) if err != nil { - logger.Error("升级程序检查失败: ", err.Error()) + log.Error("升级程序检查失败: ", err.Error()) } else { - UpdateByFile(diceManager, nil, "./xx.zip", true) + UpdateByFile(diceManager, "./xx.zip", true) } } // 先临时放这里,后面再整理一下升级模块 - diceManager.UpdateSealdiceByFile = func(packName string, log *zap.SugaredLogger) bool { + diceManager.UpdateSealdiceByFile = func(packName string, log *log.Helper) bool { err := CheckUpdater(diceManager) if err != nil { - logger.Error("升级程序检查失败: ", err.Error()) + log.Error("升级程序检查失败: ", err.Error()) return false } else { - return UpdateByFile(diceManager, log, packName, false) + return UpdateByFile(diceManager, packName, false) } } cwd, _ := os.Getwd() - fmt.Printf("%s %s\n", dice.APPNAME, dice.VERSION.String()) - fmt.Println("工作路径: ", cwd) + log.Info(dice.APPNAME, dice.VERSION.String(), "当前工作路径: ", cwd) if strings.HasPrefix(cwd, os.TempDir()) { // C:\Users\XXX\AppData\Local\Temp @@ -357,15 +355,15 @@ func main() { return err == nil && stat.IsDir() } if !checkFrontendExists() { - logger.Info("未检测到外置的UI资源文件,将使用内置资源启动UI") + log.Info("未检测到外置的UI资源文件,将使用内置资源启动UI") useBuiltinUI = true } else { - logger.Info("检测到外置的UI资源文件,将使用frontend_overwrite文件夹内的资源启动UI") + log.Info("检测到外置的UI资源文件,将使用frontend_overwrite文件夹内的资源启动UI") } // 删除遗留的shm和wal文件 if !model.DBCacheDelete() { - logger.Error("数据库缓存文件删除失败") + log.Error("数据库缓存文件删除失败") showMsgBox("数据库缓存文件删除失败", "为避免数据损坏,拒绝继续启动。请检查是否启动多份程序,或有其他程序正在使用数据库文件!") return } @@ -374,22 +372,22 @@ func main() { migrate.TryMigrateToV12() // 尝试修正log_items表的message字段类型 if migrateErr := migrate.LogItemFixDatatype(); migrateErr != nil { - logger.Errorf("修正log_items表时出错,%s", migrateErr.Error()) + log.Fatalf("修正log_items表时出错,%s", migrateErr.Error()) return } // v131迁移历史设置项到自定义文案 if migrateErr := migrate.V131DeprecatedConfig2CustomText(); migrateErr != nil { - logger.Errorf("迁移历史设置项时出错,%s", migrateErr.Error()) + log.Fatalf("迁移历史设置项时出错,%s", migrateErr.Error()) return } // v141重命名刷屏警告字段 if migrateErr := migrate.V141DeprecatedConfigRename(); migrateErr != nil { - logger.Errorf("迁移历史设置项时出错,%s", migrateErr.Error()) + log.Fatalf("迁移历史设置项时出错,%s", migrateErr.Error()) return } // v144删除旧的帮助文档 if migrateErr := migrate.V144RemoveOldHelpdoc(); migrateErr != nil { - logger.Errorf("移除旧帮助文档时出错,%v", migrateErr) + log.Fatalf("移除旧帮助文档时出错,%v", migrateErr) } // v150升级 if !migrate.V150Upgrade() { @@ -437,7 +435,7 @@ func main() { })() if opts.Address != "" { - fmt.Println("由参数输入了服务地址:", opts.Address) + log.Infof("由参数输入了服务地址: %s", opts.Address) } for _, d := range diceManager.Dice { @@ -475,7 +473,7 @@ func removeUpdateFiles() { func diceServe(d *dice.Dice) { defer dice.CrashLog() if len(d.ImSession.EndPoints) == 0 { - d.Logger.Infof("未检测到任何帐号,请先到“帐号设置”进行添加") + log.Infof("未检测到任何帐号,请先到“帐号设置”进行添加") } d.UIEndpoint = new(dice.EndPointInfo) @@ -558,13 +556,13 @@ func diceServe(d *dice.Dice) { } func uiServe(dm *dice.DiceManager, hideUI bool, useBuiltin bool) { - logger.Info("即将启动webui") + log.Info("即将启动webui") // Echo instance e := echo.New() - // Middleware - // e.Use(middleware.Logger()) - // e.Use(middleware.Recover()) + // 为UI添加日志,以echo方式输出 + echoHelper := log.GetWebLogger() + e.Use(log.EchoMiddleLogger(echoHelper)) e.Use(middleware.CORSWithConfig(middleware.CORSConfig{ Skipper: middleware.DefaultSkipper, AllowHeaders: []string{echo.HeaderOrigin, echo.HeaderContentType, echo.HeaderAccept, "token"}, diff --git a/migrate/convert_logs.go b/migrate/convert_logs.go index 4216f0d3..b099e6bf 100644 --- a/migrate/convert_logs.go +++ b/migrate/convert_logs.go @@ -4,7 +4,6 @@ import ( "encoding/binary" "encoding/json" "errors" - "fmt" "path/filepath" "strconv" "strings" @@ -12,6 +11,8 @@ import ( "github.com/jmoiron/sqlx" "go.etcd.io/bbolt" + + log "sealdice-core/utils/kratos" ) type LogOneItem struct { @@ -212,7 +213,7 @@ func LogAppend(ctx *MsgContext, group *GroupInfo, l *LogOneItem) error { return ctx.Dice.DB.Update(func(tx *bbolt.Tx) error { _, err := tx.CreateBucketIfNotExists([]byte("logs")) if err != nil { - // ctx.Dice.Logger.Error("日志写入问题", err.Error()) + // ctx.Dice.Zlogger.Error("日志写入问题", err.Error()) return err } @@ -353,7 +354,6 @@ create index if not exists idx_log_items_log_id dbSQL, err := openDB(dbDataLogsPath) if err != nil { - fmt.Println("xxx", err) return err } defer func(dbSql *sqlx.DB) { @@ -380,7 +380,7 @@ create index if not exists idx_log_items_log_id }) }) - fmt.Println("群组数量", len(groupIds)) + log.Info("群组数量", len(groupIds)) times := 0 itemNumber := 0 @@ -409,14 +409,14 @@ create index if not exists idx_log_items_log_id } exec, errExec := dbSQL.NamedExec(`insert into logs (name, group_id, created_at, updated_at) VALUES (:name, :group_id, :created_at, :updated_at)`, args) if errExec != nil { - fmt.Println("错误:", errExec, i, j) + log.Error("错误:", errExec, i, j) return errExec } logID, _ := exec.LastInsertId() logNum++ if logNum%10 == 0 { - fmt.Printf("进度: %d\n", logNum) + log.Infof("进度: %d\n", logNum) } tx := dbSQL.MustBegin() @@ -450,15 +450,15 @@ create index if not exists idx_log_items_log_id } } - fmt.Println("群组数量", len(groupIds)) - fmt.Println("log完成", times) - fmt.Println("行数", itemNumber) + log.Info("群组数量", len(groupIds)) + log.Info("log完成", times) + log.Info("行数", itemNumber) err = dbSQL.Get(&num, "select count(id) from log_items") if err != nil { return err } - fmt.Println("行数确认", num) + log.Info("行数确认", num) _ = dbSQL.Close() return nil diff --git a/tray_darwin.go b/tray_darwin.go index e6901875..7e06ee73 100644 --- a/tray_darwin.go +++ b/tray_darwin.go @@ -4,7 +4,6 @@ package main import ( - "fmt" "net" "os" "os/exec" @@ -20,6 +19,7 @@ import ( "sealdice-core/dice" "sealdice-core/icon" + log "sealdice-core/utils/kratos" ) var theDm *dice.DiceManager @@ -41,11 +41,11 @@ func TestRunning() bool { } func tempDirWarn() { - fmt.Println("当前工作路径为临时目录,因此拒绝继续执行。") + log.Info("当前工作路径为临时目录,因此拒绝继续执行。") } func showMsgBox(title string, message string) { - fmt.Println(title, message) + log.Info(title, message) } func executeWin(name string, arg ...string) *exec.Cmd { @@ -121,17 +121,16 @@ func httpServe(e *echo.Echo, dm *dice.DiceManager, hideUI bool) { ln, err := net.Listen("tcp", ":"+portStr) if err != nil { - logger.Errorf("端口已被占用,即将自动退出: %s", dm.ServeAddress) + log.Errorf("端口已被占用,即将自动退出: %s", dm.ServeAddress) runtime.Goexit() } _ = ln.Close() // exec.Command(`cmd`, `/c`, `start`, fmt.Sprintf(`http://localhost:%s`, portStr)).Start() - fmt.Println("如果浏览器没有自动打开,请手动访问:") - fmt.Printf(`http://localhost:%s`, portStr) // 默认:3211 + log.Infof("如果浏览器没有自动打开,请手动访问:\nhttp://localhost:%s", portStr) err = e.Start(dm.ServeAddress) if err != nil { - logger.Errorf("端口已被占用,即将自动退出: %s", dm.ServeAddress) + log.Errorf("端口已被占用,即将自动退出: %s", dm.ServeAddress) return } } diff --git a/tray_others.go b/tray_others.go index 75bb354a..e535b080 100644 --- a/tray_others.go +++ b/tray_others.go @@ -4,7 +4,6 @@ package main import ( - "fmt" "net" "os" "os/exec" @@ -15,6 +14,7 @@ import ( "github.com/labstack/echo/v4" "sealdice-core/dice" + log "sealdice-core/utils/kratos" ) func trayInit(dm *dice.DiceManager) { @@ -32,11 +32,11 @@ func TestRunning() bool { } func tempDirWarn() { - fmt.Println("当前工作路径为临时目录,因此拒绝继续执行。") + log.Warn("当前工作路径为临时目录,因此拒绝继续执行。") } func showMsgBox(title string, message string) { - fmt.Println(title, message) + log.Info(title, message) } func httpServe(e *echo.Echo, dm *dice.DiceManager, hideUI bool) { @@ -49,16 +49,15 @@ func httpServe(e *echo.Echo, dm *dice.DiceManager, hideUI bool) { ln, err := net.Listen("tcp", ":"+portStr) if err != nil { - logger.Errorf("端口已被占用,即将自动退出: %s", dm.ServeAddress) + log.Errorf("端口已被占用,即将自动退出: %s", dm.ServeAddress) runtime.Goexit() } _ = ln.Close() - fmt.Println("如果浏览器没有自动打开,请手动访问:") - fmt.Printf(`http://localhost:%s`, portStr) // 默认:3211 + log.Infof("如果浏览器没有自动打开,请手动访问:\nhttp://localhost:%s", portStr) err = e.Start(dm.ServeAddress) if err != nil { - logger.Errorf("端口已被占用,即将自动退出: %s", dm.ServeAddress) + log.Errorf("端口已被占用,即将自动退出: %s", dm.ServeAddress) return } } diff --git a/tray_windows.go b/tray_windows.go index 11c482f1..d234ea5a 100644 --- a/tray_windows.go +++ b/tray_windows.go @@ -25,6 +25,7 @@ import ( "sealdice-core/dice" "sealdice-core/icon" + log "sealdice-core/utils/kratos" ) func hideWindow() { @@ -154,7 +155,7 @@ func onReady() { s1, _ := syscall.UTF16PtrFromString("SealDice 临时目录错误") s2, _ := syscall.UTF16PtrFromString("自启动失败设置失败,原因: " + err.Error()) win.MessageBox(0, s2, s1, win.MB_OK|win.MB_ICONERROR) - fmt.Println("自启动设置失败: ", err.Error()) + log.Errorf("自启动设置失败: %v", err.Error()) } mAutoBoot.Uncheck() } else { @@ -163,7 +164,7 @@ func onReady() { s1, _ := syscall.UTF16PtrFromString("SealDice 临时目录错误") s2, _ := syscall.UTF16PtrFromString("自启动失败设置失败,原因: " + err.Error()) win.MessageBox(0, s2, s1, win.MB_OK|win.MB_ICONERROR) - fmt.Println("自启动设置失败: ", err.Error()) + log.Errorf("自启动设置失败: %v", err.Error()) } mAutoBoot.Check() } @@ -239,12 +240,11 @@ func httpServe(e *echo.Echo, dm *dice.DiceManager, hideUI bool) { dm.ServeAddress = fmt.Sprintf("0.0.0.0:%d", newPort) continue } else { - logger.Errorf("端口已被占用,即将自动退出: %s", dm.ServeAddress) + log.Errorf("端口已被占用,即将自动退出: %s", dm.ServeAddress) os.Exit(0) } } else { - fmt.Println("如果浏览器没有自动打开,请手动访问:") - fmt.Printf("http://localhost:%s\n", portStr) // 默认:3211 + log.Info("如果浏览器没有自动打开,请手动访问:\nhttp://localhost:%s\n", portStr) go showUI() break } @@ -255,7 +255,7 @@ func tempDirWarn() { s1, _ := syscall.UTF16PtrFromString("SealDice 临时目录错误") s2, _ := syscall.UTF16PtrFromString("你正在临时文件目录运行海豹,最可能的情况是没有解压而是直接双击运行!\n请先完整解压后再进行运行操作!\n按确定后将自动退出") win.MessageBox(0, s2, s1, win.MB_OK|win.MB_ICONERROR) - fmt.Println("当前工作路径为临时目录,因此拒绝继续执行。") + log.Error("当前工作路径为临时目录,因此拒绝继续执行。") } func showMsgBox(title string, message string) { diff --git a/update.go b/update.go index 56eea8c6..83ae2379 100644 --- a/update.go +++ b/update.go @@ -14,15 +14,14 @@ import ( "syscall" "time" - "go.uber.org/zap" - "sealdice-core/dice" "sealdice-core/utils" + log "sealdice-core/utils/kratos" ) var binPrefix = "https://sealdice.coding.net/p/sealdice/d/sealdice-binaries/git/raw/master" -func downloadUpdate(dm *dice.DiceManager, log *zap.SugaredLogger) (string, error) { +func downloadUpdate(dm *dice.DiceManager, log *log.Helper) (string, error) { var packFn string if dm.AppVersionOnline != nil { ver := dm.AppVersionOnline @@ -112,7 +111,7 @@ func doReboot(dm *dice.DiceManager) { binary, err := exec.LookPath(executablePath) if err != nil { - logger.Errorf("Restart Error: %s", err) + log.Errorf("Restart Error: %s", err) return } platform := runtime.GOOS @@ -124,7 +123,7 @@ func doReboot(dm *dice.DiceManager) { cmd := executeWin(binary, "--delay=15") err := cmd.Start() if err != nil { - logger.Errorf("Restart error: %s %v", binary, err) + log.Errorf("Restart error: %s %v", binary, err) } } else { // 手动cleanup @@ -132,7 +131,7 @@ func doReboot(dm *dice.DiceManager) { // os.Args[1:]... execErr := syscall.Exec(binary, []string{os.Args[0], "--delay=25"}, os.Environ()) if execErr != nil { - logger.Errorf("Restart error: %s %v", binary, execErr) + log.Errorf("Restart error: %s %v", binary, execErr) } } os.Exit(0) diff --git a/update_updater.go b/update_updater.go index fcaa5148..46096f35 100644 --- a/update_updater.go +++ b/update_updater.go @@ -13,10 +13,9 @@ import ( "syscall" "time" - "go.uber.org/zap" - "sealdice-core/dice" "sealdice-core/utils" + log "sealdice-core/utils/kratos" ) const updaterVersion = "0.1.1" @@ -73,7 +72,7 @@ func CheckUpdater(dm *dice.DiceManager) error { exists := false fn := getUpdaterFn() if _, err := os.Stat(fn); err == nil { - logger.Info("检测到海豹更新程序") + log.Info("检测到海豹更新程序") exists = true } @@ -82,15 +81,15 @@ func CheckUpdater(dm *dice.DiceManager) error { if exists { err := os.Chmod(fn, 0o755) if err != nil { - logger.Error("设置升级程序执行权限失败", err.Error()) + log.Error("设置升级程序执行权限失败", err.Error()) } cmd := exec.Command(fn, "--version") out, err := cmd.Output() if err != nil { - logger.Error("获取升级程序版本失败") + log.Error("获取升级程序版本失败") } else { ver := strings.TrimSpace(string(out)) - logger.Info("升级程序版本:", ver) + log.Info("升级程序版本:", ver) if ver == "seal-updater "+updaterVersion { isUpdaterOk = true } @@ -99,16 +98,16 @@ func CheckUpdater(dm *dice.DiceManager) error { // 如果升级程序不可用,那么下载一个 if !isUpdaterOk { - logger.Info("未检测到可用更新程序,开始下载") + log.Info("未检测到可用更新程序,开始下载") err := downloadUpdater(dm) if err != nil { - logger.Error("下载更新程序失败") + log.Error("下载更新程序失败") return errors.New("下载更新程序失败,无可用更新程序") } else { - logger.Info("下载更新程序成功") + log.Info("下载更新程序成功") err := os.Chmod(fn, 0o755) if err != nil { - logger.Error("设置升级程序执行权限失败", err.Error()) + log.Error("设置升级程序执行权限失败", err.Error()) } } } @@ -145,11 +144,8 @@ func downloadUpdater(dm *dice.DiceManager) error { return nil } -func UpdateByFile(dm *dice.DiceManager, log *zap.SugaredLogger, packName string, syncMode bool) bool { +func UpdateByFile(dm *dice.DiceManager, packName string, syncMode bool) bool { // 注意: 当执行完就立即退进程的情况下,需要使用 syncMode 为true - if log == nil { - log = logger - } fn := getUpdaterFn() err := os.Chmod(fn, 0o755) if err != nil { diff --git a/utils/kratos/const.go b/utils/kratos/const.go new file mode 100644 index 00000000..245435fc --- /dev/null +++ b/utils/kratos/const.go @@ -0,0 +1,9 @@ +package log + +const ( + LOG_SEAL = "SEAL" + LOG_DICE = "DICE" + LOG_WEB = "WEB" + LOG_LAGR = "LAGR" + LOG_HIDE = "HIDE" +) diff --git a/utils/kratos/echologger.go b/utils/kratos/echologger.go new file mode 100644 index 00000000..aa8a95a3 --- /dev/null +++ b/utils/kratos/echologger.go @@ -0,0 +1,52 @@ +// Package middleware provides echo request and response output log +package log + +import ( + "strconv" + "time" + + "github.com/labstack/echo/v4" +) + +// Zlogger returns a middleware that logs HTTP requests. +func EchoMiddleLogger(elogger *Helper) echo.MiddlewareFunc { + return func(next echo.HandlerFunc) echo.HandlerFunc { + return func(c echo.Context) error { + req := c.Request() + res := c.Response() + start := time.Now() + + var err error + if err = next(c); err != nil { + c.Error(err) + } + stop := time.Now() + + id := req.Header.Get(echo.HeaderXRequestID) + if id == "" { + id = res.Header().Get(echo.HeaderXRequestID) + } + reqSize := req.Header.Get(echo.HeaderContentLength) + if reqSize == "" { + reqSize = "0" + } + + // 特殊情况下,需要输出DEBUG日志 + elogger.Debugf("%s %s [%v] %s %-7s %s %3d %s %s %13v %s %s", + id, + c.RealIP(), + stop.Format(time.RFC3339), + req.Host, + req.Method, + req.RequestURI, + res.Status, + reqSize, + strconv.FormatInt(res.Size, 10), + stop.Sub(start).String(), + req.Referer(), + req.UserAgent(), + ) + return err + } + } +} diff --git a/utils/kratos/filter.go b/utils/kratos/filter.go new file mode 100644 index 00000000..7380d3dd --- /dev/null +++ b/utils/kratos/filter.go @@ -0,0 +1,95 @@ +// copied from https://github.com/go-kratos/kratos/tree/main/log +package log + +// FilterOption is filter option. +type FilterOption func(*Filter) + +const fuzzyStr = "***" + +// FilterLevel with filter level. +func FilterLevel(level Level) FilterOption { + return func(opts *Filter) { + opts.level = level + } +} + +// FilterKey with filter key. +func FilterKey(key ...string) FilterOption { + return func(o *Filter) { + for _, v := range key { + o.key[v] = struct{}{} + } + } +} + +// FilterValue with filter value. +func FilterValue(value ...string) FilterOption { + return func(o *Filter) { + for _, v := range value { + o.value[v] = struct{}{} + } + } +} + +// FilterFunc with filter func. +func FilterFunc(f func(level Level, keyvals ...interface{}) bool) FilterOption { + return func(o *Filter) { + o.filter = f + } +} + +// Filter is a logger filter. +type Filter struct { + logger Logger + level Level + key map[interface{}]struct{} + value map[interface{}]struct{} + filter func(level Level, keyvals ...interface{}) bool +} + +// NewFilter new a logger filter. +func NewFilter(logger Logger, opts ...FilterOption) *Filter { + options := Filter{ + logger: logger, + key: make(map[interface{}]struct{}), + value: make(map[interface{}]struct{}), + } + for _, o := range opts { + o(&options) + } + return &options +} + +// Log Print log by level and keyvals. +func (f *Filter) Log(level Level, keyvals ...interface{}) error { + if level < f.level { + return nil + } + // prefixkv contains the slice of arguments defined as prefixes during the log initialization + var prefixkv []interface{} + l, ok := f.logger.(*logger) + if ok && len(l.prefix) > 0 { + prefixkv = make([]interface{}, 0, len(l.prefix)) + prefixkv = append(prefixkv, l.prefix...) + } + + if f.filter != nil && (f.filter(level, prefixkv...) || f.filter(level, keyvals...)) { + return nil + } + + if len(f.key) > 0 || len(f.value) > 0 { + for i := 0; i < len(keyvals); i += 2 { + v := i + 1 + if v >= len(keyvals) { + continue + } + if _, ok := f.key[keyvals[i]]; ok { + keyvals[v] = fuzzyStr + } + if _, ok := f.value[keyvals[v]]; ok { + keyvals[v] = fuzzyStr + } + } + } + return f.logger.Log(level, keyvals...) +} diff --git a/utils/kratos/global.go b/utils/kratos/global.go new file mode 100644 index 00000000..cb9446cb --- /dev/null +++ b/utils/kratos/global.go @@ -0,0 +1,134 @@ +// copied from https://github.com/go-kratos/kratos/tree/main/log +package log + +import ( + "context" + "fmt" + "os" + "sync" +) + +// globalLogger is designed as a global logger in current process. +var global = &loggerAppliance{} + +// loggerAppliance is the proxy of `Zlogger` to +// make logger change will affect all sub-logger. +type loggerAppliance struct { + lock sync.Mutex + wx *WriterX + logger Logger +} + +// 似乎不建议使用init(),我自己手动管理吧 +// func init() { +// global.SetLogger(DefaultLogger) +// } + +func (a *loggerAppliance) SetLogger(in Logger) { + a.lock.Lock() + defer a.lock.Unlock() + a.logger = in +} + +// SetLogger should be called before any other log call. +// And it is NOT THREAD SAFE. +func SetLogger(logger Logger) { + global.SetLogger(logger) +} + +// GetLogger returns global logger appliance as logger in current process. +func GetLogger() Logger { + return global.logger +} + +// Log Print log by level and keyvals. +func Log(level Level, keyvals ...interface{}) { + _ = global.logger.Log(level, keyvals...) +} + +// Context with context logger. +func Context(ctx context.Context) *Helper { + return NewHelper(WithContext(ctx, global.logger)) +} + +// Debug logs a message at debug level. +func Debug(a ...interface{}) { + _ = global.logger.Log(LevelDebug, DefaultMessageKey, fmt.Sprint(a...)) +} + +// Debugf logs a message at debug level. +func Debugf(format string, a ...interface{}) { + _ = global.logger.Log(LevelDebug, DefaultMessageKey, fmt.Sprintf(format, a...)) +} + +// Debugw logs a message at debug level. +func Debugw(keyvals ...interface{}) { + _ = global.logger.Log(LevelDebug, keyvals...) +} + +// Info logs a message at info level. +func Info(a ...interface{}) { + _ = global.logger.Log(LevelInfo, DefaultMessageKey, fmt.Sprint(a...)) +} + +// Infof logs a message at info level. +func Infof(format string, a ...interface{}) { + _ = global.logger.Log(LevelInfo, DefaultMessageKey, fmt.Sprintf(format, a...)) +} + +// Infow logs a message at info level. +func Infow(keyvals ...interface{}) { + _ = global.logger.Log(LevelInfo, keyvals...) +} + +// Warn logs a message at warn level. +func Warn(a ...interface{}) { + _ = global.logger.Log(LevelWarn, DefaultMessageKey, fmt.Sprint(a...)) +} + +// Warnf logs a message at warnf level. +func Warnf(format string, a ...interface{}) { + _ = global.logger.Log(LevelWarn, DefaultMessageKey, fmt.Sprintf(format, a...)) +} + +// Warnw logs a message at warnf level. +func Warnw(keyvals ...interface{}) { + _ = global.logger.Log(LevelWarn, keyvals...) +} + +// Error logs a message at error level. +func Error(a ...interface{}) { + _ = global.logger.Log(LevelError, DefaultMessageKey, fmt.Sprint(a...)) +} + +// Errorf logs a message at error level. +func Errorf(format string, a ...interface{}) { + _ = global.logger.Log(LevelError, DefaultMessageKey, fmt.Sprintf(format, a...)) +} + +// Errorw logs a message at error level. +func Errorw(keyvals ...interface{}) { + _ = global.logger.Log(LevelError, keyvals...) +} + +// Fatal logs a message at fatal level. +func Fatal(a ...interface{}) { + _ = global.logger.Log(LevelFatal, DefaultMessageKey, fmt.Sprint(a...)) + os.Exit(1) +} + +// Fatalf logs a message at fatal level. +func Fatalf(format string, a ...interface{}) { + _ = global.logger.Log(LevelFatal, DefaultMessageKey, fmt.Sprintf(format, a...)) + os.Exit(1) +} + +// Fatalw logs a message at fatal level. +func Fatalw(keyvals ...interface{}) { + _ = global.logger.Log(LevelFatal, keyvals...) + os.Exit(1) +} + +func GetWriterX() *WriterX { + return global.wx +} diff --git a/utils/kratos/helper.go b/utils/kratos/helper.go new file mode 100644 index 00000000..9ccb5f8a --- /dev/null +++ b/utils/kratos/helper.go @@ -0,0 +1,181 @@ +// copied from https://github.com/go-kratos/kratos/tree/main/log +package log + +import ( + "context" + "fmt" + "os" + + "go.uber.org/zap" +) + +// DefaultMessageKey default message key. +var DefaultMessageKey = "msg" + +// Option is Helper option. +type Option func(*Helper) + +// Helper is a logger helper. +type Helper struct { + logger Logger + msgKey string + sprint func(...interface{}) string + sprintf func(format string, a ...interface{}) string +} + +// WithMessageKey with message key. +func WithMessageKey(k string) Option { + return func(opts *Helper) { + opts.msgKey = k + } +} + +// WithSprint with sprint +func WithSprint(sprint func(...interface{}) string) Option { + return func(opts *Helper) { + opts.sprint = sprint + } +} + +// WithSprintf with sprintf +func WithSprintf(sprintf func(format string, a ...interface{}) string) Option { + return func(opts *Helper) { + opts.sprintf = sprintf + } +} + +// NewHelper new a logger helper. +func NewHelper(logger Logger, opts ...Option) *Helper { + options := &Helper{ + msgKey: DefaultMessageKey, // default message key + logger: logger, + sprint: fmt.Sprint, + sprintf: fmt.Sprintf, + } + for _, o := range opts { + o(options) + } + return options +} + +// ADD 获取自定义Helper +func NewCustomHelper(loggerName string, hideConsole bool, sprintfFunc func(format string, a ...interface{}) string, withOptions ...zap.Option) *Helper { + // 获取原始zap logger + // 根据传入的Named名称和Option配置创建zap logger + var zapLogger Logger + originZapLogger = GetLoggerRaw() + if hideConsole { + // 添加HIDE的不会被输出到控制台,但会被输出到文件,或者其他位置。 + originZapLogger = originZapLogger.Named("HIDE") + } + if len(withOptions) > 0 { + // 如果有传入Options,使用WithOptions + originZapLogger = originZapLogger.Named(loggerName).WithOptions(withOptions...) + } else { + originZapLogger = originZapLogger.Named(loggerName) + } + zapLogger = NewZapLogger(originZapLogger) + // 如果 sprintfFunc 为 nil,则不使用 WithSprintf,直接使用 NewHelper + var helper *Helper + if sprintfFunc != nil { + helper = NewHelper(zapLogger, WithSprintf(sprintfFunc)) + } else { + helper = NewHelper(zapLogger) // 使用默认的 Helper + } + + return helper +} + +// WithContext returns a shallow copy of h with its context changed +// to ctx. The provided ctx must be non-nil. +func (h *Helper) WithContext(ctx context.Context) *Helper { + return &Helper{ + msgKey: h.msgKey, + logger: WithContext(ctx, h.logger), + sprint: h.sprint, + sprintf: h.sprintf, + } +} + +// Log Print log by level and keyvals. +func (h *Helper) Log(level Level, keyvals ...interface{}) { + _ = h.logger.Log(level, keyvals...) +} + +// Debug logs a message at debug level. +func (h *Helper) Debug(a ...interface{}) { + _ = h.logger.Log(LevelDebug, h.msgKey, h.sprint(a...)) +} + +// Debugf logs a message at debug level. +func (h *Helper) Debugf(format string, a ...interface{}) { + _ = h.logger.Log(LevelDebug, h.msgKey, h.sprintf(format, a...)) +} + +// Debugw logs a message at debug level. +func (h *Helper) Debugw(keyvals ...interface{}) { + _ = h.logger.Log(LevelDebug, keyvals...) +} + +// Info logs a message at info level. +func (h *Helper) Info(a ...interface{}) { + _ = h.logger.Log(LevelInfo, h.msgKey, h.sprint(a...)) +} + +// Infof logs a message at info level. +func (h *Helper) Infof(format string, a ...interface{}) { + _ = h.logger.Log(LevelInfo, h.msgKey, h.sprintf(format, a...)) +} + +// Infow logs a message at info level. +func (h *Helper) Infow(keyvals ...interface{}) { + _ = h.logger.Log(LevelInfo, keyvals...) +} + +// Warn logs a message at warn level. +func (h *Helper) Warn(a ...interface{}) { + _ = h.logger.Log(LevelWarn, h.msgKey, h.sprint(a...)) +} + +// Warnf logs a message at warnf level. +func (h *Helper) Warnf(format string, a ...interface{}) { + _ = h.logger.Log(LevelWarn, h.msgKey, h.sprintf(format, a...)) +} + +// Warnw logs a message at warnf level. +func (h *Helper) Warnw(keyvals ...interface{}) { + _ = h.logger.Log(LevelWarn, keyvals...) +} + +// Error logs a message at error level. +func (h *Helper) Error(a ...interface{}) { + _ = h.logger.Log(LevelError, h.msgKey, h.sprint(a...)) +} + +// Errorf logs a message at error level. +func (h *Helper) Errorf(format string, a ...interface{}) { + _ = h.logger.Log(LevelError, h.msgKey, h.sprintf(format, a...)) +} + +// Errorw logs a message at error level. +func (h *Helper) Errorw(keyvals ...interface{}) { + _ = h.logger.Log(LevelError, keyvals...) +} + +// Fatal logs a message at fatal level. +func (h *Helper) Fatal(a ...interface{}) { + _ = h.logger.Log(LevelFatal, h.msgKey, h.sprint(a...)) + os.Exit(1) +} + +// Fatalf logs a message at fatal level. +func (h *Helper) Fatalf(format string, a ...interface{}) { + _ = h.logger.Log(LevelFatal, h.msgKey, h.sprintf(format, a...)) + os.Exit(1) +} + +// Fatalw logs a message at fatal level. +func (h *Helper) Fatalw(keyvals ...interface{}) { + _ = h.logger.Log(LevelFatal, keyvals...) + os.Exit(1) +} diff --git a/utils/kratos/level.go b/utils/kratos/level.go new file mode 100644 index 00000000..d4279247 --- /dev/null +++ b/utils/kratos/level.go @@ -0,0 +1,61 @@ +// copied from https://github.com/go-kratos/kratos/tree/main/log +package log + +import "strings" + +// Level is a logger level. +type Level int8 + +// LevelKey is logger level key. +const LevelKey = "level" + +const ( + // LevelDebug is logger debug level. + LevelDebug Level = iota - 1 + // LevelInfo is logger info level. + LevelInfo + // LevelWarn is logger warn level. + LevelWarn + // LevelError is logger error level. + LevelError + // LevelFatal is logger fatal level + LevelFatal +) + +func (l Level) Key() string { + return LevelKey +} + +func (l Level) String() string { + switch l { + case LevelDebug: + return "DEBUG" + case LevelInfo: + return "INFO" + case LevelWarn: + return "WARN" + case LevelError: + return "ERROR" + case LevelFatal: + return "FATAL" + default: + return "" + } +} + +// ParseLevel parses a level string into a logger Level value. +func ParseLevel(s string) Level { + switch strings.ToUpper(s) { + case "DEBUG": + return LevelDebug + case "INFO": + return LevelInfo + case "WARN": + return LevelWarn + case "ERROR": + return LevelError + case "FATAL": + return LevelFatal + } + return LevelInfo +} diff --git a/utils/kratos/log.go b/utils/kratos/log.go new file mode 100644 index 00000000..2114ee7f --- /dev/null +++ b/utils/kratos/log.go @@ -0,0 +1,62 @@ +// copied from https://github.com/go-kratos/kratos/tree/main/log +package log + +import ( + "context" +) + +// Zlogger is a logger interface. +type Logger interface { + Log(level Level, keyvals ...interface{}) error +} + +type logger struct { + logger Logger + prefix []interface{} + hasValuer bool + ctx context.Context +} + +func (c *logger) Log(level Level, keyvals ...interface{}) error { + kvs := make([]interface{}, 0, len(c.prefix)+len(keyvals)) + kvs = append(kvs, c.prefix...) + if c.hasValuer { + bindValues(c.ctx, kvs) + } + kvs = append(kvs, keyvals...) + return c.logger.Log(level, kvs...) +} + +// With with logger fields. +func With(l Logger, kv ...interface{}) Logger { + c, ok := l.(*logger) + if !ok { + return &logger{logger: l, prefix: kv, hasValuer: containsValuer(kv), ctx: context.Background()} + } + kvs := make([]interface{}, 0, len(c.prefix)+len(kv)) + kvs = append(kvs, c.prefix...) + kvs = append(kvs, kv...) + return &logger{ + logger: c.logger, + prefix: kvs, + hasValuer: containsValuer(kvs), + ctx: c.ctx, + } +} + +// WithContext returns a shallow copy of l with its context changed +// to ctx. The provided ctx must be non-nil. +func WithContext(ctx context.Context, l Logger) Logger { + switch v := l.(type) { + default: + return &logger{logger: l, ctx: ctx} + case *logger: + lv := *v + lv.ctx = ctx + return &lv + case *Filter: + fv := *v + fv.logger = WithContext(ctx, fv.logger) + return &fv + } +} diff --git a/utils/kratos/value.go b/utils/kratos/value.go new file mode 100644 index 00000000..af88c969 --- /dev/null +++ b/utils/kratos/value.go @@ -0,0 +1,66 @@ +// copied from https://github.com/go-kratos/kratos/tree/main/log +package log + +import ( + "context" + "runtime" + "strconv" + "strings" + "time" +) + +var ( + // DefaultCaller is a Valuer that returns the file and line. + DefaultCaller = Caller(4) + + // DefaultTimestamp is a Valuer that returns the current wallclock time. + DefaultTimestamp = Timestamp(time.RFC3339) +) + +// Valuer is returns a log value. +type Valuer func(ctx context.Context) interface{} + +// Value return the function value. +func Value(ctx context.Context, v interface{}) interface{} { + if v, ok := v.(Valuer); ok { + return v(ctx) + } + return v +} + +// Caller returns a Valuer that returns a pkg/file:line description of the caller. +func Caller(depth int) Valuer { + return func(context.Context) interface{} { + _, file, line, _ := runtime.Caller(depth) + idx := strings.LastIndexByte(file, '/') + if idx == -1 { + return file[idx+1:] + ":" + strconv.Itoa(line) + } + idx = strings.LastIndexByte(file[:idx], '/') + return file[idx+1:] + ":" + strconv.Itoa(line) + } +} + +// Timestamp returns a timestamp Valuer with a custom time format. +func Timestamp(layout string) Valuer { + return func(context.Context) interface{} { + return time.Now().Format(layout) + } +} + +func bindValues(ctx context.Context, keyvals []interface{}) { + for i := 1; i < len(keyvals); i += 2 { + if v, ok := keyvals[i].(Valuer); ok { + keyvals[i] = v(ctx) + } + } +} + +func containsValuer(keyvals []interface{}) bool { + for i := 1; i < len(keyvals); i += 2 { + if _, ok := keyvals[i].(Valuer); ok { + return true + } + } + return false +} diff --git a/utils/kratos/zap.go b/utils/kratos/zap.go new file mode 100644 index 00000000..71bb6662 --- /dev/null +++ b/utils/kratos/zap.go @@ -0,0 +1,131 @@ +package log + +import ( + "encoding/json" + "os" + + "github.com/natefinch/lumberjack" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" + "moul.io/zapfilter" +) + +// TODO:或许有更好的方案,目前只是保证能够使用了 +// 搬运过来WriterX,然后默认初始化,给一个方式获取那个WriterX + +var logLimitDefault int64 = 100 +var originZapLogger *zap.Logger + +// GetLoggerRaw 特殊情况下,获取原生的LOGGER进行处理 +func GetLoggerRaw() *zap.Logger { + return originZapLogger +} + +type LogItem struct { + Level string `json:"level"` + TS float64 `json:"ts"` + Caller string `json:"caller"` + Msg string `json:"msg"` +} + +type WriterX struct { + LogLimit int64 + Items []*LogItem +} + +func (w *WriterX) Write(p []byte) (n int, err error) { + var a LogItem + err2 := json.Unmarshal(p, &a) + if err2 == nil { + w.Items = append(w.Items, &a) + limit := w.LogLimit + if limit == 0 { + w.LogLimit = logLimitDefault + } + if len(w.Items) > int(limit) { + w.Items = w.Items[1:] + } + } + return len(p), nil +} + +var enabledLevel = zap.InfoLevel + +func SetEnableLevel(level zapcore.Level) { + switch level { + case zapcore.DebugLevel, zapcore.InfoLevel, zapcore.WarnLevel, zapcore.ErrorLevel, + zapcore.DPanicLevel, zapcore.PanicLevel, zapcore.FatalLevel: + { + enabledLevel = level + } + default: // no-op + } +} + +// InitZapWithKartosLog 将所有的信息都会输出到main.log,以及输出到控制台 +func InitZapWithKartosLog(level zapcore.Level) { + SetEnableLevel(level) + // 日志文件的路径 + path := "./data/main.log" + + // 使用lumberjack进行日志文件轮转配置 + lumlog := &lumberjack.Logger{ + Filename: path, // 日志文件的名称和路径 + MaxSize: 10, // 每个日志文件最大10MB + MaxBackups: 3, // 最多保留3个旧日志文件 + MaxAge: 7, // 日志文件保存7天 + } + + // 获取日志编码器,定义日志的输出格式 + encoder := getEncoder() + + // 输出到UI的配置部分 + pe := zap.NewProductionEncoderConfig() + global.wx = &WriterX{} + // 输出到文件的配置部分 + mainLogCore := zapcore.NewCore(encoder, zapcore.AddSync(lumlog), zapcore.DebugLevel) + // 创建控制台的日志编码器 + consoleCoreRaw := zapcore.NewCore(encoder, zapcore.AddSync(os.Stdout), enabledLevel) + // 适配隐藏控制台输出的部分,重新设置日志级别,并输出除了HIDE以外的所有情况。这里ByNamespaces注意要先定义”全部选择“,然后定义”HIDE的不要“。 + consoleCore := zapfilter.NewFilteringCore(consoleCoreRaw, zapfilter.All(zapfilter.MinimumLevel(enabledLevel), zapfilter.ByNamespaces("*,-HIDE.*"))) + + // 创建日志核心,将日志写入lumberjack的文件中,并设置日志级别为Debug + cores := []zapcore.Core{ + // 默认输出到main.log的,全量日志文件 + mainLogCore, + // 默认输出到UI的,只输出Info级别 + // This outputs to WebUI, DO NOT apply enabledLevel + zapcore.NewCore(zapcore.NewJSONEncoder(pe), zapcore.AddSync(global.wx), zapcore.InfoLevel), + consoleCore, + } + + // 将多个日志核心组合到一起,以同时记录到文件和控制台 + core := zapcore.NewTee(cores...) + + // 创建带有调用者信息的日志记录器,注意跳过两层,这样就能正常提供给log + originZapLogger = zap.New(core, zap.AddCaller(), zap.AddCallerSkip(2)) + + // 设置全局日志记录器,默认全局记录器为SEAL命名空间 + global.SetLogger(NewZapLogger(originZapLogger.Named(LOG_SEAL))) +} + +func GetWebLogger() *Helper { + webpath := "./data/web.log" + weblumlog := &lumberjack.Logger{ + Filename: webpath, // 日志文件的名称和路径 + MaxSize: 10, // 每个日志文件最大10MB + MaxBackups: 3, // 最多保留3个旧日志文件 + MaxAge: 7, // 日志文件保存7天 + } + webCore := zapcore.NewCore(getEncoder(), zapcore.AddSync(weblumlog), zapcore.DebugLevel) + originZapLogger = zap.New(webCore, zap.WithCaller(false)) + return NewHelper(NewZapLogger(originZapLogger.Named("WEB"))) +} + +func getEncoder() zapcore.Encoder { + encoderConfig := zap.NewProductionEncoderConfig() + encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder + encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder + + return zapcore.NewConsoleEncoder(encoderConfig) +} diff --git a/utils/kratos/zaplogger.go b/utils/kratos/zaplogger.go new file mode 100644 index 00000000..9fd05636 --- /dev/null +++ b/utils/kratos/zaplogger.go @@ -0,0 +1,75 @@ +// copied from github.com/go-kratos/kratos/contrib/log/zap/v2 +package log + +import ( + "fmt" + + "go.uber.org/zap" +) + +var _ Logger = (*ZapLogger)(nil) + +type ZapLogger struct { + log *zap.Logger + msgKey string +} + +func NewZapLogger(zlog *zap.Logger) *ZapLogger { + return &ZapLogger{ + log: zlog, + msgKey: DefaultMessageKey, + } +} + +// 保留给Helper使用 + +type ZapOption func(*ZapLogger) + +// WithZapMessageKey with message key. +func WithZapMessageKey(key string) ZapOption { + return func(l *ZapLogger) { + l.msgKey = key + } +} + +func (l *ZapLogger) Log(level Level, keyvals ...interface{}) error { + var ( + msg = "" + keylen = len(keyvals) + ) + if keylen == 0 || keylen%2 != 0 { + l.log.Warn(fmt.Sprint("Keyvalues must appear in pairs: ", keyvals)) + return nil + } + + data := make([]zap.Field, 0, (keylen/2)+1) + for i := 0; i < keylen; i += 2 { + if keyvals[i].(string) == l.msgKey { + msg, _ = keyvals[i+1].(string) + continue + } + data = append(data, zap.Any(fmt.Sprint(keyvals[i]), keyvals[i+1])) + } + + switch level { + case LevelDebug: + l.log.Debug(msg, data...) + case LevelInfo: + l.log.Info(msg, data...) + case LevelWarn: + l.log.Warn(msg, data...) + case LevelError: + l.log.Error(msg, data...) + case LevelFatal: + l.log.Fatal(msg, data...) + } + return nil +} + +func (l *ZapLogger) Sync() error { + return l.log.Sync() +} + +func (l *ZapLogger) Close() error { + return l.Sync() +}