From 0dab7d495711e93a70c6409244a824cd82178c2c Mon Sep 17 00:00:00 2001 From: Pinenutn <1101839859@qq.com> Date: Fri, 18 Oct 2024 19:24:09 +0800 Subject: [PATCH 01/12] =?UTF-8?q?=E6=9A=82=E5=AD=98=EF=BC=8C=E6=9A=82?= =?UTF-8?q?=E5=AD=98=E5=96=B5=EF=BC=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go.mod | 2 + go.sum | 4 + main.go | 7 +- utils/oschecker/checker_darwin.go | 17 +++ utils/oschecker/checker_linux.go | 74 ++++++++++++ utils/oschecker/checker_windows.go | 183 +++++++++++++++++++++++++++++ 6 files changed, 286 insertions(+), 1 deletion(-) create mode 100644 utils/oschecker/checker_darwin.go create mode 100644 utils/oschecker/checker_linux.go create mode 100644 utils/oschecker/checker_windows.go diff --git a/go.mod b/go.mod index 279f04e5..5d99b602 100644 --- a/go.mod +++ b/go.mod @@ -80,6 +80,7 @@ require ( ) require ( + github.com/Masterminds/semver v1.5.0 // indirect github.com/RoaringBitmap/roaring v1.2.3 // indirect github.com/bits-and-blooms/bitset v1.2.2 // indirect github.com/bits-and-blooms/bloom/v3 v3.2.0 // indirect @@ -158,6 +159,7 @@ require ( github.com/tidwall/tinyqueue v0.1.1 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect + github.com/wobsoriano/go-macos-version v0.1.2 // indirect 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 diff --git a/go.sum b/go.sum index 20820e23..467537d0 100644 --- a/go.sum +++ b/go.sum @@ -2,6 +2,8 @@ filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= +github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= github.com/Milly/go-base2048 v0.1.0 h1:7ZgpCR3cjcAAVqIo+B8Q3P1+VFHRS8zilzAq062rUUk= @@ -422,6 +424,8 @@ github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQ github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI= github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= +github.com/wobsoriano/go-macos-version v0.1.2 h1:f5P0X2dqMOoRONkTSUPbAQ6YV2N3SOmJwErdrr3EiCI= +github.com/wobsoriano/go-macos-version v0.1.2/go.mod h1:jpf39fsNzfivDuSyvPPLYUSOCj0gkt3JQJCUw4vrXoU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/xuri/efp v0.0.0-20231025114914-d1ff6096ae53 h1:Chd9DkqERQQuHpXjR/HSV1jLZA6uaoiwwH3vSuF3IW0= github.com/xuri/efp v0.0.0-20231025114914-d1ff6096ae53/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI= diff --git a/main.go b/main.go index 0b41c6a6..7211a2ae 100644 --- a/main.go +++ b/main.go @@ -29,6 +29,7 @@ import ( "sealdice-core/static" "sealdice-core/utils/crypto" log "sealdice-core/utils/kratos" + "sealdice-core/utils/oschecker" "sealdice-core/utils/paniclog" ) @@ -204,7 +205,11 @@ func main() { paniclog.InitPanicLog() // 3. 提示日志打印 log.Info("运行日志开始记录,海豹出现故障时可查看 data/main.log 与 data/panic.log 获取更多信息") - + judge, osr := oschecker.OldVersionCheck() + if !judge { + log.Warnf("当前操作系统%s版本过低,可能无法正常启动,请升级到 Windows 10 1903 或更高版本", osr) + } + log.Info(osr) if opts.Version { fmt.Println(dice.VERSION.String()) return diff --git a/utils/oschecker/checker_darwin.go b/utils/oschecker/checker_darwin.go new file mode 100644 index 00000000..f5bda938 --- /dev/null +++ b/utils/oschecker/checker_darwin.go @@ -0,0 +1,17 @@ +package oschecker + +import ( + mac "github.com/wobsoriano/go-macos-version" +) + +func OldVersionCheck() (bool, string) { + version, err := mac.MacOSVersion() + if err != nil { + return true, "MAC_UNKNOWN" + } + judge, err := mac.IsMacOSVersion(">10.10") + if err != nil { + return true, "MAC_UNKNOWN" + } + return judge, version +} diff --git a/utils/oschecker/checker_linux.go b/utils/oschecker/checker_linux.go new file mode 100644 index 00000000..c8f2fbe7 --- /dev/null +++ b/utils/oschecker/checker_linux.go @@ -0,0 +1,74 @@ +package oschecker + +import ( + "bytes" + "fmt" + "os/exec" + "strconv" + "strings" + + log "sealdice-core/utils/kratos" +) + +func OldVersionCheck() (bool, string) { + version := getGlibcVersion() + if version == 0 { + return true, fmt.Sprintf("%v", version) + } + if getGlibcVersion() <= 2.17 { + return false, fmt.Sprintf("%v", version) + } + return true, fmt.Sprintf("%v", version) +} + +// GetGlibcVersion 获取glibc版本号,默认设置为CentOS7 的 2.17版本,这个版本默认会认为是低版本 +func getGlibcVersion() float64 { + shell, err := execShell("ldd --version | awk 'NR==1{print $NF}'") + if err != nil { + log.Debugf("获取glibc版本号失败: %s", err.Error()) + return 0 + } + version := clearStr(shell) + f, err := strconv.ParseFloat(version, 64) + if err != nil { + log.Debugf("转换glibc版本号失败:version-%s err-%s", version, err.Error()) + return 0 + } + return f +} + +// ClearStr 清理字符串中的空格、换行符、制表符 +func clearStr(str string) string { + return string(clearBytes([]byte(str))) +} + +func clearBytes(str []byte) []byte { + return bytes.ReplaceAll(bytes.ReplaceAll(bytes.ReplaceAll(bytes.ReplaceAll(str, []byte(" "), []byte("")), []byte("\r"), []byte("")), []byte("\t"), []byte("")), []byte("\n"), []byte("")) +} + +func execShell(cmdStr string) (string, error) { + if !strings.HasPrefix(cmdStr, "sudo") { + cmdStr = "sudo " + cmdStr + } + cmd := exec.Command("bash", "-c", cmdStr) + var stdout, stderr bytes.Buffer + cmd.Stdout = &stdout + cmd.Stderr = &stderr + err := cmd.Run() + if err != nil { + errMsg := "Shell: " + cmdStr + ";" + if len(stderr.String()) != 0 { + errMsg = fmt.Sprintf("stderr: %s", stderr.String()) + } + if len(stdout.String()) != 0 { + if len(errMsg) != 0 { + errMsg = fmt.Sprintf("%s; stdout: %s", errMsg, stdout.String()) + } else { + errMsg = fmt.Sprintf("stdout: %s", stdout.String()) + } + } + fmt.Printf("ExecShell-errMsg-> %s\n", errMsg) + return errMsg, fmt.Errorf(errMsg) + } + return stdout.String(), nil +} diff --git a/utils/oschecker/checker_windows.go b/utils/oschecker/checker_windows.go new file mode 100644 index 00000000..f25ae05f --- /dev/null +++ b/utils/oschecker/checker_windows.go @@ -0,0 +1,183 @@ +package oschecker + +// copied from https://github.com/jfjallid/go-secdump/blob/e307524e114f9abb39e2cd2b13ae421aae02d2de/utils.go with some changes + +import ( + "strconv" + "strings" + + "golang.org/x/sys/windows/registry" + + log "sealdice-core/utils/kratos" +) + +const ( + WIN_UNKNOWN = iota + WINXP + WIN_SERVER_2003 + WIN_VISTA + WIN_SERVER_2008 + WIN7 + WIN_SERVER_2008_R2 + WIN8 + WIN_SERVER_2012 + WIN81 + WIN_SERVER_2012_R2 + WIN10 + WIN_SERVER_2016 + WIN_SERVER_2019 + WIN_SERVER_2022 + WIN11 +) + +var osNameMap = map[byte]string{ + WIN_UNKNOWN: "Windows Unknown", + WINXP: "Windows XP", + WIN_VISTA: "Windows Vista", + WIN7: "Windows 7", + WIN8: "Windows 8", + WIN81: "Windows 8.1", + WIN10: "Windows 10", + WIN11: "Windows 11", + WIN_SERVER_2003: "Windows Server 2003", + WIN_SERVER_2008: "Windows Server 2008", + WIN_SERVER_2008_R2: "Windows Server 2008 R2", + WIN_SERVER_2012: "Windows Server 2012", + WIN_SERVER_2012_R2: "Windows Server 2012 R2", + WIN_SERVER_2016: "Windows Server 2016", + WIN_SERVER_2019: "Windows Server 2019", + WIN_SERVER_2022: "Windows Server 2022", +} + +// OldVersionCheck 只获取最低版本 +func OldVersionCheck() (bool, string) { + build, f, b, err := getOSVersionBuild() + if err != nil { + // 不知道的版本,就认为是支持的 + return true, osNameMap[WIN_UNKNOWN] + } + os := GetOSVersion(build, f, b) + if (WINXP <= os) && (os <= WIN10) { + return true, osNameMap[os] + } else { + return false, osNameMap[os] + } +} + +func GetOSVersion(currentBuild int, currentVersion float64, server bool) (os byte) { + currentVersionStr := strconv.FormatFloat(currentVersion, 'f', 1, 64) + if server { + switch { + case currentBuild >= 3790 && currentBuild < 6001: + os = WIN_SERVER_2003 + case currentBuild >= 6001 && currentBuild < 7601: + os = WIN_SERVER_2008 + case currentBuild >= 7601 && currentBuild < 9200: + os = WIN_SERVER_2008_R2 + case currentBuild >= 9200 && currentBuild < 9600: + os = WIN_SERVER_2012 + case currentBuild >= 9200 && currentBuild < 14393: + os = WIN_SERVER_2012_R2 + case currentBuild >= 14393 && currentBuild < 17763: + os = WIN_SERVER_2016 + case currentBuild >= 17763 && currentBuild < 20348: + os = WIN_SERVER_2019 + case currentBuild >= 20348: + os = WIN_SERVER_2022 + default: + log.Debugf("Unknown server version of Windows with CurrentBuild %d and CurrentVersion %f\n", currentBuild, currentVersion) + os = WIN_UNKNOWN + } + } else { + switch currentVersionStr { + case "5.1": + os = WINXP + case "6.0": + // Windows Vista but it shares CurrentVersion and CurrentBuild with Windows Server 2008 + os = WIN_VISTA + case "6.1": + // Windows 7 but it shares CurrentVersion and CurrentBuild with Windows Server 2008 R2 + os = WIN7 + case "6.2": + // Windows 8 but it shares CurrentVersion and CurrentBuild with Windows Server 2012 + os = WIN8 + case "6.3": + // Windows 8.1 but it shares CurrentVersion and CurrentBuild with Windows Server 2012 R2 + os = WIN81 + case "10.0": + if currentBuild < 22000 { + os = WIN10 + } else { + os = WIN11 + } + default: + log.Debugf("Unknown version of Windows with CurrentBuild %d and CurrentVersion %f\n", currentBuild, currentVersion) + os = WIN_UNKNOWN + } + } + + log.Debugf("OS Version: %s\n", osNameMap[os]) + return +} + +func getOSVersionBuild() (build int, version float64, server bool, err error) { + hSubKey, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion`, registry.QUERY_VALUE) + if err != nil { + log.Errorf("Failed to open registry key CurrentVersion with error: %v\n", err) + return + } + defer func(hSubKey registry.Key) { + err = hSubKey.Close() + if err != nil { + log.Fatalf("Failed to close hSubkey with error: %v\n", err) + } + }(hSubKey) + + buildStr, _, err := hSubKey.GetStringValue("CurrentBuild") + if err != nil { + log.Error(err) + return + } + build, err = strconv.Atoi(buildStr) + if err != nil { + log.Error(err) + return + } + versionStr, _, err := hSubKey.GetStringValue("CurrentVersion") + if err != nil { + log.Error(err) + return + } + + version, err = strconv.ParseFloat(versionStr, 32) + if err != nil { + log.Errorf("Failed to get CurrentVersion with error: %v\n", err) + return + } + majorVersionStr, _, err := hSubKey.GetIntegerValue("CurrentMajorVersionNumber") + if err != nil { + return + } + // 据说,当前Win11和Win10的大版本号还相同,没有Win11,难以测试 + if majorVersionStr == 10 { + version = 10.0 + } + + hSubKey, err = registry.OpenKey(registry.LOCAL_MACHINE, `SYSTEM\CurrentControlSet\Control\ProductOptions`, registry.QUERY_VALUE) + if err != nil { + log.Errorf("Failed to open registry key ProductOptions with error: %v\n", err) + return + } + + serverFlag, _, err := hSubKey.GetStringValue("ProductType") + if err != nil { + log.Error(err) + return + } + + if strings.Compare(serverFlag, "ServerNT") == 0 { + server = true + } + + return +} From 593d4339f1641c7fa71ecee59f0a31c679d2aebd Mon Sep 17 00:00:00 2001 From: Pinenutn <1101839859@qq.com> Date: Fri, 18 Oct 2024 19:56:18 +0800 Subject: [PATCH 02/12] =?UTF-8?q?fix:=20=E6=B7=BB=E5=8A=A0checker=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go.mod | 2 +- go.sum | 6 ++++++ main.go | 6 +++--- utils/oschecker/checker_darwin.go | 1 + utils/oschecker/checker_linux.go | 1 + utils/oschecker/checker_windows.go | 20 +++++++++++++++++--- 6 files changed, 29 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index 432ccaa7..b2ef8ceb 100644 --- a/go.mod +++ b/go.mod @@ -64,6 +64,7 @@ require ( github.com/tidwall/gjson v1.18.0 github.com/tidwall/sjson v1.2.5 github.com/vmihailenco/msgpack v4.0.4+incompatible + github.com/wobsoriano/go-macos-version v0.1.2 github.com/xuri/excelize/v2 v2.8.1 github.com/yuin/goldmark v1.7.4 go.etcd.io/bbolt v1.3.9 @@ -159,7 +160,6 @@ require ( github.com/tidwall/tinyqueue v0.1.1 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect - github.com/wobsoriano/go-macos-version v0.1.2 // indirect 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 diff --git a/go.sum b/go.sum index 467537d0..9de19c8f 100644 --- a/go.sum +++ b/go.sum @@ -187,6 +187,7 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg= github.com/google/pprof v0.0.0-20230926050212-f7f687d19a98 h1:pUa4ghanp6q4IJHwE9RwLgmVFfReJN+KbQ8ExNEUUoQ= @@ -298,6 +299,7 @@ github.com/open-dingtalk/dingtalk-stream-sdk-go v0.9.0/go.mod h1:ln3IqPYYocZbYvl github.com/otiai10/copy v1.14.0 h1:dCI/t1iTdYGtkvCuBG2BgR6KZa83PTclw4U5n2wAllU= github.com/otiai10/copy v1.14.0/go.mod h1:ECfuL02W+/FkTWZWgQqXPWZgW9oeKCSQ5qVfSc4qc4w= github.com/otiai10/mint v1.5.1 h1:XaPLeE+9vGbuyEHem1JNk3bYc7KKqyI/na0/mLd/Kks= +github.com/otiai10/mint v1.5.1/go.mod h1:MJm72SBthJjz8qhefc4z1PYEieWmy8Bku7CjcAqyUSM= 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.8.1 h1:AiWUb8uXlrXqJ73OmiYXBjDF0Qxt4OuM281eAfkAOMA= @@ -393,7 +395,9 @@ github.com/tdewolff/parse/v2 v2.7.15 h1:hysDXtdGZIRF5UZXwpfn3ZWRbm+ru4l53/ajBRGp github.com/tdewolff/parse/v2 v2.7.15/go.mod h1:3FbJWZp3XT9OWVN3Hmfp0p/a08v4h8J9W1aghka0soA= github.com/tdewolff/test v1.0.11-0.20231101010635-f1265d231d52/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE= github.com/tdewolff/test v1.0.11-0.20240106005702-7de5f7df4739 h1:IkjBCtQOOjIn03u/dMQK9g+Iw9ewps4mCl1nB8Sscbo= +github.com/tdewolff/test v1.0.11-0.20240106005702-7de5f7df4739/go.mod h1:XPuWBzvdUzhCuxWO1ojpXsyzsA5bFoS3tO/Q3kFuTG8= github.com/tidwall/assert v0.1.0 h1:aWcKyRBUAdLoVebxo95N7+YZVTFF/ASTr7BN4sLP6XI= +github.com/tidwall/assert v0.1.0/go.mod h1:QLYtGyeqse53vuELQheYl9dngGCJQ+mTtlxcktb+Kj8= github.com/tidwall/btree v1.7.0 h1:L1fkJH/AuEh5zBnnBbmTwQ5Lt+bRJ5A8EWecslvo9iI= github.com/tidwall/btree v1.7.0/go.mod h1:twD9XRA5jj9VUQGELzDO4HPQTNJsoWWfYEL+EUQ2cKY= github.com/tidwall/buntdb v1.3.2 h1:qd+IpdEGs0pZci37G4jF51+fSKlkuUTMXuHhXL1AkKg= @@ -406,6 +410,7 @@ github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vl github.com/tidwall/grect v0.1.4 h1:dA3oIgNgWdSspFzn1kS4S/RDpZFLrIxAZOdJKjYapOg= github.com/tidwall/grect v0.1.4/go.mod h1:9FBsaYRaR0Tcy4UwefBX/UDcDcDy9V5jUcxHzv2jd5Q= github.com/tidwall/lotsa v1.0.2 h1:dNVBH5MErdaQ/xd9s769R31/n2dXavsQ0Yf4TMEHHw8= +github.com/tidwall/lotsa v1.0.2/go.mod h1:X6NiU+4yHA3fE3Puvpnn1XMDrFZrE9JO2/w+UMuqgR8= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= @@ -444,6 +449,7 @@ 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/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= 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= diff --git a/main.go b/main.go index 7211a2ae..835e21eb 100644 --- a/main.go +++ b/main.go @@ -206,10 +206,10 @@ func main() { // 3. 提示日志打印 log.Info("运行日志开始记录,海豹出现故障时可查看 data/main.log 与 data/panic.log 获取更多信息") judge, osr := oschecker.OldVersionCheck() - if !judge { - log.Warnf("当前操作系统%s版本过低,可能无法正常启动,请升级到 Windows 10 1903 或更高版本", osr) + // 预留收集信息的接口,如果有需要可以考虑从这里拿数据。不从这里做提示的原因是Windows和Linux的展示方式不同。 + if judge { + log.Info(osr) } - log.Info(osr) if opts.Version { fmt.Println(dice.VERSION.String()) return diff --git a/utils/oschecker/checker_darwin.go b/utils/oschecker/checker_darwin.go index f5bda938..ba9d13ff 100644 --- a/utils/oschecker/checker_darwin.go +++ b/utils/oschecker/checker_darwin.go @@ -4,6 +4,7 @@ import ( mac "github.com/wobsoriano/go-macos-version" ) +// TODO: MacOS 如何提示用户? func OldVersionCheck() (bool, string) { version, err := mac.MacOSVersion() if err != nil { diff --git a/utils/oschecker/checker_linux.go b/utils/oschecker/checker_linux.go index c8f2fbe7..3b72646c 100644 --- a/utils/oschecker/checker_linux.go +++ b/utils/oschecker/checker_linux.go @@ -10,6 +10,7 @@ import ( log "sealdice-core/utils/kratos" ) +// 如果使用musl,这个有没有用就存疑了 func OldVersionCheck() (bool, string) { version := getGlibcVersion() if version == 0 { diff --git a/utils/oschecker/checker_windows.go b/utils/oschecker/checker_windows.go index f25ae05f..782c0783 100644 --- a/utils/oschecker/checker_windows.go +++ b/utils/oschecker/checker_windows.go @@ -3,9 +3,12 @@ package oschecker // copied from https://github.com/jfjallid/go-secdump/blob/e307524e114f9abb39e2cd2b13ae421aae02d2de/utils.go with some changes import ( + "fmt" "strconv" "strings" + "syscall" + "github.com/lxn/win" "golang.org/x/sys/windows/registry" log "sealdice-core/utils/kratos" @@ -57,13 +60,23 @@ func OldVersionCheck() (bool, string) { return true, osNameMap[WIN_UNKNOWN] } os := GetOSVersion(build, f, b) - if (WINXP <= os) && (os <= WIN10) { + // 这里用WinXP打底的原因是,WinXP下面是未知系统,我们默认放行未知系统 + if (WINXP <= os) && (os < WIN10) { + // 展示提示弹窗,提示用户升级 + showMsgBox("版本升级提示", fmt.Sprintf("您的操作系统:%s 即将不受支持,请升级至 Windows 10/Windows Server 2016 或更高版本。", osNameMap[os])) return true, osNameMap[os] } else { + showMsgBox("版本升级提示", fmt.Sprintf("您的操作系统:%s 还在受支持,您无需考虑升级到更高版本。", osNameMap[os])) return false, osNameMap[os] } } +func showMsgBox(title string, message string) { + s1, _ := syscall.UTF16PtrFromString(title) + s2, _ := syscall.UTF16PtrFromString(message) + win.MessageBox(0, s2, s1, win.MB_OK|win.MB_ICONERROR) +} + func GetOSVersion(currentBuild int, currentVersion float64, server bool) (os byte) { currentVersionStr := strconv.FormatFloat(currentVersion, 'f', 1, 64) if server { @@ -154,11 +167,12 @@ func getOSVersionBuild() (build int, version float64, server bool, err error) { log.Errorf("Failed to get CurrentVersion with error: %v\n", err) return } + // 二次判断:由于有Win8升级成Win10的情况,这个参数不准确。这个参数只有Win10往上有,所以下面 majorVersionStr, _, err := hSubKey.GetIntegerValue("CurrentMajorVersionNumber") if err != nil { - return + log.Debug("非Win8以上系统,不包含CurrentMajorVersionNumber参数。") } - // 据说,当前Win11和Win10的大版本号还相同,没有Win11,难以测试 + // TODO: 据说,当前Win11和Win10的大版本号还相同,没有Win11,难以测试 if majorVersionStr == 10 { version = 10.0 } From a6d6f52357e38398fae7d1b639932d79c479d7c0 Mon Sep 17 00:00:00 2001 From: Pinenutn <1101839859@qq.com> Date: Fri, 18 Oct 2024 19:57:43 +0800 Subject: [PATCH 03/12] =?UTF-8?q?chores:=20=E5=86=99=E6=98=8E=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- utils/oschecker/checker_darwin.go | 3 +++ utils/oschecker/checker_linux.go | 3 +++ utils/oschecker/checker_windows.go | 3 +++ 3 files changed, 9 insertions(+) diff --git a/utils/oschecker/checker_darwin.go b/utils/oschecker/checker_darwin.go index ba9d13ff..8fd37d33 100644 --- a/utils/oschecker/checker_darwin.go +++ b/utils/oschecker/checker_darwin.go @@ -1,3 +1,6 @@ +//go:build darwin +// +build darwin + package oschecker import ( diff --git a/utils/oschecker/checker_linux.go b/utils/oschecker/checker_linux.go index 3b72646c..0517a1b4 100644 --- a/utils/oschecker/checker_linux.go +++ b/utils/oschecker/checker_linux.go @@ -1,3 +1,6 @@ +//go:build !windows && !darwin +// +build !windows,!darwin + package oschecker import ( diff --git a/utils/oschecker/checker_windows.go b/utils/oschecker/checker_windows.go index 782c0783..481dda28 100644 --- a/utils/oschecker/checker_windows.go +++ b/utils/oschecker/checker_windows.go @@ -1,3 +1,6 @@ +//go:build windows +// +build windows + package oschecker // copied from https://github.com/jfjallid/go-secdump/blob/e307524e114f9abb39e2cd2b13ae421aae02d2de/utils.go with some changes From 095bbf133ec6530ee7afd02a0299318023e168d6 Mon Sep 17 00:00:00 2001 From: Pinenutn <1101839859@qq.com> Date: Fri, 18 Oct 2024 20:02:49 +0800 Subject: [PATCH 04/12] make new lint happy. --- utils/oschecker/checker_linux.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/utils/oschecker/checker_linux.go b/utils/oschecker/checker_linux.go index 0517a1b4..f0ea9451 100644 --- a/utils/oschecker/checker_linux.go +++ b/utils/oschecker/checker_linux.go @@ -5,6 +5,7 @@ package oschecker import ( "bytes" + "errors" "fmt" "os/exec" "strconv" @@ -72,7 +73,7 @@ func execShell(cmdStr string) (string, error) { } } fmt.Printf("ExecShell-errMsg-> %s\n", errMsg) - return errMsg, fmt.Errorf(errMsg) + return errMsg, errors.New(errMsg) } return stdout.String(), nil } From 9b8a4369ba863262f1d596716a586b980a239f8c Mon Sep 17 00:00:00 2001 From: Pinenutn <1101839859@qq.com> Date: Sat, 19 Oct 2024 03:04:09 +0800 Subject: [PATCH 05/12] =?UTF-8?q?fix:=20=E5=8E=BB=E9=99=A4=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E4=BD=8D=E7=BD=AE=E7=9A=84=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- utils/oschecker/checker_windows.go | 1 - 1 file changed, 1 deletion(-) diff --git a/utils/oschecker/checker_windows.go b/utils/oschecker/checker_windows.go index 481dda28..73d570a7 100644 --- a/utils/oschecker/checker_windows.go +++ b/utils/oschecker/checker_windows.go @@ -69,7 +69,6 @@ func OldVersionCheck() (bool, string) { showMsgBox("版本升级提示", fmt.Sprintf("您的操作系统:%s 即将不受支持,请升级至 Windows 10/Windows Server 2016 或更高版本。", osNameMap[os])) return true, osNameMap[os] } else { - showMsgBox("版本升级提示", fmt.Sprintf("您的操作系统:%s 还在受支持,您无需考虑升级到更高版本。", osNameMap[os])) return false, osNameMap[os] } } From fb4e24badf27e24f1b8e47a560d4585d2b6f16a8 Mon Sep 17 00:00:00 2001 From: Pinenutn <1101839859@qq.com> Date: Sat, 19 Oct 2024 22:48:00 +0800 Subject: [PATCH 06/12] =?UTF-8?q?fix:=20=E5=8E=BB=E9=99=A4linux=E7=AD=89?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E7=9A=84=E6=A3=80=E6=9F=A5=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- utils/oschecker/checker_darwin.go | 21 -------- utils/oschecker/checker_linux.go | 79 ------------------------------- utils/oschecker/checker_other.go | 9 ++++ 3 files changed, 9 insertions(+), 100 deletions(-) delete mode 100644 utils/oschecker/checker_darwin.go delete mode 100644 utils/oschecker/checker_linux.go create mode 100644 utils/oschecker/checker_other.go diff --git a/utils/oschecker/checker_darwin.go b/utils/oschecker/checker_darwin.go deleted file mode 100644 index 8fd37d33..00000000 --- a/utils/oschecker/checker_darwin.go +++ /dev/null @@ -1,21 +0,0 @@ -//go:build darwin -// +build darwin - -package oschecker - -import ( - mac "github.com/wobsoriano/go-macos-version" -) - -// TODO: MacOS 如何提示用户? -func OldVersionCheck() (bool, string) { - version, err := mac.MacOSVersion() - if err != nil { - return true, "MAC_UNKNOWN" - } - judge, err := mac.IsMacOSVersion(">10.10") - if err != nil { - return true, "MAC_UNKNOWN" - } - return judge, version -} diff --git a/utils/oschecker/checker_linux.go b/utils/oschecker/checker_linux.go deleted file mode 100644 index f0ea9451..00000000 --- a/utils/oschecker/checker_linux.go +++ /dev/null @@ -1,79 +0,0 @@ -//go:build !windows && !darwin -// +build !windows,!darwin - -package oschecker - -import ( - "bytes" - "errors" - "fmt" - "os/exec" - "strconv" - "strings" - - log "sealdice-core/utils/kratos" -) - -// 如果使用musl,这个有没有用就存疑了 -func OldVersionCheck() (bool, string) { - version := getGlibcVersion() - if version == 0 { - return true, fmt.Sprintf("%v", version) - } - if getGlibcVersion() <= 2.17 { - return false, fmt.Sprintf("%v", version) - } - return true, fmt.Sprintf("%v", version) -} - -// GetGlibcVersion 获取glibc版本号,默认设置为CentOS7 的 2.17版本,这个版本默认会认为是低版本 -func getGlibcVersion() float64 { - shell, err := execShell("ldd --version | awk 'NR==1{print $NF}'") - if err != nil { - log.Debugf("获取glibc版本号失败: %s", err.Error()) - return 0 - } - version := clearStr(shell) - f, err := strconv.ParseFloat(version, 64) - if err != nil { - log.Debugf("转换glibc版本号失败:version-%s err-%s", version, err.Error()) - return 0 - } - return f -} - -// ClearStr 清理字符串中的空格、换行符、制表符 -func clearStr(str string) string { - return string(clearBytes([]byte(str))) -} - -func clearBytes(str []byte) []byte { - return bytes.ReplaceAll(bytes.ReplaceAll(bytes.ReplaceAll(bytes.ReplaceAll(str, []byte(" "), []byte("")), []byte("\r"), []byte("")), []byte("\t"), []byte("")), []byte("\n"), []byte("")) -} - -func execShell(cmdStr string) (string, error) { - if !strings.HasPrefix(cmdStr, "sudo") { - cmdStr = "sudo " + cmdStr - } - cmd := exec.Command("bash", "-c", cmdStr) - var stdout, stderr bytes.Buffer - cmd.Stdout = &stdout - cmd.Stderr = &stderr - err := cmd.Run() - if err != nil { - errMsg := "Shell: " + cmdStr + ";" - if len(stderr.String()) != 0 { - errMsg = fmt.Sprintf("stderr: %s", stderr.String()) - } - if len(stdout.String()) != 0 { - if len(errMsg) != 0 { - errMsg = fmt.Sprintf("%s; stdout: %s", errMsg, stdout.String()) - } else { - errMsg = fmt.Sprintf("stdout: %s", stdout.String()) - } - } - fmt.Printf("ExecShell-errMsg-> %s\n", errMsg) - return errMsg, errors.New(errMsg) - } - return stdout.String(), nil -} diff --git a/utils/oschecker/checker_other.go b/utils/oschecker/checker_other.go new file mode 100644 index 00000000..20a39fda --- /dev/null +++ b/utils/oschecker/checker_other.go @@ -0,0 +1,9 @@ +//go:build !windows +// +build !windows + +package oschecker + +// 我们没有对其他的系统进行筛查的打算。 +func OldVersionCheck() (bool, string) { + return true, "NOTHING" +} From 662a3f99aae34cb8be76ba1172db00091860fe0f Mon Sep 17 00:00:00 2001 From: Pinenutn <1101839859@qq.com> Date: Sat, 19 Oct 2024 22:48:33 +0800 Subject: [PATCH 07/12] =?UTF-8?q?fix:=20=E6=8A=B9=E9=99=A4=E5=BC=95?= =?UTF-8?q?=E5=85=A5=E7=9A=84=E6=97=A0=E7=94=A8=E5=BA=93=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go.mod | 2 -- go.sum | 4 ---- 2 files changed, 6 deletions(-) diff --git a/go.mod b/go.mod index b2ef8ceb..eeab74ae 100644 --- a/go.mod +++ b/go.mod @@ -64,7 +64,6 @@ require ( github.com/tidwall/gjson v1.18.0 github.com/tidwall/sjson v1.2.5 github.com/vmihailenco/msgpack v4.0.4+incompatible - github.com/wobsoriano/go-macos-version v0.1.2 github.com/xuri/excelize/v2 v2.8.1 github.com/yuin/goldmark v1.7.4 go.etcd.io/bbolt v1.3.9 @@ -81,7 +80,6 @@ require ( ) require ( - github.com/Masterminds/semver v1.5.0 // indirect github.com/RoaringBitmap/roaring v1.2.3 // indirect github.com/bits-and-blooms/bitset v1.2.2 // indirect github.com/bits-and-blooms/bloom/v3 v3.2.0 // indirect diff --git a/go.sum b/go.sum index 9de19c8f..4699e97c 100644 --- a/go.sum +++ b/go.sum @@ -2,8 +2,6 @@ filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= -github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= github.com/Milly/go-base2048 v0.1.0 h1:7ZgpCR3cjcAAVqIo+B8Q3P1+VFHRS8zilzAq062rUUk= @@ -429,8 +427,6 @@ github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQ github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI= github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= -github.com/wobsoriano/go-macos-version v0.1.2 h1:f5P0X2dqMOoRONkTSUPbAQ6YV2N3SOmJwErdrr3EiCI= -github.com/wobsoriano/go-macos-version v0.1.2/go.mod h1:jpf39fsNzfivDuSyvPPLYUSOCj0gkt3JQJCUw4vrXoU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/xuri/efp v0.0.0-20231025114914-d1ff6096ae53 h1:Chd9DkqERQQuHpXjR/HSV1jLZA6uaoiwwH3vSuF3IW0= github.com/xuri/efp v0.0.0-20231025114914-d1ff6096ae53/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI= From 7ad5b1fc28383dbb39335bbacffedbb0726e8b9c Mon Sep 17 00:00:00 2001 From: Pinenutn <1101839859@qq.com> Date: Sat, 19 Oct 2024 22:55:37 +0800 Subject: [PATCH 08/12] =?UTF-8?q?=E5=BC=B9=E7=AA=97=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- utils/oschecker/checker_other.go | 2 +- utils/oschecker/checker_windows.go | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/utils/oschecker/checker_other.go b/utils/oschecker/checker_other.go index 20a39fda..9e2d65f0 100644 --- a/utils/oschecker/checker_other.go +++ b/utils/oschecker/checker_other.go @@ -5,5 +5,5 @@ package oschecker // 我们没有对其他的系统进行筛查的打算。 func OldVersionCheck() (bool, string) { - return true, "NOTHING" + return false, "NOTHING" } diff --git a/utils/oschecker/checker_windows.go b/utils/oschecker/checker_windows.go index 73d570a7..67b55097 100644 --- a/utils/oschecker/checker_windows.go +++ b/utils/oschecker/checker_windows.go @@ -60,13 +60,14 @@ func OldVersionCheck() (bool, string) { build, f, b, err := getOSVersionBuild() if err != nil { // 不知道的版本,就认为是支持的 + showNoticeBox("版本确认提示", "海豹无法获取您的操作系统版本,请确认正在使用 Windows 10/Windows Server 2016 或更高版本的 Windows。") return true, osNameMap[WIN_UNKNOWN] } os := GetOSVersion(build, f, b) // 这里用WinXP打底的原因是,WinXP下面是未知系统,我们默认放行未知系统 if (WINXP <= os) && (os < WIN10) { // 展示提示弹窗,提示用户升级 - showMsgBox("版本升级提示", fmt.Sprintf("您的操作系统:%s 即将不受支持,请升级至 Windows 10/Windows Server 2016 或更高版本。", osNameMap[os])) + showMsgBox("版本升级提示", fmt.Sprintf("您的操作系统版本「%s」过旧,海豹未来将不再支持,请尽快升级系统至 Windows 10/Windows Server 2016 或更高版本。", osNameMap[os])) return true, osNameMap[os] } else { return false, osNameMap[os] @@ -79,6 +80,12 @@ func showMsgBox(title string, message string) { win.MessageBox(0, s2, s1, win.MB_OK|win.MB_ICONERROR) } +func showNoticeBox(title string, message string) { + s1, _ := syscall.UTF16PtrFromString(title) + s2, _ := syscall.UTF16PtrFromString(message) + win.MessageBox(0, s2, s1, win.MB_OK|win.MB_ICONWARNING) +} + func GetOSVersion(currentBuild int, currentVersion float64, server bool) (os byte) { currentVersionStr := strconv.FormatFloat(currentVersion, 'f', 1, 64) if server { From 436552bf03007f603826c0e11c1496e8fb9e93a6 Mon Sep 17 00:00:00 2001 From: Pinenutn <1101839859@qq.com> Date: Sun, 20 Oct 2024 00:16:01 +0800 Subject: [PATCH 09/12] =?UTF-8?q?feat:=20=E5=B0=86=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=BA=93=E6=97=A5=E5=BF=97=E8=AE=B0=E5=BD=95=E6=89=93=E5=8D=B0?= =?UTF-8?q?=E5=88=B0main.log=E6=96=87=E4=BB=B6=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dice/model/db_init.go | 2 +- dice/model/db_init_cgo.go | 2 +- dice/model/sqlhook.go | 83 +++++++++++++++++++++++++++++++++++++++ dice/model/sqlhook_cgo.go | 83 +++++++++++++++++++++++++++++++++++++++ go.mod | 1 + go.sum | 6 +++ main.go | 2 + 7 files changed, 177 insertions(+), 2 deletions(-) create mode 100644 dice/model/sqlhook.go create mode 100644 dice/model/sqlhook_cgo.go diff --git a/dice/model/db_init.go b/dice/model/db_init.go index 99c78ccf..a6ba08ee 100644 --- a/dice/model/db_init.go +++ b/dice/model/db_init.go @@ -9,7 +9,7 @@ import ( ) func _SQLiteDBInit(path string, useWAL bool) (*sqlx.DB, error) { - db, err := sqlx.Open("sqlite", path) + db, err := sqlx.Open(zapDriverName, path) if err != nil { panic(err) } diff --git a/dice/model/db_init_cgo.go b/dice/model/db_init_cgo.go index dcf25921..34706eab 100644 --- a/dice/model/db_init_cgo.go +++ b/dice/model/db_init_cgo.go @@ -9,7 +9,7 @@ import ( ) func _SQLiteDBInit(path string, useWAL bool) (*sqlx.DB, error) { - db, err := sqlx.Open("sqlite3", path) + db, err := sqlx.Open(zapDriverName, path) if err != nil { panic(err) } diff --git a/dice/model/sqlhook.go b/dice/model/sqlhook.go new file mode 100644 index 00000000..88a1c8df --- /dev/null +++ b/dice/model/sqlhook.go @@ -0,0 +1,83 @@ +//go:build !cgo +// +build !cgo + +package model + +import ( + "context" + "database/sql" + "fmt" + "time" + + "github.com/glebarez/go-sqlite" + "github.com/qustavo/sqlhooks/v2" + + log "sealdice-core/utils/kratos" +) + +// 覆盖驱动名 sqlite3 会导致 panic, 因此需要创建新的驱动. +// +// database/sql/sql.go:51 +const zapDriverName = "sqlite3-log" + +func InitZapHook(log *log.Helper) { + hook := &zapHook{Helper: log, IsPrintSQLDuration: true} + sql.Register(zapDriverName, sqlhooks.Wrap(new(sqlite.Driver), hook)) +} + +// make sure zapHook implement all sqlhooks interface. +var _ interface { + sqlhooks.Hooks + sqlhooks.OnErrorer +} = (*zapHook)(nil) + +// zapHook 使用 zap 记录 SQL 查询和参数 +type zapHook struct { + *log.Helper + + // 是否打印 SQL 耗时 + IsPrintSQLDuration bool +} + +// sqlDurationKey 是 context.valueCtx Key +type sqlDurationKey struct{} + +func buildQueryArgsFields(query string, args ...interface{}) []interface{} { + if len(args) == 0 { + return []interface{}{"查询", query} + } + return []interface{}{"查询", query, "参数", args} +} + +func (z *zapHook) Before(ctx context.Context, _ string, _ ...interface{}) (context.Context, error) { + if z == nil || z.Helper == nil { + return ctx, nil + } + + if z.IsPrintSQLDuration { + ctx = context.WithValue(ctx, (*sqlDurationKey)(nil), time.Now()) + } + return ctx, nil +} + +func (z *zapHook) After(ctx context.Context, query string, args ...interface{}) (context.Context, error) { + if z == nil || z.Helper == nil { + return ctx, nil + } + + var durationField string + if v, ok := ctx.Value((*sqlDurationKey)(nil)).(time.Time); ok { + durationField = fmt.Sprintf("%v", time.Now().Sub(v)) + } + + z.Debugf("SQL 执行后: %v 耗时: %v 秒", buildQueryArgsFields(query, args...), durationField) + return ctx, nil +} + +func (z *zapHook) OnError(_ context.Context, err error, query string, args ...interface{}) error { + if z == nil || z.Helper == nil { + return nil + } + z.Errorf("SQL 执行出错日志 %v 豹错为: %v", buildQueryArgsFields(query, args...), err) + return nil +} diff --git a/dice/model/sqlhook_cgo.go b/dice/model/sqlhook_cgo.go new file mode 100644 index 00000000..158b71e5 --- /dev/null +++ b/dice/model/sqlhook_cgo.go @@ -0,0 +1,83 @@ +//go:build cgo +// +build cgo + +package model + +import ( + "context" + "database/sql" + "fmt" + "time" + + "github.com/mattn/go-sqlite3" + "github.com/qustavo/sqlhooks/v2" + + log "sealdice-core/utils/kratos" +) + +// 覆盖驱动名 sqlite3 会导致 panic, 因此需要创建新的驱动. +// +// database/sql/sql.go:51 +const zapDriverName = "sqlite3-log" + +func InitZapHook(log *log.Helper) { + hook := &zapHook{Helper: log, IsPrintSQLDuration: true} + sql.Register(zapDriverName, sqlhooks.Wrap(new(sqlite3.SQLiteDriver), hook)) +} + +// make sure zapHook implement all sqlhooks interface. +var _ interface { + sqlhooks.Hooks + sqlhooks.OnErrorer +} = (*zapHook)(nil) + +// zapHook 使用 zap 记录 SQL 查询和参数 +type zapHook struct { + *log.Helper + + // 是否打印 SQL 耗时 + IsPrintSQLDuration bool +} + +// sqlDurationKey 是 context.valueCtx Key +type sqlDurationKey struct{} + +func buildQueryArgsFields(query string, args ...interface{}) []interface{} { + if len(args) == 0 { + return []interface{}{"查询", query} + } + return []interface{}{"查询", query, "参数", args} +} + +func (z *zapHook) Before(ctx context.Context, _ string, _ ...interface{}) (context.Context, error) { + if z == nil || z.Helper == nil { + return ctx, nil + } + + if z.IsPrintSQLDuration { + ctx = context.WithValue(ctx, (*sqlDurationKey)(nil), time.Now()) + } + return ctx, nil +} + +func (z *zapHook) After(ctx context.Context, query string, args ...interface{}) (context.Context, error) { + if z == nil || z.Helper == nil { + return ctx, nil + } + + var durationField string + if v, ok := ctx.Value((*sqlDurationKey)(nil)).(time.Time); ok { + durationField = fmt.Sprintf("%v", time.Now().Sub(v)) + } + + z.Debugf("SQL 执行后: %v 耗时: %v 秒", buildQueryArgsFields(query, args...), durationField) + return ctx, nil +} + +func (z *zapHook) OnError(_ context.Context, err error, query string, args ...interface{}) error { + if z == nil || z.Helper == nil { + return nil + } + z.Errorf("SQL 执行出错日志 %v 豹错为: %v", buildQueryArgsFields(query, args...), err) + return nil +} diff --git a/go.mod b/go.mod index eeab74ae..7d451907 100644 --- a/go.mod +++ b/go.mod @@ -140,6 +140,7 @@ require ( 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.8.1 // indirect + github.com/qustavo/sqlhooks/v2 v2.1.0 // 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 diff --git a/go.sum b/go.sum index 4699e97c..606be659 100644 --- a/go.sum +++ b/go.sum @@ -138,6 +138,7 @@ github.com/go-resty/resty/v2 v2.11.0 h1:i7jMfNOJYMp69lq7qozJP+bjgzfAzeOhuGlyDrqx github.com/go-resty/resty/v2 v2.11.0/go.mod h1:iiP/OpA0CkcL3IGt1O0+/SIItFUbkkyw5BGXiVdTu+A= github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU= github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= +github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= @@ -238,6 +239,7 @@ github.com/labstack/echo/v4 v4.12.0 h1:IKpw49IMryVB2p1a4dzwlhP1O2Tf2E0Ir/450lH+k github.com/labstack/echo/v4 v4.12.0/go.mod h1:UP9Cr2DJXbOK3Kr9ONYzNowSh7HP0aG0ShAyycHSJvM= github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0= github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU= +github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lonelyevil/kook v0.0.29/go.mod h1:WjHC7AmbmNjInT/U/etBVOmAw7T6EqdCwApceRGs1sk= @@ -256,6 +258,7 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= 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.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= 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= @@ -294,6 +297,7 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/open-dingtalk/dingtalk-stream-sdk-go v0.9.0 h1:DL64ORGMk6AUB8q5LbRp8KRFn4oHhdrSepBmbMrtmNo= github.com/open-dingtalk/dingtalk-stream-sdk-go v0.9.0/go.mod h1:ln3IqPYYocZbYvl9TAOrG/cxGR9xcn4pnZRLdCTEGEU= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/otiai10/copy v1.14.0 h1:dCI/t1iTdYGtkvCuBG2BgR6KZa83PTclw4U5n2wAllU= github.com/otiai10/copy v1.14.0/go.mod h1:ECfuL02W+/FkTWZWgQqXPWZgW9oeKCSQ5qVfSc4qc4w= github.com/otiai10/mint v1.5.1 h1:XaPLeE+9vGbuyEHem1JNk3bYc7KKqyI/na0/mLd/Kks= @@ -314,6 +318,8 @@ 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= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/qustavo/sqlhooks/v2 v2.1.0 h1:54yBemHnGHp/7xgT+pxwmIlMSDNYKx5JW5dfRAiCZi0= +github.com/qustavo/sqlhooks/v2 v2.1.0/go.mod h1:aMREyKo7fOKTwiLuWPsaHRXEmtqG4yREztO0idF83AU= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/richardlehane/mscfb v1.0.4 h1:WULscsljNPConisD5hR0+OyZjwK46Pfyr6mPu5ZawpM= diff --git a/main.go b/main.go index 7535dfa6..974d15c1 100644 --- a/main.go +++ b/main.go @@ -205,6 +205,8 @@ func main() { paniclog.InitPanicLog() // 3. 提示日志打印 log.Info("运行日志开始记录,海豹出现故障时可查看 data/main.log 与 data/panic.log 获取更多信息") + logger := log.NewCustomHelper("SQLX", false, nil) + model.InitZapHook(logger) judge, osr := oschecker.OldVersionCheck() // 预留收集信息的接口,如果有需要可以考虑从这里拿数据。不从这里做提示的原因是Windows和Linux的展示方式不同。 if judge { From d5837287557f7f05c72712ddd7848dabeb8c75a9 Mon Sep 17 00:00:00 2001 From: Pinenutn <1101839859@qq.com> Date: Sun, 20 Oct 2024 00:25:30 +0800 Subject: [PATCH 10/12] lint happy. --- dice/model/sqlhook.go | 2 +- dice/model/sqlhook_cgo.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dice/model/sqlhook.go b/dice/model/sqlhook.go index 88a1c8df..81dd0b78 100644 --- a/dice/model/sqlhook.go +++ b/dice/model/sqlhook.go @@ -67,7 +67,7 @@ func (z *zapHook) After(ctx context.Context, query string, args ...interface{}) var durationField string if v, ok := ctx.Value((*sqlDurationKey)(nil)).(time.Time); ok { - durationField = fmt.Sprintf("%v", time.Now().Sub(v)) + durationField = fmt.Sprintf("%v", time.Since(v)) } z.Debugf("SQL 执行后: %v 耗时: %v 秒", buildQueryArgsFields(query, args...), durationField) diff --git a/dice/model/sqlhook_cgo.go b/dice/model/sqlhook_cgo.go index 158b71e5..1a01cffc 100644 --- a/dice/model/sqlhook_cgo.go +++ b/dice/model/sqlhook_cgo.go @@ -67,7 +67,7 @@ func (z *zapHook) After(ctx context.Context, query string, args ...interface{}) var durationField string if v, ok := ctx.Value((*sqlDurationKey)(nil)).(time.Time); ok { - durationField = fmt.Sprintf("%v", time.Now().Sub(v)) + durationField = fmt.Sprintf("%v", time.Since(v)) } z.Debugf("SQL 执行后: %v 耗时: %v 秒", buildQueryArgsFields(query, args...), durationField) From c2e4d12600239db6cc056767aba548006069cef7 Mon Sep 17 00:00:00 2001 From: PaienNate <68044286+PaienNate@users.noreply.github.com> Date: Sun, 20 Oct 2024 22:59:43 +0800 Subject: [PATCH 11/12] Update dice/model/sqlhook.go Co-authored-by: JustAnotherID --- dice/model/sqlhook.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dice/model/sqlhook.go b/dice/model/sqlhook.go index 81dd0b78..a01464e7 100644 --- a/dice/model/sqlhook.go +++ b/dice/model/sqlhook.go @@ -78,6 +78,6 @@ func (z *zapHook) OnError(_ context.Context, err error, query string, args ...in if z == nil || z.Helper == nil { return nil } - z.Errorf("SQL 执行出错日志 %v 豹错为: %v", buildQueryArgsFields(query, args...), err) + z.Debugf("SQL 执行出错日志 %v 报错为: %v", buildQueryArgsFields(query, args...), err) return nil } From 04c32bddaa904ce36e136b3a4e5074733f639df4 Mon Sep 17 00:00:00 2001 From: PaienNate <68044286+PaienNate@users.noreply.github.com> Date: Sun, 20 Oct 2024 22:59:49 +0800 Subject: [PATCH 12/12] Update dice/model/sqlhook_cgo.go Co-authored-by: JustAnotherID --- dice/model/sqlhook_cgo.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dice/model/sqlhook_cgo.go b/dice/model/sqlhook_cgo.go index 1a01cffc..6bd11479 100644 --- a/dice/model/sqlhook_cgo.go +++ b/dice/model/sqlhook_cgo.go @@ -78,6 +78,6 @@ func (z *zapHook) OnError(_ context.Context, err error, query string, args ...in if z == nil || z.Helper == nil { return nil } - z.Errorf("SQL 执行出错日志 %v 豹错为: %v", buildQueryArgsFields(query, args...), err) + z.Debugf("SQL 执行出错日志 %v 报错为: %v", buildQueryArgsFields(query, args...), err) return nil }