优化抖动幅度和日志双时间显示

- jitterDuration 抖动从 base/3 降至 base/10,避免过大的随机延迟
- 日志新增斗鱼双时间显示:本地时间后追加 (D斗鱼时间),前端蓝色高亮
- 时间校准后自动同步斗鱼偏移量到日志模块
This commit is contained in:
yml2213
2026-06-27 16:39:23 +08:00
parent 8029333613
commit 99885c1ddd
5 changed files with 42 additions and 7 deletions
+3 -2
View File
@@ -86,8 +86,9 @@ func (a *App) startup(ctx context.Context) {
logger.LogEvent("图片", "warn", "成功图片目录创建失败,图片保存功能可能不可用: %v", err)
}
if serverTime, err := a.client.ServerTime(); err == nil {
logger.LogEvent("时间", "success", "服务端时间获取成功: %s", serverTime.In(constants.CST).Format("2006-01-02 15:04:05.000"))
if sample, err := a.client.ServerTimeSample(); err == nil {
logger.SetDouyuOffset(sample.Offset)
logger.LogEvent("时间", "success", "服务端时间获取成功: %s", sample.EstimatedServerNow().In(constants.CST).Format("2006-01-02 15:04:05.000"))
} else {
logger.LogEvent("时间", "error", "服务端时间获取失败: %v", err)
}
+8
View File
@@ -157,6 +157,7 @@ const handleVerify = async () => {
<template v-if="log.source === 'server'">
<span class="log-prefix">[后端]</span>
<span v-if="log.time" class="log-time">[{{ log.time }}]</span>
<span v-if="log.douyuTime" class="log-douyu-time">D:{{ log.douyuTime }}</span>
<span v-if="log.category" class="log-cat">{{ log.category }}</span>
<span v-if="log.account" class="log-account">{{ log.account }}</span>
<span class="log-msg">{{ log.message }}</span>
@@ -363,6 +364,13 @@ const handleVerify = async () => {
font-size: 10px;
}
.log-douyu-time {
color: var(--accent);
flex-shrink: 0;
font-size: 10px;
font-weight: 600;
}
.log-cat {
display: inline-block;
padding: 0 4px;
+10
View File
@@ -12,6 +12,7 @@ export interface LogEntry {
export interface LogMessage {
time: string
douyuTime?: string
type: 's' | 'e' | 'i' | 'w' | 'd'
message: string
category?: string
@@ -40,8 +41,15 @@ const formatServerLogTime = (time: string): string => {
return match ? match[0] : value
}
// 从消息中提取斗鱼时间 (D16:25:00.047)
const extractDouyuTime = (message: string): string => {
const match = String(message || '').match(/\(D(\d{2}:\d{2}:\d{2}\.\d{3})\)/)
return match ? match[1] : ''
}
const cleanServerLogMessage = (message: string): string => {
return String(message || '')
.replace(/^\d{4}\/\d{2}\/\d{2}\s+\d{2}:\d{2}:\d{2}(?:\.\d{3})?\s*\(D\d{2}:\d{2}:\d{2}\.\d{3}\)\s*/i, '')
.replace(/^\d{4}\/\d{2}\/\d{2}\s+\d{2}:\d{2}:\d{2}(?:\.\d{3})?\s*/i, '')
.replace(/\[[^\]]+\]\[(debug|info|success|warn|error)\]\s*/i, '')
.replace(/^\[账号:[^\]]+\]\s*/i, '')
@@ -97,9 +105,11 @@ export function useLogs() {
// 清理后端结构化前缀,时间/分类/账号由独立字段展示。
const cleanMsg = cleanServerLogMessage(item.message)
const dyTime = extractDouyuTime(item.message)
logs.value.push({
time: formatServerLogTime(item.time || ''),
douyuTime: dyTime || undefined,
type,
message: cleanMsg,
category: item.category,
+19 -3
View File
@@ -23,11 +23,18 @@ const (
// minLevel 日志最低等级,低于此等级的日志不输出。0=info, 1=warn, 2=error。
var minLevel atomic.Int32
var douyuOffset atomic.Int64
// SetMinLevel 设置日志最低显示等级。
func SetMinLevel(level string) {
minLevel.Store(int32(levelPriority(level)))
}
// SetDouyuOffset 设置斗鱼服务端时间与本地时间的偏移量,用于日志双时间显示。
func SetDouyuOffset(offset time.Duration) {
douyuOffset.Store(int64(offset))
}
func levelPriority(level string) int {
switch strings.ToLower(level) {
case "debug":
@@ -192,10 +199,19 @@ func logStructuredEvent(category, level, account, format string, args ...any) {
func formatLogLine(now time.Time, category, level, account, message string) string {
ts := now.In(constants.CST).Format(logTimeLayout)
if account != "" {
return fmt.Sprintf("%s [%s][%s][账号:%s] %s", ts, category, level, account, message)
offset := time.Duration(douyuOffset.Load())
var prefix string
if offset != 0 {
dyTime := now.Add(offset)
prefix = fmt.Sprintf("%s(D%02d:%02d:%02d.%03d) ", ts,
dyTime.Hour(), dyTime.Minute(), dyTime.Second(), dyTime.Nanosecond()/1e6)
} else {
prefix = ts + " "
}
return fmt.Sprintf("%s [%s][%s] %s", ts, category, level, message)
if account != "" {
return fmt.Sprintf("%s[%s][%s][账号:%s] %s", prefix, category, level, account, message)
}
return fmt.Sprintf("%s[%s][%s] %s", prefix, category, level, message)
}
// LogMeta 是从日志文本中解析出的结构化信息。
+2 -2
View File
@@ -644,8 +644,7 @@ func jitterDuration(base time.Duration) time.Duration {
if base <= 0 {
return 0
}
// 加一点抖动,避免所有机器严格同频请求。
jitter := time.Duration(rand.Int63n(int64(base / 3)))
jitter := time.Duration(rand.Int63n(int64(base / 10)))
return base + jitter
}
@@ -858,6 +857,7 @@ func (s *Scheduler) calibrateDouyuTime(label string) types.TimeCalibration {
if err != nil {
logger.LogEvent("时间", "warn", "%s校准降级: %v", label, err)
}
logger.SetDouyuOffset(calibration.Offset)
logger.LogEvent("时间", "success", "%s校准完成: 斗鱼估算=%s 偏移=%dms 误差<=%dms RTT=%dms 采样=%d 来源=%s",
label,
calibration.EstimatedServerNow().In(constants.CST).Format("2006-01-02 15:04:05.000"),