新增实例槽位隔离与结构化日志,多开不再共用日志与账号
This commit is contained in:
+57
-5
@@ -14,9 +14,20 @@ import (
|
||||
"time"
|
||||
|
||||
"huya-go/internal/huya"
|
||||
"huya-go/internal/instance"
|
||||
"huya-go/internal/logger"
|
||||
"huya-go/internal/sniper"
|
||||
)
|
||||
|
||||
// closeLogger 由 logger.Init 返回;os.Exit 不会执行 defer,退出前必须显式刷盘。
|
||||
var closeLogger func()
|
||||
|
||||
const (
|
||||
categoryNet = "网络"
|
||||
categoryMonitor = "监控"
|
||||
categoryCLI = "CLI"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var (
|
||||
cmd = flag.String("cmd", "list", "命令:list/score/records/exchange/monitor")
|
||||
@@ -47,10 +58,15 @@ func main() {
|
||||
refreshSuccess = flag.Bool("refresh-after-success", true, "monitor 成功后异步刷新积分和记录")
|
||||
freqBackoffMS = flag.Int("freq-backoff", 300, "操作频繁后的账号退避毫秒")
|
||||
errorBackoffMS = flag.Int("error-backoff", 300, "请求异常后的账号退避毫秒")
|
||||
verbose = flag.Bool("v", false, "输出调试日志")
|
||||
verbose = flag.Bool("v", false, "输出调试日志(同时打印到 stderr)")
|
||||
logDir = flag.String("log-dir", "", "日志目录,默认使用应用数据目录下的 logs")
|
||||
logLevel = flag.String("log-level", "info", "日志最低等级:debug/info/warn/error")
|
||||
)
|
||||
flag.Parse()
|
||||
|
||||
initLogging(*logDir, *logLevel, *verbose)
|
||||
defer flushLogs()
|
||||
|
||||
if *sid <= 0 {
|
||||
exitErr(errors.New("必须提供有效 -sid"))
|
||||
}
|
||||
@@ -68,11 +84,13 @@ func main() {
|
||||
accounts = append(accounts, sniper.Account{UID: uid, Cookie: ck})
|
||||
}
|
||||
|
||||
logger := func(string) {}
|
||||
if *verbose {
|
||||
logger = func(msg string) { fmt.Fprintln(os.Stderr, msg) }
|
||||
clientLogger := func(msg string) {
|
||||
logger.LogEvent(categoryNet, logger.LevelDebug, "%s", msg)
|
||||
if *verbose {
|
||||
fmt.Fprintln(os.Stderr, msg)
|
||||
}
|
||||
}
|
||||
client, closeClient, err := huya.NewActivityClient(*transport, *wssHost, time.Duration(*timeoutSec)*time.Second, logger)
|
||||
client, closeClient, err := huya.NewActivityClient(*transport, *wssHost, time.Duration(*timeoutSec)*time.Second, clientLogger)
|
||||
if err != nil {
|
||||
exitErr(err)
|
||||
}
|
||||
@@ -138,6 +156,8 @@ func main() {
|
||||
outMu.Lock()
|
||||
defer outMu.Unlock()
|
||||
_ = json.NewEncoder(os.Stdout).Encode(result)
|
||||
logger.LogAccountEvent(categoryMonitor, sniper.LogLevelForCategory(result.Category), strconv.FormatInt(result.UID, 10),
|
||||
"loop=%d action=%s category=%s msg=%s error=%s", result.Loop, result.Action, result.Category, result.Message, result.Error)
|
||||
}
|
||||
cfg := sniper.Config{
|
||||
SID: int32(*sid),
|
||||
@@ -336,8 +356,40 @@ func availableScore(resp *huya.GetUserScoreResp) int64 {
|
||||
return resp.AvailableScore()
|
||||
}
|
||||
|
||||
// initLogging 初始化 CLI 日志:默认写入应用数据目录下的 logs,和 GUI 一样是
|
||||
// 结构化日志(带分类与账号标签),便于事后复盘。
|
||||
func initLogging(dir, level string, verbose bool) {
|
||||
if strings.TrimSpace(dir) == "" {
|
||||
dir = instance.DefaultLogDir()
|
||||
}
|
||||
logger.SetMinLevel(logger.LevelFromString(chooseLevel(level, verbose)))
|
||||
store := logger.NewStore(1000)
|
||||
closeFn, err := logger.Init(store, dir, "CLI", "cli", instance.DefaultDataDir())
|
||||
closeLogger = closeFn
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "日志文件不可用,仅保留在内存: %v\n", err)
|
||||
}
|
||||
}
|
||||
|
||||
func chooseLevel(level string, verbose bool) string {
|
||||
if verbose {
|
||||
return logger.LevelDebug
|
||||
}
|
||||
return level
|
||||
}
|
||||
|
||||
// flushLogs 把异步日志队列刷盘;必须在 os.Exit 之前调用。
|
||||
func flushLogs() {
|
||||
if closeLogger != nil {
|
||||
closeLogger()
|
||||
closeLogger = nil
|
||||
}
|
||||
}
|
||||
|
||||
func exitErr(err error) {
|
||||
logger.LogEvent(categoryCLI, logger.LevelError, "%v", err)
|
||||
fmt.Fprintln(os.Stderr, "错误:", err)
|
||||
flushLogs()
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user