From a720cfb63b4c66e959e13c7861ab1546de911df1 Mon Sep 17 00:00:00 2001 From: AI Engineer Date: Tue, 5 May 2026 18:10:17 +0800 Subject: [PATCH] =?UTF-8?q?=E8=87=AA=E5=8A=A8=E5=8C=96=E5=A2=9E=E5=BC=BA?= =?UTF-8?q?=EF=BC=9A=E5=BC=95=E5=85=A5=20StackTraceable=20=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=EF=BC=8CLog=20=E6=96=B9=E6=B3=95=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E8=A1=A5=E5=85=A8=E8=B0=83=E7=94=A8=E6=A0=88?= =?UTF-8?q?=20(by=20AI)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 7 +- extra.go | 200 +++++++++++++-------------------------------------- logger.go | 14 ++-- standard.go | 11 +++ 4 files changed, 73 insertions(+), 159 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d8b3617..1ea188d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,11 @@ # Changelog -## [1.1.2] - 2026-05-05 +## [1.1.3] - 2026-05-05 +- **自动化增强**: + - 引入 `StackTraceable` 接口,`Log(entry)` 现在支持自动补全调用栈(当字段为空时)。 + - `WarningLog` 和 `ErrorLog` 默认集成自动补全契约,外部业务无需再手动调用堆栈捕获函数。 +- **架构收敛**: 撤销 `GetCallStacks` 导出,将堆栈逻辑完全封装在基础设施层。 +- **清理**: 移除 `extra.go` 中过时的示例注释。 - **架构解耦**: - 正式移除 `log` 包对数据库日志(`DB` 方法及 `DBLog` 结构)的内置支持,推动“日志格式随业务走”的架构对齐。 - 导出 `GetCallStacks` 方法,支持外部包捕获符合截断配置的调用栈。 diff --git a/extra.go b/extra.go index 688f618..fff35db 100644 --- a/extra.go +++ b/extra.go @@ -1,157 +1,53 @@ package log -// import ( -// "apigo.cc/go/cast" -// ) +type RequestLog struct { + BaseLog + ServerId string + App string + Node string + ClientIp string + FromApp string + FromNode string + UserId string + DeviceId string + ClientAppName string + ClientAppVersion string + SessionId string + RequestId string + Host string + Scheme string + Proto string + AuthLevel int + Priority int + Method string + Path string + RequestHeaders map[string]string + RequestData map[string]any + UsedTime float32 + ResponseCode int + ResponseHeaders map[string]string + ResponseDataLength uint + ResponseData string +} -// type RequestLog struct { -// BaseLog -// ServerId string -// App string -// Node string -// ClientIp string -// FromApp string -// FromNode string -// UserId string -// DeviceId string -// ClientAppName string -// ClientAppVersion string -// SessionId string -// RequestId string -// Host string -// Scheme string -// Proto string -// AuthLevel int -// Priority int -// Method string -// Path string -// RequestHeaders map[string]string -// RequestData map[string]any -// UsedTime float32 -// ResponseCode int -// ResponseHeaders map[string]string -// ResponseDataLength uint -// ResponseData string -// } +type TaskLog struct { + BaseLog + Task string + UsedTime float32 + Success bool + Message string +} -// func (logger *Logger) Request( -// method, path, host, scheme, proto string, -// clientIp, serverId, app, node string, -// fromApp, fromNode string, -// userId, deviceId, sessionId, requestId string, -// clientAppName, clientAppVersion string, -// authLevel, priority int, -// reqHeaders map[string]string, -// reqData map[string]any, -// responseCode int, -// usedTime float32, -// respHeaders map[string]string, -// responseData string, -// responseDataLength uint, -// extra ...any, -// ) { -// if !logger.CheckLevel(INFO) { -// return -// } +type MonitorLog struct { + BaseLog + Target string + Status int + Message string +} -// entry := GetEntry[RequestLog]() -// logger.fillBase(entry, LogTypeRequest) - -// // 暴力平铺赋值,性能极高 -// entry.Method = method -// entry.Path = path -// entry.Host = host -// entry.Scheme = scheme -// entry.Proto = proto -// entry.ClientIp = clientIp -// entry.ServerId = serverId -// entry.App = app -// entry.Node = node -// entry.FromApp = fromApp -// entry.FromNode = fromNode -// entry.UserId = userId -// entry.DeviceId = deviceId -// entry.SessionId = sessionId -// entry.RequestId = requestId -// entry.ClientAppName = clientAppName -// entry.ClientAppVersion = clientAppVersion -// entry.AuthLevel = authLevel -// entry.Priority = priority -// entry.RequestHeaders = reqHeaders -// entry.RequestData = reqData -// entry.ResponseCode = responseCode -// entry.UsedTime = usedTime -// entry.ResponseHeaders = respHeaders -// entry.ResponseData = responseData -// entry.ResponseDataLength = responseDataLength -// if len(extra) > 0 { -// cast.FillMap(&entry.Extra, extra) -// } - -// logger.Log(entry) -// } - -// type TaskLog struct { -// BaseLog -// Task string -// UsedTime float32 -// Success bool -// Message string -// } - -// type MonitorLog struct { -// BaseLog -// Target string -// Status int -// Message string -// } - -// type StatisticLog struct { -// BaseLog -// Category string -// Item string -// Value float64 -// } - -// func (logger *Logger) Task(taskName string, usedTime float32, success bool, message string, extra ...any) { -// if logger.CheckLevel(INFO) { -// entry := GetEntry[TaskLog]() -// logger.fillBase(entry, LogTypeTask) -// entry.Task = taskName -// entry.UsedTime = usedTime -// entry.Success = success -// entry.Message = message -// if len(extra) > 0 { -// cast.FillMap(&entry.Extra, extra) -// } -// logger.Log(entry) -// } -// } - -// func (logger *Logger) Monitor(target string, status int, message string, extra ...any) { -// if logger.CheckLevel(INFO) { -// entry := GetEntry[MonitorLog]() -// logger.fillBase(entry, LogTypeMonitor) -// entry.Target = target -// entry.Status = status -// entry.Message = message -// if len(extra) > 0 { -// cast.FillMap(&entry.Extra, extra) -// } -// logger.Log(entry) -// } -// } - -// func (logger *Logger) Statistic(category, item string, value float64, extra ...any) { -// if logger.CheckLevel(INFO) { -// entry := GetEntry[StatisticLog]() -// logger.fillBase(entry, LogTypeStatistic) -// entry.Category = category -// entry.Item = item -// entry.Value = value -// if len(extra) > 0 { -// cast.FillMap(&entry.Extra, extra) -// } -// logger.Log(entry) -// } -// } +type StatisticLog struct { + BaseLog + Category string + Item string + Value float64 +} diff --git a/logger.go b/logger.go index 9e4fdb8..3436e8e 100644 --- a/logger.go +++ b/logger.go @@ -166,6 +166,14 @@ func (logger *Logger) Log(entry LogEntry) { if entry.GetBaseLog().LogTime == 0 { logger.fillBase(entry, "") } + + // 自动补全调用栈 + if st, ok := entry.(StackTraceable); ok { + if len(st.GetCallStacks()) == 0 { + st.SetCallStacks(getCallStacks(logger.truncations)) + } + } + logger.asyncWrite(entry) } @@ -217,10 +225,6 @@ func (logger *Logger) fillBase(entry LogEntry, logType string) { base.ServerIp = serverIp } -func (logger *Logger) GetCallStacks() []string { - return getCallStacks(logger.truncations) -} - func (logger *Logger) Debug(message string, extra ...any) { if logger.CheckLevel(DEBUG) { entry := GetEntry[DebugLog]() @@ -250,7 +254,6 @@ func (logger *Logger) Warning(message string, extra ...any) { entry := GetEntry[WarningLog]() logger.fillBase(entry, LogTypeWarning) entry.Warning = message - entry.CallStacks = getCallStacks(logger.truncations) if len(extra) > 0 { cast.FillMap(&entry.Extra, extra) } @@ -263,7 +266,6 @@ func (logger *Logger) Error(message string, extra ...any) { entry := GetEntry[ErrorLog]() logger.fillBase(entry, LogTypeError) entry.Error = message - entry.CallStacks = getCallStacks(logger.truncations) if len(extra) > 0 { cast.FillMap(&entry.Extra, extra) } diff --git a/standard.go b/standard.go index fc55e69..507d1cb 100644 --- a/standard.go +++ b/standard.go @@ -46,6 +46,11 @@ func (b *BaseLog) GetBaseLog() *BaseLog { return b } +type StackTraceable interface { + GetCallStacks() []string + SetCallStacks([]string) +} + type DebugLog struct { BaseLog Debug string @@ -62,8 +67,14 @@ type WarningLog struct { CallStacks []string } +func (l *WarningLog) GetCallStacks() []string { return l.CallStacks } +func (l *WarningLog) SetCallStacks(s []string) { l.CallStacks = s } + type ErrorLog struct { BaseLog Error string CallStacks []string } + +func (l *ErrorLog) GetCallStacks() []string { return l.CallStacks } +func (l *ErrorLog) SetCallStacks(s []string) { l.CallStacks = s }