feat(log): Seq 会话追踪、控制台降噪与推送质量增强

请求日志自动带 sid/request_id,支持 LogBind;挂 Seq 后控制台仅 Warn+,Seq 仍全量;并修毫秒时间戳、@m、失败重试与停机 flush。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-23 05:26:44 +08:00
parent b254606003
commit 831a7f017a
6 changed files with 554 additions and 197 deletions
+32 -16
View File
@@ -6,19 +6,20 @@ import (
"io"
"mime/multipart"
"net/http"
"strings"
"sync"
"time"
. "code.hoteas.com/golang/hotime/common"
. "code.hoteas.com/golang/hotime/db"
htlog "code.hoteas.com/golang/hotime/log"
)
type Context struct {
*Application
Resp http.ResponseWriter
Req *http.Request
Log Map //日志有则创建
Log Map //业务 logs 表字段(有则写入),与 Logger 不同
Logger *htlog.Logger // 请求级日志(带 sid/request_id),业务与 SQL 共用
RouterString []string
Config Map
Db *HoTimeDB
@@ -60,7 +61,7 @@ func (that *Context) Display(statu int, data interface{}) {
//兼容android等需要json转对象的服务
resp["error"] = temp
that.Application.Log.Warn().Int("status", statu).Msg(resp.ToJsonString())
that.reqLogger().Warn().Int("status", statu).Msg(resp.ToJsonString())
} else {
resp["result"] = data
@@ -71,6 +72,33 @@ func (that *Context) Display(statu int, data interface{}) {
//that.Data=d;
}
// reqLogger 返回请求级 Loggernil 时回退 Application.Log
func (that *Context) reqLogger() *htlog.Logger {
if that.Logger != nil {
return that.Logger
}
if that.Application != nil {
return that.Application.Log
}
return nil
}
// LogBind 为本请求追加自定义日志字段(如 user_id),后续业务日志与 SQL 日志均携带。
// 供 main.go 的 connectListener 调用;nil 安全。
func (that *Context) LogBind(key string, value interface{}) {
if that == nil || key == "" {
return
}
base := that.reqLogger()
if base == nil {
return
}
that.Logger = base.WithFields(key, ObjToStr(value))
if that.Db != nil {
that.Db.Log = that.Logger
}
}
func (that *Context) View() {
if that.RespFunc != nil {
that.RespFunc()
@@ -87,19 +115,7 @@ func (that *Context) View() {
if that.Session("user_id").Data != nil {
that.Log["user_id"] = that.Session("user_id").ToCeilInt()
}
//负载均衡优化
ipStr := ""
if that.Req.Header.Get("X-Forwarded-For") != "" {
ipStr = that.Req.Header.Get("X-Forwarded-For")
} else if that.Req.Header.Get("X-Real-IP") != "" {
ipStr = that.Req.Header.Get("X-Real-IP")
}
//负载均衡优化
if ipStr == "" {
//RemoteAddr := that.Req.RemoteAddr
ipStr = Substr(that.Req.RemoteAddr, 0, strings.Index(that.Req.RemoteAddr, ":"))
}
that.Log["ip"] = ipStr
that.Log["ip"] = clientIP(that.Req)
that.Db.Insert("logs", that.Log)
}