Compare commits

..

2 Commits

Author SHA1 Message Date
AI Engineer
8a44c1ace6 temp version for new plan 2026-05-05 20:35:27 +08:00
AI Engineer
b2f91d37be temp version for new plan 2026-05-05 20:35:15 +08:00
5 changed files with 187 additions and 89 deletions

View File

@ -1,11 +1,6 @@
# Changelog
## [1.1.3] - 2026-05-05
- **自动化增强**:
- 引入 `StackTraceable` 接口,`Log(entry)` 现在支持自动补全调用栈(当字段为空时)。
- `WarningLog``ErrorLog` 默认集成自动补全契约,外部业务无需再手动调用堆栈捕获函数。
- **架构收敛**: 撤销 `GetCallStacks` 导出,将堆栈逻辑完全封装在基础设施层。
- **清理**: 移除 `extra.go` 中过时的示例注释。
## [1.1.2] - 2026-05-05
- **架构解耦**:
- 正式移除 `log` 包对数据库日志(`DB` 方法及 `DBLog` 结构)的内置支持,推动“日志格式随业务走”的架构对齐。
- 导出 `GetCallStacks` 方法,支持外部包捕获符合截断配置的调用栈。

200
extra.go
View File

@ -1,53 +1,157 @@
package log
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
}
// import (
// "apigo.cc/go/cast"
// )
type TaskLog struct {
BaseLog
Task string
UsedTime float32
Success bool
Message 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 MonitorLog struct {
BaseLog
Target string
Status int
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 StatisticLog struct {
BaseLog
Category string
Item string
Value float64
}
// 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)
// }
// }

View File

@ -47,6 +47,7 @@ func TestDesensitization(t *testing.T) {
}
entry := log.GetEntry[MyLog]()
logger.FillBase(entry, "test")
entry.Phone = "13812345678"
logger.Log(entry) // 应该在输出中脱敏
}
@ -57,7 +58,7 @@ func TestDBLog(t *testing.T) {
})
entry := log.GetEntry[DBEntry]()
entry.LogType = "db"
logger.FillBase(entry, "db")
entry.DbType = "mysql"
entry.Query = "SELECT * FROM users"
entry.UsedTime = 10.5
@ -70,7 +71,7 @@ func TestRequestLog(t *testing.T) {
})
entry := log.GetEntry[RequestEntry]()
entry.LogType = "request"
logger.FillBase(entry, "request")
entry.Method = "GET"
entry.Path = "/api/user"
entry.ResponseCode = 200

View File

@ -161,19 +161,6 @@ func NewLogger(conf Config) *Logger {
}
func (logger *Logger) Log(entry LogEntry) {
// 如果是自动生成的 LogType如 Debug/Info/Warning/Error 对应的类型),这里通常已经在方法内 fillBase 了
// 但对于像 discover.Log 这样直接调用 Log(entry) 的,需要在这里补全
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)
}
@ -207,7 +194,7 @@ func (logger *Logger) writeBuf(buf []byte) {
}
}
func (logger *Logger) fillBase(entry LogEntry, logType string) {
func (logger *Logger) FillBase(entry LogEntry, logType string) {
base := entry.GetBaseLog()
if base == nil {
return
@ -225,11 +212,36 @@ func (logger *Logger) fillBase(entry LogEntry, logType string) {
base.ServerIp = serverIp
}
func (logger *Logger) FillDebug(entry *DebugLog, message string) {
logger.FillBase(entry, LogTypeDebug)
entry.Debug = message
}
func (logger *Logger) FillInfo(entry *InfoLog, message string) {
logger.FillBase(entry, LogTypeInfo)
entry.Info = message
}
func (logger *Logger) FillWarning(entry *WarningLog, message string) {
logger.FillBase(entry, LogTypeWarning)
entry.Warning = message
entry.CallStacks = getCallStacks(logger.truncations)
}
func (logger *Logger) FillError(entry *ErrorLog, message string) {
logger.FillBase(entry, LogTypeError)
entry.Error = message
entry.CallStacks = getCallStacks(logger.truncations)
}
func (logger *Logger) GetCallStacks() []string {
return getCallStacks(logger.truncations)
}
func (logger *Logger) Debug(message string, extra ...any) {
if logger.CheckLevel(DEBUG) {
entry := GetEntry[DebugLog]()
logger.fillBase(entry, LogTypeDebug)
entry.Debug = message
logger.FillDebug(entry, message)
if len(extra) > 0 {
cast.FillMap(&entry.Extra, extra)
}
@ -240,8 +252,7 @@ func (logger *Logger) Debug(message string, extra ...any) {
func (logger *Logger) Info(message string, extra ...any) {
if logger.CheckLevel(INFO) {
entry := GetEntry[InfoLog]()
logger.fillBase(entry, LogTypeInfo)
entry.Info = message
logger.FillInfo(entry, message)
if len(extra) > 0 {
cast.FillMap(&entry.Extra, extra)
}
@ -252,8 +263,7 @@ func (logger *Logger) Info(message string, extra ...any) {
func (logger *Logger) Warning(message string, extra ...any) {
if logger.CheckLevel(WARNING) {
entry := GetEntry[WarningLog]()
logger.fillBase(entry, LogTypeWarning)
entry.Warning = message
logger.FillWarning(entry, message)
if len(extra) > 0 {
cast.FillMap(&entry.Extra, extra)
}
@ -264,8 +274,7 @@ func (logger *Logger) Warning(message string, extra ...any) {
func (logger *Logger) Error(message string, extra ...any) {
if logger.CheckLevel(ERROR) {
entry := GetEntry[ErrorLog]()
logger.fillBase(entry, LogTypeError)
entry.Error = message
logger.FillError(entry, message)
if len(extra) > 0 {
cast.FillMap(&entry.Extra, extra)
}

View File

@ -46,11 +46,6 @@ func (b *BaseLog) GetBaseLog() *BaseLog {
return b
}
type StackTraceable interface {
GetCallStacks() []string
SetCallStacks([]string)
}
type DebugLog struct {
BaseLog
Debug string
@ -67,14 +62,8 @@ 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 }