Compare commits
9 Commits
a501f79e78
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 416e962cbf | |||
| fe1986e938 | |||
| 1b81309d82 | |||
| 9001cd0048 | |||
| 000b92ede9 | |||
| 152b1320f7 | |||
| 29cc7ca248 | |||
| 1afd71fd86 | |||
| 8944f76eb1 |
126
config.go
126
config.go
@ -14,7 +14,6 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.zhangdeman.cn/zhangdeman/consts"
|
||||
"go.uber.org/zap/zapcore"
|
||||
)
|
||||
|
||||
@ -27,43 +26,27 @@ const (
|
||||
)
|
||||
|
||||
// RotateLogConfig 日志切割的配置
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 3:08 下午 2021/1/2
|
||||
type RotateLogConfig struct {
|
||||
TimeIntervalType consts.LogSplit `json:"time_interval_type" yaml:"time_interval_type"` // 日志切割的时间间隔类型 0 - 小时 1 - 天 2 - 月 3 - 年
|
||||
TimeInterval time.Duration `json:"time_interval" yaml:"time_interval"` // 日志切割的时间间隔
|
||||
LogPath string `json:"log_path" yaml:"log_path"` // 存储日志的路径
|
||||
LogFileName string `json:"log_file_name" yaml:"log_file_name"` // 日志文件名
|
||||
DivisionChar string `json:"division_char" yaml:"division_char"` // 日志文件拼时间分隔符
|
||||
FullLogFormat string `json:"full_log_format" yaml:"full_log_format"` // 完整的日志格式
|
||||
MaxAge time.Duration `json:"max_age" yaml:"max_age"` // 日志最长保存时间
|
||||
TimeIntervalType LogSplit `json:"time_interval_type" yaml:"time_interval_type"` // 日志切割的时间间隔类型 0 - 小时 1 - 天 2 - 月 3 - 年
|
||||
TimeInterval time.Duration `json:"time_interval" yaml:"time_interval"` // 日志切割的时间间隔
|
||||
LogPath string `json:"log_path" yaml:"log_path"` // 存储日志的路径
|
||||
LogFileName string `json:"log_file_name" yaml:"log_file_name"` // 日志文件名
|
||||
DivisionChar string `json:"division_char" yaml:"division_char"` // 日志文件拼时间分隔符
|
||||
FullLogFormat string `json:"full_log_format" yaml:"full_log_format"` // 完整的日志格式
|
||||
MaxAge int64 `json:"max_age" yaml:"max_age"` // 日志最长保存时间, 单位: s
|
||||
}
|
||||
|
||||
// SetRotateLogConfigFunc 设置日志切割的选项
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 3:13 下午 2021/1/2
|
||||
type SetRotateLogConfigFunc func(rlc *RotateLogConfig)
|
||||
|
||||
// WithTimeIntervalType 设置日志切割时间间隔
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 3:34 下午 2021/1/2
|
||||
func WithTimeIntervalType(timeIntervalType consts.LogSplit) SetRotateLogConfigFunc {
|
||||
func WithTimeIntervalType(timeIntervalType LogSplit) SetRotateLogConfigFunc {
|
||||
return func(rlc *RotateLogConfig) {
|
||||
rlc.TimeIntervalType = timeIntervalType
|
||||
}
|
||||
}
|
||||
|
||||
// WithDivisionChar 设置分隔符
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 3:49 下午 2021/1/2
|
||||
func WithDivisionChar(divisionChar string) SetRotateLogConfigFunc {
|
||||
return func(rlc *RotateLogConfig) {
|
||||
rlc.DivisionChar = divisionChar
|
||||
@ -71,27 +54,22 @@ func WithDivisionChar(divisionChar string) SetRotateLogConfigFunc {
|
||||
}
|
||||
|
||||
// WithMaxAge 设置日志保存时间
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 5:03 下午 2021/1/2
|
||||
func WithMaxAge(maxAge time.Duration) SetRotateLogConfigFunc {
|
||||
func WithMaxAge(maxAge int64) SetRotateLogConfigFunc {
|
||||
return func(rlc *RotateLogConfig) {
|
||||
if maxAge <= 0 {
|
||||
maxAge = 3 * 24 * 3600 // 默认3天
|
||||
}
|
||||
rlc.MaxAge = maxAge
|
||||
}
|
||||
}
|
||||
|
||||
// NewRotateLogConfig 生成日志切割的配置
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 3:53 下午 2021/1/2
|
||||
func NewRotateLogConfig(logPath string, logFile string, option ...SetRotateLogConfigFunc) (*RotateLogConfig, error) {
|
||||
if len(logPath) == 0 || len(logFile) == 0 {
|
||||
return nil, LogPathEmptyError()
|
||||
}
|
||||
c := &RotateLogConfig{
|
||||
TimeIntervalType: consts.LogSplitHour,
|
||||
TimeIntervalType: LogSplitHour,
|
||||
LogPath: logPath,
|
||||
LogFileName: logFile,
|
||||
DivisionChar: "",
|
||||
@ -109,10 +87,6 @@ func NewRotateLogConfig(logPath string, logFile string, option ...SetRotateLogCo
|
||||
}
|
||||
|
||||
// formatConfig 格式化配置
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 4:23 下午 2021/1/2
|
||||
func formatConfig(c *RotateLogConfig) error {
|
||||
|
||||
if len(c.DivisionChar) == 0 {
|
||||
@ -132,23 +106,23 @@ func formatConfig(c *RotateLogConfig) error {
|
||||
}
|
||||
}
|
||||
|
||||
c.TimeIntervalType = consts.LogSplit(strings.ToUpper(c.TimeIntervalType.String()))
|
||||
c.TimeIntervalType = LogSplit(strings.ToUpper(c.TimeIntervalType.String()))
|
||||
if !c.TimeIntervalType.IsValid() {
|
||||
// 非法的日志切割规则,默认按天切
|
||||
c.TimeIntervalType = consts.LogSplitDay
|
||||
c.TimeIntervalType = LogSplitDay
|
||||
}
|
||||
// 生成格式化日志全路径
|
||||
switch c.TimeIntervalType {
|
||||
case consts.LogSplitHour:
|
||||
case LogSplitHour:
|
||||
c.TimeInterval = time.Hour
|
||||
c.FullLogFormat = c.LogPath + "%Y" + c.DivisionChar + "%m" + c.DivisionChar + "%d" + c.DivisionChar + "%H" + c.DivisionChar + c.LogFileName
|
||||
case consts.LogSplitDay:
|
||||
case LogSplitDay:
|
||||
c.TimeInterval = time.Hour * 24
|
||||
c.FullLogFormat = c.LogPath + "%Y" + c.DivisionChar + "%m" + c.DivisionChar + "%d" + c.DivisionChar + c.LogFileName
|
||||
case consts.LogSplitMonth:
|
||||
case LogSplitMonth:
|
||||
c.TimeInterval = time.Hour * 24 * 30
|
||||
c.FullLogFormat = c.LogPath + "%Y" + c.DivisionChar + "%m" + c.DivisionChar + c.LogFileName
|
||||
case consts.LogSplitYear:
|
||||
case LogSplitYear:
|
||||
c.TimeInterval = time.Hour * 24 * 365
|
||||
c.FullLogFormat = c.LogPath + "%Y" + c.DivisionChar + c.LogFileName
|
||||
default:
|
||||
@ -176,51 +150,31 @@ const (
|
||||
)
|
||||
|
||||
// defaultTimeEncoder 默认的时间处理
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 11:53 下午 2021/1/2
|
||||
func defaultTimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
|
||||
sec := t.UnixNano() / 1e9
|
||||
ms := t.UnixNano() / 1e6 % 1e3
|
||||
ns := t.UnixNano() % 1e6
|
||||
enc.AppendString(time.Unix(sec, ns).Format("2006-01-02 15:04:05") + "." + fmt.Sprintf("%v", ms) + "+" + fmt.Sprintf("%v", ns))
|
||||
enc.AppendString(time.Unix(sec, ns).Format(time.DateTime) + "." + fmt.Sprintf("%v", ms) + "+" + fmt.Sprintf("%v", ns))
|
||||
}
|
||||
|
||||
// SecondTimeEncoder 秒级时间戳格式化
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 8:34 下午 2021/1/3
|
||||
func SecondTimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
|
||||
enc.AppendString(t.Format("2006-01-02 15:04:05"))
|
||||
enc.AppendString(t.Format(time.DateTime))
|
||||
}
|
||||
|
||||
// MsTimeEncoder 毫秒时间格式化方法
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 8:35 下午 2021/1/3
|
||||
func MsTimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
|
||||
sec := t.UnixNano() / 1e9
|
||||
ms := t.UnixNano() / 1e6 % 1e3
|
||||
enc.AppendString(time.Unix(sec, 0).Format("2006-01-02 15:04:05") + "." + fmt.Sprintf("%v", ms))
|
||||
enc.AppendString(time.Unix(sec, 0).Format(time.DateTime) + "." + fmt.Sprintf("%v", ms))
|
||||
}
|
||||
|
||||
// defaultEncodeDuration 默认的原始时间处理
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 11:56 下午 2021/1/2
|
||||
func defaultEncodeDuration(d time.Duration, enc zapcore.PrimitiveArrayEncoder) {
|
||||
enc.AppendInt64(int64(d) / 1000000)
|
||||
}
|
||||
|
||||
// OptionLogger 日志配置的选项
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 11:41 下午 2021/1/2
|
||||
type OptionLogger struct {
|
||||
UseJsonFormat bool // 日志使用json格式
|
||||
MessageKey string // message 字段
|
||||
@ -269,10 +223,6 @@ func WithEncoder(encoder zapcore.Encoder) SetLoggerOptionFunc {
|
||||
}
|
||||
|
||||
// WithUseJsonFormat 日志是否使用json格式数据
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 12:30 上午 2021/1/3
|
||||
func WithUseJsonFormat(isJsonFormat bool) SetLoggerOptionFunc {
|
||||
return func(o *OptionLogger) {
|
||||
o.UseJsonFormat = isJsonFormat
|
||||
@ -280,10 +230,6 @@ func WithUseJsonFormat(isJsonFormat bool) SetLoggerOptionFunc {
|
||||
}
|
||||
|
||||
// WithMessageKey 使用message key
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 12:32 上午 2021/1/3
|
||||
func WithMessageKey(messageKey string) SetLoggerOptionFunc {
|
||||
return func(o *OptionLogger) {
|
||||
messageKey = strings.Trim(messageKey, " ")
|
||||
@ -295,10 +241,6 @@ func WithMessageKey(messageKey string) SetLoggerOptionFunc {
|
||||
}
|
||||
|
||||
// WithLevelKey 设置level key
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 12:33 上午 2021/1/3
|
||||
func WithLevelKey(levelKey string) SetLoggerOptionFunc {
|
||||
return func(o *OptionLogger) {
|
||||
levelKey = strings.Trim(levelKey, " ")
|
||||
@ -310,10 +252,6 @@ func WithLevelKey(levelKey string) SetLoggerOptionFunc {
|
||||
}
|
||||
|
||||
// WithTimeKey 设置time key ...
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 12:34 上午 2021/1/3
|
||||
func WithTimeKey(timeKey string) SetLoggerOptionFunc {
|
||||
return func(o *OptionLogger) {
|
||||
timeKey = strings.Trim(timeKey, " ")
|
||||
@ -325,10 +263,6 @@ func WithTimeKey(timeKey string) SetLoggerOptionFunc {
|
||||
}
|
||||
|
||||
// WithCallerKey 设置caller key
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 12:37 上午 2021/1/3
|
||||
func WithCallerKey(callerKey string) SetLoggerOptionFunc {
|
||||
return func(o *OptionLogger) {
|
||||
callerKey = strings.Trim(callerKey, " ")
|
||||
@ -340,10 +274,6 @@ func WithCallerKey(callerKey string) SetLoggerOptionFunc {
|
||||
}
|
||||
|
||||
// WithShortCaller 是否使用短caller格式
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 12:39 上午 2021/1/3
|
||||
func WithShortCaller(useShortCaller bool) SetLoggerOptionFunc {
|
||||
return func(o *OptionLogger) {
|
||||
o.UseShortCaller = useShortCaller
|
||||
@ -351,10 +281,6 @@ func WithShortCaller(useShortCaller bool) SetLoggerOptionFunc {
|
||||
}
|
||||
|
||||
// WithTimeEncoder 设置格式化时间方法
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 12:41 上午 2021/1/3
|
||||
func WithTimeEncoder(encoder zapcore.TimeEncoder) SetLoggerOptionFunc {
|
||||
return func(o *OptionLogger) {
|
||||
if nil == encoder {
|
||||
@ -365,10 +291,6 @@ func WithTimeEncoder(encoder zapcore.TimeEncoder) SetLoggerOptionFunc {
|
||||
}
|
||||
|
||||
// WithEncodeDuration 原始时间
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 12:42 上午 2021/1/3
|
||||
func WithEncodeDuration(encoder zapcore.DurationEncoder) SetLoggerOptionFunc {
|
||||
return func(o *OptionLogger) {
|
||||
if nil == encoder {
|
||||
@ -386,10 +308,6 @@ func WithZincLogCollect(zincCfg *ZincConfig) SetLoggerOptionFunc {
|
||||
}
|
||||
|
||||
// GetEncoder 获取空中台输出的encoder
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 6:24 下午 2021/1/2
|
||||
func GetEncoder(option ...SetLoggerOptionFunc) zapcore.Encoder {
|
||||
ol := &OptionLogger{
|
||||
UseJsonFormat: defaultUseJsonFormat,
|
||||
|
||||
129
consts.go
Normal file
129
consts.go
Normal file
@ -0,0 +1,129 @@
|
||||
// Package logger ...
|
||||
//
|
||||
// Description : logger ...
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 2025-10-30 17:19
|
||||
package logger
|
||||
|
||||
type LogLevel string
|
||||
|
||||
func (ll LogLevel) String() string {
|
||||
return string(ll)
|
||||
}
|
||||
|
||||
func (ll LogLevel) MarshalJSON() ([]byte, error) {
|
||||
return []byte(`"` + ll.String() + `"`), nil
|
||||
}
|
||||
|
||||
func (ll LogLevel) IsValid() bool {
|
||||
levelList := []LogLevel{
|
||||
LogLevelDebug,
|
||||
LogLevelInfo,
|
||||
LogLevelWarn,
|
||||
LogLevelError,
|
||||
LogLevelPanic,
|
||||
}
|
||||
for _, level := range levelList {
|
||||
if level == ll {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
const (
|
||||
LogLevelDebug LogLevel = "DEBUG"
|
||||
LogLevelInfo LogLevel = "INFO"
|
||||
LogLevelWarn LogLevel = "WARN"
|
||||
LogLevelError LogLevel = "ERROR"
|
||||
LogLevelPanic LogLevel = "PANIC"
|
||||
)
|
||||
|
||||
type LogSplit string
|
||||
|
||||
func (ls LogSplit) String() string {
|
||||
return string(ls)
|
||||
}
|
||||
func (ls LogSplit) MarshalJSON() ([]byte, error) {
|
||||
return []byte(`"` + ls.String() + `"`), nil
|
||||
}
|
||||
|
||||
func (ls LogSplit) IsValid() bool {
|
||||
for _, supportSplit := range SupportLogSplitList {
|
||||
if supportSplit.Value == ls || supportSplit.Value.String() == ls.String() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
const (
|
||||
LogSplitHour LogSplit = "HOUR"
|
||||
LogSplitDay LogSplit = "DAY"
|
||||
LogSplitMonth LogSplit = "MONTH"
|
||||
LogSplitYear LogSplit = "YEAR"
|
||||
)
|
||||
|
||||
type LogSplitDesc struct {
|
||||
Value LogSplit `json:"value"`
|
||||
Desc string `json:"desc"`
|
||||
}
|
||||
|
||||
var (
|
||||
SupportLogSplitList = []LogSplitDesc{
|
||||
{
|
||||
Value: LogSplitHour,
|
||||
Desc: "按小时切割",
|
||||
},
|
||||
{
|
||||
Value: LogSplitDay,
|
||||
Desc: "按天切割",
|
||||
},
|
||||
{
|
||||
Value: LogSplitMonth,
|
||||
Desc: "按月切割",
|
||||
},
|
||||
{
|
||||
Value: LogSplitYear,
|
||||
Desc: "按年切割",
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
const (
|
||||
LogPathDefault = "logs"
|
||||
)
|
||||
|
||||
const (
|
||||
LogMessageKey = "message"
|
||||
LogLevelKey = "level"
|
||||
LogTimeKey = "time"
|
||||
LogCallerKey = "caller"
|
||||
)
|
||||
|
||||
const (
|
||||
LogAccessName = "access.log"
|
||||
LogRequestName = "request.log"
|
||||
LogProxyName = "proxy.log"
|
||||
LogBusinessName = "business.log"
|
||||
LogMonitorName = "monitor.log"
|
||||
LogDatabaseName = "database.log"
|
||||
LogRateLimitName = "rate-limit.log"
|
||||
LogEventName = "event.log"
|
||||
LogCacheName = "cache.log"
|
||||
)
|
||||
|
||||
const (
|
||||
LogTypeAccess = "access" // 访问日志
|
||||
LogTypeRequest = "request" // 请求日志
|
||||
LogTypeOutput = "output" // 响应日志
|
||||
LogTypeProxy = "proxy" // 代理请求日志
|
||||
LogTypeBusiness = "business" // 业务日志
|
||||
LogTypeMonitor = "monitor" // 监控日志
|
||||
LogTypeDatabase = "database" // 数据库日志
|
||||
LogTypeRateLimit = "rate-limit" // 流控日志
|
||||
LogTypeEvent = "event" // 事件日志
|
||||
LogTypeCache = "cache" // 缓存日志
|
||||
)
|
||||
26
debug.go
26
debug.go
@ -1,26 +0,0 @@
|
||||
// Package logger...
|
||||
//
|
||||
// Description : logger...
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 2021-01-03 12:58 上午
|
||||
package logger
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
// FormatJson 格式化输出json
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 1:06 上午 2021/1/3
|
||||
func FormatJson(src any) string {
|
||||
byteData, _ := json.Marshal(src)
|
||||
|
||||
var str bytes.Buffer
|
||||
_ = json.Indent(&str, byteData, "", " ")
|
||||
return str.String()
|
||||
}
|
||||
132
define.go
132
define.go
@ -8,10 +8,15 @@
|
||||
package logger
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.zhangdeman.cn/zhangdeman/consts"
|
||||
"git.zhangdeman.cn/zhangdeman/network/util"
|
||||
"git.zhangdeman.cn/zhangdeman/serialize"
|
||||
"git.zhangdeman.cn/zhangdeman/wrapper/op_any"
|
||||
|
||||
"git.zhangdeman.cn/zhangdeman/websocket/storage"
|
||||
"go.uber.org/zap"
|
||||
@ -41,56 +46,95 @@ func GetWsLoggConnect() storage.IConnection {
|
||||
}
|
||||
|
||||
// LogData 记录日志数据
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 16:07 2024/7/23
|
||||
type LogData struct {
|
||||
Env string `json:"env"` // 运行环境
|
||||
Uri string `json:"uri"` // 请求的接口
|
||||
TraceID string `json:"trace_id"` // 请求的trace_id
|
||||
UserID string `json:"user_id"` // 用户ID
|
||||
UserRoleID string `json:"user_role_id"` // 用户角色
|
||||
OperateMode string `json:"operate_mode"` // 操作模式
|
||||
OperateMode string `json:"operate_mode"` // 操作模式(PC/APP/PAD等)
|
||||
LogType string `json:"log_type"` // 日志类型
|
||||
CodeVersion string `json:"code_version"` // 代码版本
|
||||
CodeVersion string `json:"code_version"` // 代码版本(可以设置为git commit id)
|
||||
ServiceVersion string `json:"service_version"` // 服务本身的版本
|
||||
ClientIp string `json:"client_ip"` // 客户端IP
|
||||
ServerIp string `json:"server_ip"` // 服务器IP
|
||||
Hostname string `json:"hostname"` // 服务器主机名
|
||||
Code string `json:"code"` // 日志状态码
|
||||
Code string `json:"code"` // 日志分类标记码
|
||||
Data map[string]any `json:"data"` // 扩展记录的数据, 会展开一层进行记录
|
||||
}
|
||||
|
||||
// ToFieldList 转换为 zap.Field 列表
|
||||
func (ld *LogData) ToFieldList() []zap.Field {
|
||||
var (
|
||||
fieldList []zap.Field
|
||||
mapLogData map[string]any
|
||||
)
|
||||
serialize.JSON.TransitionIgnoreError(ld, &mapLogData)
|
||||
for k, v := range mapLogData {
|
||||
fieldList = append(fieldList, zap.Any(k, v))
|
||||
}
|
||||
return fieldList
|
||||
}
|
||||
|
||||
// InputLogConfig 输入的日志配置
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 18:40 2022/6/12
|
||||
type InputLogConfig struct {
|
||||
Name string `json:"name" yaml:"name"` // 日志文件名
|
||||
Path string `json:"path" yaml:"path"` // 日志文件路径
|
||||
TimeIntervalType consts.LogSplit `json:"time_interval_type" yaml:"time_interval_type"` // 日志切割规则
|
||||
DivisionChar string `json:"division_char" yaml:"division_char"` // 文件名分隔符
|
||||
LogLevel consts.LogLevel `json:"log_level" yaml:"log_level"` // 日志等级
|
||||
Console bool `json:"console" yaml:"console"` // 是否进行控制台日志输出
|
||||
UseJson bool `json:"use_json" yaml:"use_json"` // 日志是否使用JSON格式
|
||||
FileLine bool `json:"file_line" yaml:"file_line"` // 日志是否打印行号
|
||||
MessageKey string `json:"message_key" yaml:"message_key"` // message 字段
|
||||
LevelKey string `json:"level_key" yaml:"level_key"` // level 字段
|
||||
TimeKey string `json:"time_key" yaml:"time_key"` // 时间字段
|
||||
CallerKey string `json:"caller_key" yaml:"caller_key"` // 记录日志的文件的代码行数
|
||||
UseShortFile bool `json:"use_short_file" yaml:"use_short_file"` // 是否使用短文件格式
|
||||
CallerSkip int `json:"caller_skip" yaml:"caller_skip"` // 日志记录的文件跳过多少层
|
||||
MaxAge int `json:"max_age" yaml:"max_age"` // 日志最长保存时间, 单位 : 秒
|
||||
ZincSyncConfig *ZincConfig `json:"zinc_sync_config" yaml:"zinc_sync_config"` // 日志同步至zinc的配置
|
||||
Name string `json:"name" yaml:"name"` // 日志文件名
|
||||
Path string `json:"path" yaml:"path"` // 日志文件路径
|
||||
TimeIntervalType LogSplit `json:"time_interval_type" yaml:"time_interval_type"` // 日志切割规则
|
||||
DivisionChar string `json:"division_char" yaml:"division_char"` // 文件名分隔符
|
||||
LogLevel LogLevel `json:"log_level" yaml:"log_level"` // 日志等级
|
||||
Console bool `json:"console" yaml:"console"` // 是否进行控制台日志输出
|
||||
UseJson bool `json:"use_json" yaml:"use_json"` // 日志是否使用JSON格式
|
||||
FileLine bool `json:"file_line" yaml:"file_line"` // 日志是否打印行号
|
||||
MessageKey string `json:"message_key" yaml:"message_key"` // message 字段
|
||||
LevelKey string `json:"level_key" yaml:"level_key"` // level 字段
|
||||
TimeKey string `json:"time_key" yaml:"time_key"` // 时间字段
|
||||
CallerKey string `json:"caller_key" yaml:"caller_key"` // 记录日志的文件的代码行数
|
||||
UseShortFile bool `json:"use_short_file" yaml:"use_short_file"` // 是否使用短文件格式
|
||||
CallerSkip int `json:"caller_skip" yaml:"caller_skip"` // 日志记录的文件跳过多少层
|
||||
MaxAge int64 `json:"max_age" yaml:"max_age"` // 日志最长保存时间, 单位 : 秒
|
||||
ZincSyncConfig *ZincConfig `json:"zinc_sync_config" yaml:"zinc_sync_config"` // 日志同步至zinc的配置
|
||||
}
|
||||
|
||||
// NewLogData ...
|
||||
func NewLogData(ctx context.Context, logType string, code string, logData map[string]any) *LogData {
|
||||
hostname, _ := os.Hostname()
|
||||
if nil == ctx {
|
||||
ctx = context.Background()
|
||||
}
|
||||
commonLogData := &LogData{
|
||||
Env: getStrVal(ctx, consts.GinEnvField),
|
||||
Uri: getStrVal(ctx, consts.GinRequestURIField),
|
||||
TraceID: getStrVal(ctx, consts.GinTraceIDField),
|
||||
UserID: getStrVal(ctx, consts.GinUserIDField),
|
||||
OperateMode: getStrVal(ctx, consts.GinOperateModeField),
|
||||
LogType: logType,
|
||||
CodeVersion: getStrVal(ctx, consts.GinCodeVersionField),
|
||||
ServiceVersion: getStrVal(ctx, consts.GinServiceVersionField),
|
||||
ClientIp: getStrVal(ctx, consts.GinClientIpField),
|
||||
ServerIp: util.IP.GetHostIP(),
|
||||
Hostname: hostname,
|
||||
Code: code,
|
||||
Data: logData,
|
||||
}
|
||||
return commonLogData
|
||||
}
|
||||
|
||||
func getStrVal(ctx context.Context, key string) string {
|
||||
val := ctx.Value(key)
|
||||
if nil != val {
|
||||
return op_any.AnyDataType(val).ToString()
|
||||
}
|
||||
if v := ctx.Value(consts.GinContextDataField); nil != v {
|
||||
if data, ok := v.(map[string]any); ok {
|
||||
if searchVal, exist := data[key]; exist && nil != searchVal {
|
||||
return fmt.Sprintf("%v", searchVal)
|
||||
}
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// GetLogInstanceFromInputConfig 从输入配置获取日志实例
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 18:43 2022/6/12
|
||||
func GetLogInstanceFromInputConfig(logConf *InputLogConfig) (*zap.Logger, error) {
|
||||
if nil == logConf {
|
||||
return nil, nil
|
||||
@ -117,7 +161,7 @@ func GetLogInstanceFromInputConfig(logConf *InputLogConfig) (*zap.Logger, error)
|
||||
logConf.Name,
|
||||
WithDivisionChar(logConf.DivisionChar),
|
||||
WithTimeIntervalType(logConf.TimeIntervalType),
|
||||
WithMaxAge(time.Duration(logConf.MaxAge)*time.Second)); nil != err {
|
||||
WithMaxAge(logConf.MaxAge)); nil != err {
|
||||
return nil, err
|
||||
}
|
||||
if loggerInstance, err = NewLogger(logConf.LogLevel, splitConfig, logConfList...); nil != err {
|
||||
@ -127,27 +171,23 @@ func GetLogInstanceFromInputConfig(logConf *InputLogConfig) (*zap.Logger, error)
|
||||
}
|
||||
|
||||
// inputLevel2ZapLevel 输入日志等级转化为zap日志等级
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 18:07 2024/6/24
|
||||
func inputLevel2ZapLevel(inputLoggerLevel consts.LogLevel) zapcore.Level {
|
||||
inputLoggerLevel = consts.LogLevel(strings.ToUpper(inputLoggerLevel.String()))
|
||||
func inputLevel2ZapLevel(inputLoggerLevel LogLevel) zapcore.Level {
|
||||
inputLoggerLevel = LogLevel(strings.ToUpper(inputLoggerLevel.String()))
|
||||
if !inputLoggerLevel.IsValid() {
|
||||
// 非法的日志等级, 自动重定向为 info 级别
|
||||
inputLoggerLevel = consts.LogLevelInfo
|
||||
inputLoggerLevel = LogLevelInfo
|
||||
}
|
||||
loggerLevel := zapcore.DebugLevel
|
||||
switch inputLoggerLevel {
|
||||
case consts.LogLevelDebug:
|
||||
case LogLevelDebug:
|
||||
loggerLevel = zapcore.DebugLevel
|
||||
case consts.LogLevelInfo:
|
||||
case LogLevelInfo:
|
||||
loggerLevel = zapcore.InfoLevel
|
||||
case consts.LogLevelWarn:
|
||||
case LogLevelWarn:
|
||||
loggerLevel = zapcore.WarnLevel
|
||||
case consts.LogLevelError:
|
||||
case LogLevelError:
|
||||
loggerLevel = zapcore.ErrorLevel
|
||||
case consts.LogLevelPanic:
|
||||
case LogLevelPanic:
|
||||
loggerLevel = zapcore.PanicLevel
|
||||
}
|
||||
return loggerLevel
|
||||
|
||||
24
error.go
24
error.go
@ -10,55 +10,31 @@ package logger
|
||||
import "github.com/pkg/errors"
|
||||
|
||||
// CreateLogFileError 创建日志文件失败
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 2:55 下午 2021/1/2
|
||||
func CreateLogFileError(err error, logFilePath string) error {
|
||||
return errors.Wrapf(err, "创建日志文件失败,日志文件路径 : %s", logFilePath)
|
||||
}
|
||||
|
||||
// LogPathEmptyError 日志路径为空
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 4:03 下午 2021/1/2
|
||||
func LogPathEmptyError() error {
|
||||
return errors.Wrap(errors.New("日志存储路径或者日志文件名为空"), "日志存储路径或者日志文件名为空")
|
||||
}
|
||||
|
||||
// CustomTimeIntervalError 自定义日志切割时间间隔错误
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 4:11 下午 2021/1/2
|
||||
func CustomTimeIntervalError() error {
|
||||
return errors.Wrap(errors.New("自定义时间间隔错误,必须是大于0的值"), "自定义时间间隔错误,必须是大于0的值")
|
||||
}
|
||||
|
||||
// DealLogPathError 日志路径处理异常
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 4:31 下午 2021/1/2
|
||||
func DealLogPathError(err error, logPath string) error {
|
||||
return errors.Wrapf(err, "日志路径检测处理异常, 日志路径 : %s", logPath)
|
||||
}
|
||||
|
||||
// LogSplitTypeError 日志切割类型错误
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 4:50 下午 2021/1/2
|
||||
func LogSplitTypeError(splitType string) error {
|
||||
return errors.Wrapf(errors.New("日志切割时间类型错误"), "日志切割时间类型错误, 传入类型 : %v", splitType)
|
||||
}
|
||||
|
||||
// CreateIOWriteError 创建日志实例失败
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 5:20 下午 2021/1/2
|
||||
func CreateIOWriteError(err error) error {
|
||||
return errors.Wrapf(err, "创建日志实例失败")
|
||||
}
|
||||
|
||||
51
go.mod
51
go.mod
@ -5,39 +5,37 @@ go 1.24.1
|
||||
toolchain go1.24.2
|
||||
|
||||
require (
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250816114446-59d5034e469b
|
||||
git.zhangdeman.cn/zhangdeman/network v0.0.0-20250726060351-78810e906bfa
|
||||
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20250504055908-8d68e6106ea9
|
||||
git.zhangdeman.cn/zhangdeman/websocket v0.0.0-20241125101541-c5ea194c9c1e
|
||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20250321102712-1cbfbe959740
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250916024308-d378e6c57772
|
||||
git.zhangdeman.cn/zhangdeman/network v0.0.0-20251013095944-5b89fff39bde
|
||||
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20251013044511-86c1a4a3a9dd
|
||||
git.zhangdeman.cn/zhangdeman/websocket v0.0.0-20251013144324-313024336a6f
|
||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20251014035305-c0ec06fa6dff
|
||||
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible
|
||||
github.com/pkg/errors v0.9.1
|
||||
go.uber.org/zap v1.27.0
|
||||
gorm.io/gorm v1.30.1
|
||||
)
|
||||
|
||||
require (
|
||||
git.zhangdeman.cn/zhangdeman/easylock v0.0.0-20230731062340-983985c12eda // indirect
|
||||
git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20241101082529-28a6c68e38a4 // indirect
|
||||
git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0 // indirect
|
||||
git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20251013024601-da007da2fb42 // indirect
|
||||
git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e // indirect
|
||||
github.com/BurntSushi/toml v1.5.0 // indirect
|
||||
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 // indirect
|
||||
github.com/bytedance/sonic v1.14.0 // indirect
|
||||
github.com/bytedance/sonic/loader v0.3.0 // indirect
|
||||
github.com/bytedance/gopkg v0.1.3 // indirect
|
||||
github.com/bytedance/sonic v1.14.2 // indirect
|
||||
github.com/bytedance/sonic/loader v0.4.0 // indirect
|
||||
github.com/cloudwego/base64x v0.1.6 // indirect
|
||||
github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.9 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.11 // indirect
|
||||
github.com/gin-contrib/sse v1.1.0 // indirect
|
||||
github.com/gin-gonic/gin v1.10.1 // indirect
|
||||
github.com/gin-gonic/gin v1.11.0 // indirect
|
||||
github.com/go-ini/ini v1.67.0 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.27.0 // indirect
|
||||
github.com/go-playground/validator/v10 v10.28.0 // indirect
|
||||
github.com/goccy/go-json v0.10.5 // indirect
|
||||
github.com/goccy/go-yaml v1.18.0 // indirect
|
||||
github.com/gorilla/websocket v1.5.3 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/jonboulle/clockwork v0.3.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
|
||||
@ -50,20 +48,23 @@ require (
|
||||
github.com/mozillazg/go-pinyin v0.21.0 // indirect
|
||||
github.com/mssola/user_agent v0.6.0 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
||||
github.com/quic-go/qpack v0.5.1 // indirect
|
||||
github.com/quic-go/quic-go v0.55.0 // indirect
|
||||
github.com/sbabiv/xml2map v1.2.1 // indirect
|
||||
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||
github.com/tidwall/gjson v1.18.0 // indirect
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
github.com/tidwall/pretty v1.2.1 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.3.0 // indirect
|
||||
github.com/ugorji/go/codec v1.3.1 // indirect
|
||||
go.uber.org/mock v0.6.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/arch v0.20.0 // indirect
|
||||
golang.org/x/crypto v0.41.0 // indirect
|
||||
golang.org/x/net v0.43.0 // indirect
|
||||
golang.org/x/sys v0.35.0 // indirect
|
||||
golang.org/x/text v0.28.0 // indirect
|
||||
google.golang.org/protobuf v1.36.7 // indirect
|
||||
golang.org/x/arch v0.22.0 // indirect
|
||||
golang.org/x/crypto v0.43.0 // indirect
|
||||
golang.org/x/mod v0.29.0 // indirect
|
||||
golang.org/x/net v0.46.0 // indirect
|
||||
golang.org/x/sync v0.17.0 // indirect
|
||||
golang.org/x/sys v0.37.0 // indirect
|
||||
golang.org/x/text v0.30.0 // indirect
|
||||
golang.org/x/tools v0.38.0 // indirect
|
||||
google.golang.org/protobuf v1.36.10 // indirect
|
||||
gopkg.in/olahol/melody.v1 v1.0.0-20170518105555-d52139073376 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
112
go.sum
112
go.sum
@ -1,31 +1,33 @@
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250809071206-eb75a5365406 h1:urGVIPwPjaovpdp4MpJdJqpScK9mgnKVXoXW2NwudUg=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250809071206-eb75a5365406/go.mod h1:5p8CEKGBxi7qPtTXDI3HDmqKAfIm5i/aBWdrbkbdNjc=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250816114446-59d5034e469b h1:OwAtjuvSgUxA94HYd55L6Nh2xm8atUOo3sjzEeZ0z/I=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250816114446-59d5034e469b/go.mod h1:5p8CEKGBxi7qPtTXDI3HDmqKAfIm5i/aBWdrbkbdNjc=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250916024308-d378e6c57772 h1:Yo1ur3LnDF5s7F7tpJsNrdUSF8LwYKnN9TdQU32F3eU=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250916024308-d378e6c57772/go.mod h1:5p8CEKGBxi7qPtTXDI3HDmqKAfIm5i/aBWdrbkbdNjc=
|
||||
git.zhangdeman.cn/zhangdeman/easylock v0.0.0-20230731062340-983985c12eda h1:bMD6r9gjRy7cO+T4zRQVYAesgIblBdTnhzT1vN5wjvI=
|
||||
git.zhangdeman.cn/zhangdeman/easylock v0.0.0-20230731062340-983985c12eda/go.mod h1:dT0rmHcJ9Z9IqWeMIt7YzR88nKkNV2V3dfG0j9Q6lK0=
|
||||
git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20241101082529-28a6c68e38a4 h1:s6d4b6yY+NaK1AzoBD1pxqsuygEHQz0Oie86c45geDw=
|
||||
git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20241101082529-28a6c68e38a4/go.mod h1:V4Dfg1v/JVIZGEKCm6/aehs8hK+Xow1dkL1yiQymXlQ=
|
||||
git.zhangdeman.cn/zhangdeman/network v0.0.0-20250726060351-78810e906bfa h1:r3AK2EKbQ82ShC5+AjbE95sqm90CkpbzLpmoV3zok9Q=
|
||||
git.zhangdeman.cn/zhangdeman/network v0.0.0-20250726060351-78810e906bfa/go.mod h1:v0tMMfXvE4WyUxaRo1r/D20BAbMkT5QPLSW7XtgQOxo=
|
||||
git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0 h1:gUDlQMuJ4xNfP2Abl1Msmpa3fASLWYkNlqDFF/6GN0Y=
|
||||
git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0/go.mod h1:VHb9qmhaPDAQDcS6vUiDCamYjZ4R5lD1XtVsh55KsMI=
|
||||
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20250504055908-8d68e6106ea9 h1:/GLQaFoLb+ciHOtAS2BIyPNnf4O5ME3AC5PUaJY9kfs=
|
||||
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20250504055908-8d68e6106ea9/go.mod h1:ABJ655C5QenQNOzf7LjCe4sSB52CXvaWLX2Zg4uwDJY=
|
||||
git.zhangdeman.cn/zhangdeman/network v0.0.0-20251013095944-5b89fff39bde h1:+3zIOditaUwzSpl2ybM1PYN4OYTIKiemMBt+pNv3Yko=
|
||||
git.zhangdeman.cn/zhangdeman/network v0.0.0-20251013095944-5b89fff39bde/go.mod h1:Ewh0UYOqXxEh0khgHj9bDz1rbnd7cCCsJrcOTFX/8wg=
|
||||
git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20251013024601-da007da2fb42 h1:VjYrb4adud7FHeiYS9XA0B/tOaJjfRejzQAlwimrrDc=
|
||||
git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20251013024601-da007da2fb42/go.mod h1:VHb9qmhaPDAQDcS6vUiDCamYjZ4R5lD1XtVsh55KsMI=
|
||||
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20251013044511-86c1a4a3a9dd h1:kTZOpR8iHx27sUufMWVYhDZx9Q4h80j7RWlaR8GIBiU=
|
||||
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20251013044511-86c1a4a3a9dd/go.mod h1:pLrQ63JICi81/3w2BrD26QZiu+IpddvEVfMJ6No3Xb4=
|
||||
git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e h1:Q973S6CcWr1ICZhFI1STFOJ+KUImCl2BaIXm6YppBqI=
|
||||
git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e/go.mod h1:VpPjBlwz8U+OxZuxzHQBv1aEEZ3pStH6bZvT21ADEbI=
|
||||
git.zhangdeman.cn/zhangdeman/websocket v0.0.0-20241125101541-c5ea194c9c1e h1:YE2Gi+M03UDImIpWa3I7jzSesyfu2RL8x/4ONs5v0oE=
|
||||
git.zhangdeman.cn/zhangdeman/websocket v0.0.0-20241125101541-c5ea194c9c1e/go.mod h1:L/7JugxKZL3JP9JP/XDvPAPz0FQXG1u181Su1+u/d1c=
|
||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20250321102712-1cbfbe959740 h1:zPUoylfJTbc0EcxW+NEzOTBmoeFZ2I/rLFBnEzxb4Wk=
|
||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20250321102712-1cbfbe959740/go.mod h1:1ct92dbVc49pmXusA/iGfcQUJzcYmJ+cjAhgc3sDv1I=
|
||||
git.zhangdeman.cn/zhangdeman/websocket v0.0.0-20251013144324-313024336a6f h1:InxNoLPHBLwCLblW0lsL2P1ZBYoUEzw9Yh+KNLt4Xmg=
|
||||
git.zhangdeman.cn/zhangdeman/websocket v0.0.0-20251013144324-313024336a6f/go.mod h1:Pbs7tusW6RNcqrNCVcLE2zrM8JfPaO7lBJQuRiAzzLs=
|
||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20251014035305-c0ec06fa6dff h1:ym1Qs4diJe27CK/0K6vy7RvgH90mXgslWA++L8mXaKE=
|
||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20251014035305-c0ec06fa6dff/go.mod h1:mBvTwcdqHRF3QIkAh92j/JRhru2LzyJ2LBqolxjzzKE=
|
||||
github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
|
||||
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 h1:OYA+5W64v3OgClL+IrOD63t4i/RW7RqrAVl9LTZ9UqQ=
|
||||
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394/go.mod h1:Q8n74mJTIgjX4RBBcHnJ05h//6/k6foqmgE45jTQtxg=
|
||||
github.com/bytedance/sonic v1.14.0 h1:/OfKt8HFw0kh2rj8N0F6C/qPGRESq0BbaNZgcNXXzQQ=
|
||||
github.com/bytedance/sonic v1.14.0/go.mod h1:WoEbx8WTcFJfzCe0hbmyTGrfjt8PzNEBdxlNUO24NhA=
|
||||
github.com/bytedance/gopkg v0.1.3 h1:TPBSwH8RsouGCBcMBktLt1AymVo2TVsBVCY4b6TnZ/M=
|
||||
github.com/bytedance/gopkg v0.1.3/go.mod h1:576VvJ+eJgyCzdjS+c4+77QF3p7ubbtiKARP3TxducM=
|
||||
github.com/bytedance/sonic v1.14.1 h1:FBMC0zVz5XUmE4z9wF4Jey0An5FueFvOsTKKKtwIl7w=
|
||||
github.com/bytedance/sonic v1.14.1/go.mod h1:gi6uhQLMbTdeP0muCnrjHLeCUPyb70ujhnNlhOylAFc=
|
||||
github.com/bytedance/sonic v1.14.2 h1:k1twIoe97C1DtYUo+fZQy865IuHia4PR5RPiuGPPIIE=
|
||||
github.com/bytedance/sonic v1.14.2/go.mod h1:T80iDELeHiHKSc0C9tubFygiuXoGzrkjKzX2quAx980=
|
||||
github.com/bytedance/sonic/loader v0.3.0 h1:dskwH8edlzNMctoruo8FPTJDF3vLtDT0sXZwvZJyqeA=
|
||||
github.com/bytedance/sonic/loader v0.3.0/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI=
|
||||
github.com/bytedance/sonic/loader v0.4.0 h1:olZ7lEqcxtZygCK9EKYKADnpQoYkRQxaeY2NYzevs+o=
|
||||
github.com/bytedance/sonic/loader v0.4.0/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo=
|
||||
github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M=
|
||||
github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@ -34,12 +36,14 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||
github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1 h1:CaO/zOnF8VvUfEbhRatPcwKVWamvbYd8tQGRWacE9kU=
|
||||
github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1/go.mod h1:+hnT3ywWDTAFrW5aE+u2Sa/wT555ZqwoCS+pk3p6ry4=
|
||||
github.com/gabriel-vasile/mimetype v1.4.9 h1:5k+WDwEsD9eTLL8Tz3L0VnmVh9QxGjRmjBvAG7U/oYY=
|
||||
github.com/gabriel-vasile/mimetype v1.4.9/go.mod h1:WnSQhFKJuBlRyLiKohA/2DtIlPFAbguNaG7QCHcyGok=
|
||||
github.com/gabriel-vasile/mimetype v1.4.10 h1:zyueNbySn/z8mJZHLt6IPw0KoZsiQNszIpU+bX4+ZK0=
|
||||
github.com/gabriel-vasile/mimetype v1.4.10/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=
|
||||
github.com/gabriel-vasile/mimetype v1.4.11 h1:AQvxbp830wPhHTqc1u7nzoLT+ZFxGY7emj5DR5DYFik=
|
||||
github.com/gabriel-vasile/mimetype v1.4.11/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=
|
||||
github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w=
|
||||
github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM=
|
||||
github.com/gin-gonic/gin v1.10.1 h1:T0ujvqyCSqRopADpgPgiTT63DUQVSfojyME59Ei63pQ=
|
||||
github.com/gin-gonic/gin v1.10.1/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
|
||||
github.com/gin-gonic/gin v1.11.0 h1:OW/6PLjyusp2PPXtyxKHU0RbX6I/l28FTdDlae5ueWk=
|
||||
github.com/gin-gonic/gin v1.11.0/go.mod h1:+iq/FyxlGzII0KHiBGjuNn4UNENUlKbGlNmc+W50Dls=
|
||||
github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A=
|
||||
github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
|
||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||
@ -48,10 +52,12 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o
|
||||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||
github.com/go-playground/validator/v10 v10.27.0 h1:w8+XrWVMhGkxOaaowyKH35gFydVHOvC0/uWoy2Fzwn4=
|
||||
github.com/go-playground/validator/v10 v10.27.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo=
|
||||
github.com/go-playground/validator/v10 v10.28.0 h1:Q7ibns33JjyW48gHkuFT91qX48KG0ktULL6FgHdG688=
|
||||
github.com/go-playground/validator/v10 v10.28.0/go.mod h1:GoI6I1SjPBh9p7ykNE/yj3fFYbyDOpwMn5KXd+m2hUU=
|
||||
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
|
||||
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||
github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw=
|
||||
github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
@ -61,10 +67,6 @@ github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25d
|
||||
github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k=
|
||||
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
|
||||
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/jonboulle/clockwork v0.3.0 h1:9BSCMi8C+0qdApAp4auwX0RkLGUjs956h0EkuQymUhg=
|
||||
github.com/jonboulle/clockwork v0.3.0/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
@ -104,6 +106,10 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI=
|
||||
github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg=
|
||||
github.com/quic-go/quic-go v0.55.0 h1:zccPQIqYCXDt5NmcEabyYvOnomjs8Tlwl7tISjJh9Mk=
|
||||
github.com/quic-go/quic-go v0.55.0/go.mod h1:DR51ilwU1uE164KuWXhinFcKWGlEjzys2l8zUl5Ss1U=
|
||||
github.com/sbabiv/xml2map v1.2.1 h1:1lT7t0hhUvXZCkdxqtq4n8/ZCnwLWGq4rDuDv5XOoFE=
|
||||
github.com/sbabiv/xml2map v1.2.1/go.mod h1:2TPoAfcaM7+Sd4iriPvzyntb2mx7GY+kkQpB/GQa/eo=
|
||||
github.com/smarty/assertions v1.15.0 h1:cR//PqUBUiQRakZWqBiFFQ9wb8emQGDb0HeGdqGByCY=
|
||||
@ -115,44 +121,50 @@ github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
|
||||
github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||
github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
|
||||
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||
github.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA=
|
||||
github.com/ugorji/go/codec v1.3.0/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4=
|
||||
github.com/ugorji/go/codec v1.3.1 h1:waO7eEiFDwidsBN6agj1vJQ4AG7lh2yqXyOXqhgQuyY=
|
||||
github.com/ugorji/go/codec v1.3.1/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=
|
||||
go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
||||
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||
golang.org/x/arch v0.20.0 h1:dx1zTU0MAE98U+TQ8BLl7XsJbgze2WnNKF/8tGp/Q6c=
|
||||
golang.org/x/arch v0.20.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk=
|
||||
golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4=
|
||||
golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc=
|
||||
golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
|
||||
golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
|
||||
golang.org/x/arch v0.22.0 h1:c/Zle32i5ttqRXjdLyyHZESLD/bB90DCU1g9l/0YBDI=
|
||||
golang.org/x/arch v0.22.0/go.mod h1:dNHoOeKiyja7GTvF9NJS1l3Z2yntpQNzgrjh1cU103A=
|
||||
golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04=
|
||||
golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0=
|
||||
golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA=
|
||||
golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w=
|
||||
golang.org/x/net v0.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4=
|
||||
golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210=
|
||||
golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
|
||||
golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
|
||||
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
|
||||
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
|
||||
golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
|
||||
golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k=
|
||||
golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM=
|
||||
golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ=
|
||||
golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/protobuf v1.36.7 h1:IgrO7UwFQGJdRNXH/sQux4R1Dj1WAKcLElzeeRaXV2A=
|
||||
google.golang.org/protobuf v1.36.7/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
|
||||
google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
|
||||
google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
@ -161,7 +173,3 @@ gopkg.in/olahol/melody.v1 v1.0.0-20170518105555-d52139073376/go.mod h1:BHKOc1m5w
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gorm.io/gorm v1.25.3 h1:zi4rHZj1anhZS2EuEODMhDisGy+Daq9jtPrNGgbQYD8=
|
||||
gorm.io/gorm v1.25.3/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
|
||||
gorm.io/gorm v1.30.1 h1:lSHg33jJTBxs2mgJRfRZeLDG+WZaHYCk3Wtfl6Ngzo4=
|
||||
gorm.io/gorm v1.30.1/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE=
|
||||
|
||||
23
logger.go
23
logger.go
@ -10,8 +10,7 @@ package logger
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"git.zhangdeman.cn/zhangdeman/consts"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
@ -23,11 +22,7 @@ import (
|
||||
)
|
||||
|
||||
// NewLogger 获取日志实例
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 5:05 下午 2021/1/2
|
||||
func NewLogger(inputLoggerLevel consts.LogLevel, splitConfig *RotateLogConfig, optionFunc ...SetLoggerOptionFunc) (*zap.Logger, error) {
|
||||
func NewLogger(inputLoggerLevel LogLevel, splitConfig *RotateLogConfig, optionFunc ...SetLoggerOptionFunc) (*zap.Logger, error) {
|
||||
if nil == splitConfig {
|
||||
return nil, errors.New("未配置日志切割规则")
|
||||
}
|
||||
@ -87,10 +82,6 @@ func NewLogger(inputLoggerLevel consts.LogLevel, splitConfig *RotateLogConfig, o
|
||||
}
|
||||
|
||||
// NewConsoleLogger 获取控制台输出的日志实例
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 8:22 下午 2021/4/17
|
||||
func NewConsoleLogger(loggerLevel zapcore.Level, optionFunc ...SetLoggerOptionFunc) (*zap.Logger, error) {
|
||||
o := &OptionLogger{}
|
||||
|
||||
@ -124,15 +115,11 @@ type Logger struct {
|
||||
}
|
||||
|
||||
// getWriter 获取日志实例
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 5:08 下午 2021/1/2
|
||||
func (l *Logger) getWriter() (io.Writer, error) {
|
||||
option := make([]rotatelogs.Option, 0)
|
||||
option = append(option, rotatelogs.WithRotationTime(l.splitConfig.TimeInterval))
|
||||
if l.splitConfig.MaxAge > 0 {
|
||||
option = append(option, rotatelogs.WithMaxAge(l.splitConfig.MaxAge))
|
||||
option = append(option, rotatelogs.WithMaxAge(time.Duration(l.splitConfig.MaxAge)*time.Second))
|
||||
}
|
||||
var (
|
||||
hook *rotatelogs.RotateLogs
|
||||
@ -149,10 +136,6 @@ type wsWriter struct {
|
||||
}
|
||||
|
||||
// Write ws的writer
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 22:24 2024/7/22
|
||||
func (w *wsWriter) Write(p []byte) (n int, err error) {
|
||||
if nil == wsLoggerConnect {
|
||||
return 0, nil
|
||||
|
||||
82
util.go
82
util.go
@ -1,82 +0,0 @@
|
||||
// Package logger ...
|
||||
//
|
||||
// Description : logger ...
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 2024-07-24 21:14
|
||||
package logger
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"git.zhangdeman.cn/zhangdeman/consts"
|
||||
"git.zhangdeman.cn/zhangdeman/network/util"
|
||||
"git.zhangdeman.cn/zhangdeman/serialize"
|
||||
"git.zhangdeman.cn/zhangdeman/wrapper"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
func getStrVal(ctx context.Context, key string) string {
|
||||
val := ctx.Value(key)
|
||||
if nil != val {
|
||||
return wrapper.AnyDataType(val).ToString().Value()
|
||||
}
|
||||
if v := ctx.Value(consts.GinContextDataField); nil != v {
|
||||
if data, ok := v.(map[string]any); ok {
|
||||
if searchVal, exist := data[key]; exist && nil != searchVal {
|
||||
return fmt.Sprintf("%v", searchVal)
|
||||
}
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// NewLogData ...
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 16:21 2024/7/23
|
||||
func NewLogData(ctx context.Context, logType string, code string, logData map[string]any) *LogData {
|
||||
hostname, _ := os.Hostname()
|
||||
if nil == ctx {
|
||||
ctx = context.Background()
|
||||
}
|
||||
commonLogData := &LogData{
|
||||
Env: getStrVal(ctx, consts.GinEnvField),
|
||||
Uri: getStrVal(ctx, consts.GinRequestURIField),
|
||||
TraceID: getStrVal(ctx, consts.GinTraceIDField),
|
||||
UserID: getStrVal(ctx, consts.GinUserIDField),
|
||||
UserRoleID: getStrVal(ctx, consts.GinUserRoleIDField),
|
||||
OperateMode: getStrVal(ctx, consts.GinOperateModeField),
|
||||
LogType: logType,
|
||||
CodeVersion: getStrVal(ctx, consts.GinCodeVersionField),
|
||||
ServiceVersion: getStrVal(ctx, consts.GinServiceVersionField),
|
||||
ClientIp: getStrVal(ctx, consts.GinClientIpField),
|
||||
ServerIp: util.IP.GetHostIP(),
|
||||
Hostname: hostname,
|
||||
Code: code,
|
||||
Data: logData,
|
||||
}
|
||||
return commonLogData
|
||||
}
|
||||
|
||||
// ZapLogDataList 记录的日志数据字段列表
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 17:33 2024/7/23
|
||||
func ZapLogDataList(logData *LogData) []zap.Field {
|
||||
logDataList := make([]zap.Field, 0)
|
||||
if logData == nil {
|
||||
return logDataList
|
||||
}
|
||||
var mapData map[string]any
|
||||
_ = serialize.JSON.Transition(logData, &mapData)
|
||||
for k, v := range mapData {
|
||||
logDataList = append(logDataList, zap.Any(k, v))
|
||||
}
|
||||
return logDataList
|
||||
}
|
||||
@ -1,216 +0,0 @@
|
||||
// Package wrapper...
|
||||
//
|
||||
// Description : gorm v2 版本接口实现
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 2021/03/01 9:52 下午
|
||||
package wrapper
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.zhangdeman.cn/zhangdeman/consts"
|
||||
|
||||
"gorm.io/gorm"
|
||||
|
||||
"go.uber.org/zap/zapcore"
|
||||
|
||||
"go.uber.org/zap"
|
||||
|
||||
logger2 "git.zhangdeman.cn/zhangdeman/logger"
|
||||
"gorm.io/gorm/logger"
|
||||
)
|
||||
|
||||
// NewGormV2 获取日志实例
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 9:56 下午 2021/3/1
|
||||
func NewGormV2(loggerLevel consts.LogLevel, consoleOutput bool, encoder zapcore.Encoder, splitConfig *logger2.RotateLogConfig, traceIDField string, skip int) (logger.Interface, error) {
|
||||
logConfList := []logger2.SetLoggerOptionFunc{logger2.WithEncoder(encoder), logger2.WithCallerSkip(skip), logger2.WithCaller()}
|
||||
if consoleOutput {
|
||||
logConfList = append(logConfList, logger2.WithConsoleOutput())
|
||||
}
|
||||
|
||||
logInstance, err := logger2.NewLogger(loggerLevel, splitConfig, logConfList...)
|
||||
if nil != err {
|
||||
return nil, err
|
||||
}
|
||||
if len(traceIDField) == 0 {
|
||||
traceIDField = "trace_id"
|
||||
}
|
||||
|
||||
return &Gorm{
|
||||
instance: logInstance,
|
||||
traceIDField: traceIDField,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// NewGormLoggerWithInstance 获取gorm日志实现
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 3:36 PM 2021/12/24
|
||||
func NewGormLoggerWithInstance(outCtx context.Context, dbClient *gorm.DB, instance *zap.Logger, node string, extraCtxFieldList []string) logger.Interface {
|
||||
nodeArr := strings.Split(node, "|")
|
||||
i := &Gorm{
|
||||
dbClient: dbClient,
|
||||
instance: instance,
|
||||
traceIDField: consts.GinTraceIDField,
|
||||
extraCtxFieldList: extraCtxFieldList,
|
||||
flag: "",
|
||||
node: node,
|
||||
outCtx: outCtx,
|
||||
}
|
||||
if len(nodeArr) >= 2 {
|
||||
i.node = nodeArr[1]
|
||||
i.flag = nodeArr[0]
|
||||
}
|
||||
return i
|
||||
}
|
||||
|
||||
// Gorm v2 版本库日志实现
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 9:55 下午 2021/3/1
|
||||
type Gorm struct {
|
||||
dbClient *gorm.DB
|
||||
instance *zap.Logger // 日志实例
|
||||
traceIDField string // 串联请求上下文的的ID
|
||||
extraCtxFieldList []string // 从请求上线问提取的字段
|
||||
flag string // 数据库标识
|
||||
node string // 数据库节点 master / slave
|
||||
outCtx context.Context
|
||||
}
|
||||
|
||||
// LogMode ...
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 10:08 下午 2021/3/1
|
||||
func (g *Gorm) LogMode(level logger.LogLevel) logger.Interface {
|
||||
return g
|
||||
}
|
||||
|
||||
// Info 日志
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 10:18 下午 2021/3/1
|
||||
func (g *Gorm) Info(ctx context.Context, s string, i ...any) {
|
||||
g.write(ctx, s, consts.LogLevelInfo, map[string]any{
|
||||
"log_data": i,
|
||||
})
|
||||
}
|
||||
|
||||
// Warn ...
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 10:16 下午 2021/3/1
|
||||
func (g *Gorm) Warn(ctx context.Context, s string, i ...any) {
|
||||
g.write(ctx, s, consts.LogLevelWarn, map[string]any{
|
||||
"log_data": i,
|
||||
})
|
||||
}
|
||||
|
||||
// Error 日志
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 10:18 下午 2021/3/1
|
||||
func (g *Gorm) Error(ctx context.Context, s string, i ...any) {
|
||||
g.write(ctx, s, consts.LogLevelError, map[string]any{
|
||||
"log_data": i,
|
||||
})
|
||||
}
|
||||
|
||||
// Trace Trace 记录
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 10:19 下午 2021/3/1
|
||||
func (g *Gorm) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) {
|
||||
start := begin.UnixNano()
|
||||
end := time.Now().UnixNano()
|
||||
sql := ""
|
||||
affectRows := int64(0)
|
||||
if nil != fc {
|
||||
sql, affectRows = fc()
|
||||
}
|
||||
|
||||
logData := map[string]any{
|
||||
"db_flag": g.flag,
|
||||
"db_node": g.node,
|
||||
"begin_time": start,
|
||||
"finish_time": end,
|
||||
"used_time": (end - start) / 1e6,
|
||||
"sql": sql,
|
||||
"affect_rows": affectRows,
|
||||
"err": "",
|
||||
}
|
||||
if nil != err {
|
||||
logData["err"] = err.Error()
|
||||
}
|
||||
g.write(ctx, "SQL执行记录", consts.LogLevelInfo, logData)
|
||||
}
|
||||
|
||||
// write ...
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 4:11 PM 2021/12/24
|
||||
func (g *Gorm) write(ctx context.Context, message string, level consts.LogLevel, data map[string]any) {
|
||||
if len(message) == 0 {
|
||||
message = "SQL执行记录"
|
||||
}
|
||||
if nil == g.instance {
|
||||
// 未设置日志实例
|
||||
return
|
||||
}
|
||||
if nil == data {
|
||||
data = make(map[string]any)
|
||||
}
|
||||
if nil != data["sql"] {
|
||||
sqlStr := strings.TrimSpace(fmt.Sprintf("%v", data["sql"]))
|
||||
sqlArr := strings.Split(sqlStr, " ")
|
||||
if len(sqlArr) > 0 {
|
||||
data["sql_type"] = strings.ToUpper(sqlArr[0])
|
||||
}
|
||||
}
|
||||
if nil == g.outCtx {
|
||||
g.outCtx = context.Background()
|
||||
}
|
||||
|
||||
dataList := logger2.ZapLogDataList(logger2.NewLogData(g.outCtx, consts.LogTypeDatabase, "", data))
|
||||
switch level {
|
||||
case consts.LogLevelDebug:
|
||||
g.instance.Debug(message, dataList...)
|
||||
case consts.LogLevelInfo:
|
||||
g.instance.Info(message, dataList...)
|
||||
case consts.LogLevelWarn:
|
||||
g.instance.Warn(message, dataList...)
|
||||
case consts.LogLevelError:
|
||||
g.instance.Error(message, dataList...)
|
||||
case consts.LogLevelPanic:
|
||||
g.instance.Panic(message, dataList...)
|
||||
default:
|
||||
g.instance.Info(message, dataList...)
|
||||
}
|
||||
}
|
||||
|
||||
// GetGormSQL 获取trace fn
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 10:38 下午 2021/3/1
|
||||
func GetGormSQL(dbClient *gorm.DB) func() (string, int64) {
|
||||
return func() (string, int64) {
|
||||
return dbClient.Dialector.Explain(dbClient.Statement.SQL.String(), dbClient.Statement.Vars...), dbClient.RowsAffected
|
||||
}
|
||||
}
|
||||
@ -10,18 +10,13 @@ package wrapper
|
||||
import (
|
||||
"context"
|
||||
|
||||
"git.zhangdeman.cn/zhangdeman/consts"
|
||||
"git.zhangdeman.cn/zhangdeman/logger"
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
)
|
||||
|
||||
// NewGinLogger 使用gin框架记录日志
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 3:45 下午 2021/1/3
|
||||
func NewGinLogger(loggerLevel consts.LogLevel, consoleOutput bool, encoder zapcore.Encoder, splitConfig *logger.RotateLogConfig, extractFieldList []string, skip int) (*Gin, error) {
|
||||
func NewGinLogger(loggerLevel logger.LogLevel, consoleOutput bool, encoder zapcore.Encoder, splitConfig *logger.RotateLogConfig, extractFieldList []string, skip int) (*Gin, error) {
|
||||
var (
|
||||
err error
|
||||
l *zap.Logger
|
||||
@ -41,20 +36,12 @@ func NewGinLogger(loggerLevel consts.LogLevel, consoleOutput bool, encoder zapco
|
||||
}
|
||||
|
||||
// Gin 包装gin实例
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 3:59 下午 2021/1/3
|
||||
type Gin struct {
|
||||
loggerInstance *zap.Logger // zap 的日志实例
|
||||
extractFieldList []string // 从gin中抽取的字段
|
||||
}
|
||||
|
||||
// formatFieldList 格式化日志field列表
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 4:13 下午 2021/1/3
|
||||
func (gw *Gin) formatFieldList(ctx context.Context, inputFieldList []zap.Field) []zap.Field {
|
||||
if nil == ctx {
|
||||
ctx = context.Background()
|
||||
@ -70,70 +57,42 @@ func (gw *Gin) formatFieldList(ctx context.Context, inputFieldList []zap.Field)
|
||||
}
|
||||
|
||||
// Debug 日志
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 4:14 下午 2021/1/3
|
||||
func (gw *Gin) Debug(ctx context.Context, msg string, field ...zap.Field) {
|
||||
fieldList := gw.formatFieldList(ctx, field)
|
||||
gw.loggerInstance.Debug(msg, fieldList...)
|
||||
}
|
||||
|
||||
// Info 日志
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 4:28 下午 2021/1/3
|
||||
func (gw *Gin) Info(ctx context.Context, msg string, field ...zap.Field) {
|
||||
fieldList := gw.formatFieldList(ctx, field)
|
||||
gw.loggerInstance.Info(msg, fieldList...)
|
||||
}
|
||||
|
||||
// Warn 日志
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 4:29 下午 2021/1/3
|
||||
func (gw *Gin) Warn(ctx context.Context, msg string, field ...zap.Field) {
|
||||
fieldList := gw.formatFieldList(ctx, field)
|
||||
gw.loggerInstance.Warn(msg, fieldList...)
|
||||
}
|
||||
|
||||
// Error 日志
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 4:29 下午 2021/1/3
|
||||
func (gw *Gin) Error(ctx context.Context, msg string, field ...zap.Field) {
|
||||
fieldList := gw.formatFieldList(ctx, field)
|
||||
gw.loggerInstance.Error(msg, fieldList...)
|
||||
}
|
||||
|
||||
// Panic 日志
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 4:29 下午 2021/1/3
|
||||
func (gw *Gin) Panic(ctx context.Context, msg string, field ...zap.Field) {
|
||||
fieldList := gw.formatFieldList(ctx, field)
|
||||
gw.loggerInstance.Panic(msg, fieldList...)
|
||||
}
|
||||
|
||||
// DPanic 日志
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 4:30 下午 2021/1/3
|
||||
func (gw *Gin) DPanic(ctx context.Context, msg string, field ...zap.Field) {
|
||||
fieldList := gw.formatFieldList(ctx, field)
|
||||
gw.loggerInstance.DPanic(msg, fieldList...)
|
||||
}
|
||||
|
||||
// GetZapLoggerInstance 获取zap日志实例
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 2021/01/03 22:56:47
|
||||
func (gw *Gin) GetZapLoggerInstance() *zap.Logger {
|
||||
return gw.loggerInstance
|
||||
}
|
||||
|
||||
@ -10,14 +10,15 @@ package logger
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"git.zhangdeman.cn/zhangdeman/consts"
|
||||
"git.zhangdeman.cn/zhangdeman/serialize"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"git.zhangdeman.cn/zhangdeman/consts"
|
||||
"git.zhangdeman.cn/zhangdeman/serialize"
|
||||
)
|
||||
|
||||
func NewZincLogConnect(cfg *ZincConfig) io.Writer {
|
||||
|
||||
Reference in New Issue
Block a user