feat: 优化升级日志组织
This commit is contained in:
		
							
								
								
									
										116
									
								
								config.go
									
									
									
									
									
								
							
							
						
						
									
										116
									
								
								config.go
									
									
									
									
									
								
							| @ -14,7 +14,6 @@ import ( | |||||||
| 	"strings" | 	"strings" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	"git.zhangdeman.cn/zhangdeman/consts" |  | ||||||
| 	"go.uber.org/zap/zapcore" | 	"go.uber.org/zap/zapcore" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @ -27,43 +26,27 @@ const ( | |||||||
| ) | ) | ||||||
|  |  | ||||||
| // RotateLogConfig 日志切割的配置 | // RotateLogConfig 日志切割的配置 | ||||||
| // |  | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 3:08 下午 2021/1/2 |  | ||||||
| type RotateLogConfig struct { | type RotateLogConfig struct { | ||||||
| 	TimeIntervalType consts.LogSplit `json:"time_interval_type" yaml:"time_interval_type"` // 日志切割的时间间隔类型 0 - 小时 1 - 天 2 - 月 3 - 年 | 	TimeIntervalType LogSplit      `json:"time_interval_type" yaml:"time_interval_type"` // 日志切割的时间间隔类型 0 - 小时 1 - 天 2 - 月 3 - 年 | ||||||
| 	TimeInterval     time.Duration `json:"time_interval"  yaml:"time_interval"`          // 日志切割的时间间隔 | 	TimeInterval     time.Duration `json:"time_interval"  yaml:"time_interval"`          // 日志切割的时间间隔 | ||||||
| 	LogPath          string        `json:"log_path" yaml:"log_path"`                     // 存储日志的路径 | 	LogPath          string        `json:"log_path" yaml:"log_path"`                     // 存储日志的路径 | ||||||
| 	LogFileName      string        `json:"log_file_name" yaml:"log_file_name"`           // 日志文件名 | 	LogFileName      string        `json:"log_file_name" yaml:"log_file_name"`           // 日志文件名 | ||||||
| 	DivisionChar     string        `json:"division_char" yaml:"division_char"`           // 日志文件拼时间分隔符 | 	DivisionChar     string        `json:"division_char" yaml:"division_char"`           // 日志文件拼时间分隔符 | ||||||
| 	FullLogFormat    string        `json:"full_log_format"  yaml:"full_log_format"`      // 完整的日志格式 | 	FullLogFormat    string        `json:"full_log_format"  yaml:"full_log_format"`      // 完整的日志格式 | ||||||
| 	MaxAge           time.Duration   `json:"max_age" yaml:"max_age"`                       // 日志最长保存时间 | 	MaxAge           int64         `json:"max_age" yaml:"max_age"`                       // 日志最长保存时间, 单位: s | ||||||
| } | } | ||||||
|  |  | ||||||
| // SetRotateLogConfigFunc 设置日志切割的选项 | // SetRotateLogConfigFunc 设置日志切割的选项 | ||||||
| // |  | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 3:13 下午 2021/1/2 |  | ||||||
| type SetRotateLogConfigFunc func(rlc *RotateLogConfig) | type SetRotateLogConfigFunc func(rlc *RotateLogConfig) | ||||||
|  |  | ||||||
| // WithTimeIntervalType 设置日志切割时间间隔 | // WithTimeIntervalType 设置日志切割时间间隔 | ||||||
| // | func WithTimeIntervalType(timeIntervalType LogSplit) SetRotateLogConfigFunc { | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 3:34 下午 2021/1/2 |  | ||||||
| func WithTimeIntervalType(timeIntervalType consts.LogSplit) SetRotateLogConfigFunc { |  | ||||||
| 	return func(rlc *RotateLogConfig) { | 	return func(rlc *RotateLogConfig) { | ||||||
| 		rlc.TimeIntervalType = timeIntervalType | 		rlc.TimeIntervalType = timeIntervalType | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| // WithDivisionChar 设置分隔符 | // WithDivisionChar 设置分隔符 | ||||||
| // |  | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 3:49 下午 2021/1/2 |  | ||||||
| func WithDivisionChar(divisionChar string) SetRotateLogConfigFunc { | func WithDivisionChar(divisionChar string) SetRotateLogConfigFunc { | ||||||
| 	return func(rlc *RotateLogConfig) { | 	return func(rlc *RotateLogConfig) { | ||||||
| 		rlc.DivisionChar = divisionChar | 		rlc.DivisionChar = divisionChar | ||||||
| @ -71,27 +54,22 @@ func WithDivisionChar(divisionChar string) SetRotateLogConfigFunc { | |||||||
| } | } | ||||||
|  |  | ||||||
| // WithMaxAge 设置日志保存时间 | // WithMaxAge 设置日志保存时间 | ||||||
| // | func WithMaxAge(maxAge int64) SetRotateLogConfigFunc { | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 5:03 下午 2021/1/2 |  | ||||||
| func WithMaxAge(maxAge time.Duration) SetRotateLogConfigFunc { |  | ||||||
| 	return func(rlc *RotateLogConfig) { | 	return func(rlc *RotateLogConfig) { | ||||||
|  | 		if maxAge <= 0 { | ||||||
|  | 			maxAge = 3 * 24 * 3600 // 默认3天 | ||||||
|  | 		} | ||||||
| 		rlc.MaxAge = maxAge | 		rlc.MaxAge = maxAge | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| // NewRotateLogConfig 生成日志切割的配置 | // NewRotateLogConfig 生成日志切割的配置 | ||||||
| // |  | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 3:53 下午 2021/1/2 |  | ||||||
| func NewRotateLogConfig(logPath string, logFile string, option ...SetRotateLogConfigFunc) (*RotateLogConfig, error) { | func NewRotateLogConfig(logPath string, logFile string, option ...SetRotateLogConfigFunc) (*RotateLogConfig, error) { | ||||||
| 	if len(logPath) == 0 || len(logFile) == 0 { | 	if len(logPath) == 0 || len(logFile) == 0 { | ||||||
| 		return nil, LogPathEmptyError() | 		return nil, LogPathEmptyError() | ||||||
| 	} | 	} | ||||||
| 	c := &RotateLogConfig{ | 	c := &RotateLogConfig{ | ||||||
| 		TimeIntervalType: consts.LogSplitHour, | 		TimeIntervalType: LogSplitHour, | ||||||
| 		LogPath:          logPath, | 		LogPath:          logPath, | ||||||
| 		LogFileName:      logFile, | 		LogFileName:      logFile, | ||||||
| 		DivisionChar:     "", | 		DivisionChar:     "", | ||||||
| @ -109,10 +87,6 @@ func NewRotateLogConfig(logPath string, logFile string, option ...SetRotateLogCo | |||||||
| } | } | ||||||
|  |  | ||||||
| // formatConfig 格式化配置 | // formatConfig 格式化配置 | ||||||
| // |  | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 4:23 下午 2021/1/2 |  | ||||||
| func formatConfig(c *RotateLogConfig) error { | func formatConfig(c *RotateLogConfig) error { | ||||||
|  |  | ||||||
| 	if len(c.DivisionChar) == 0 { | 	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() { | 	if !c.TimeIntervalType.IsValid() { | ||||||
| 		// 非法的日志切割规则,默认按天切 | 		// 非法的日志切割规则,默认按天切 | ||||||
| 		c.TimeIntervalType = consts.LogSplitDay | 		c.TimeIntervalType = LogSplitDay | ||||||
| 	} | 	} | ||||||
| 	// 生成格式化日志全路径 | 	// 生成格式化日志全路径 | ||||||
| 	switch c.TimeIntervalType { | 	switch c.TimeIntervalType { | ||||||
| 	case consts.LogSplitHour: | 	case LogSplitHour: | ||||||
| 		c.TimeInterval = time.Hour | 		c.TimeInterval = time.Hour | ||||||
| 		c.FullLogFormat = c.LogPath + "%Y" + c.DivisionChar + "%m" + c.DivisionChar + "%d" + c.DivisionChar + "%H" + c.DivisionChar + c.LogFileName | 		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.TimeInterval = time.Hour * 24 | ||||||
| 		c.FullLogFormat = c.LogPath + "%Y" + c.DivisionChar + "%m" + c.DivisionChar + "%d" + c.DivisionChar + c.LogFileName | 		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.TimeInterval = time.Hour * 24 * 30 | ||||||
| 		c.FullLogFormat = c.LogPath + "%Y" + c.DivisionChar + "%m" + c.DivisionChar + c.LogFileName | 		c.FullLogFormat = c.LogPath + "%Y" + c.DivisionChar + "%m" + c.DivisionChar + c.LogFileName | ||||||
| 	case consts.LogSplitYear: | 	case LogSplitYear: | ||||||
| 		c.TimeInterval = time.Hour * 24 * 365 | 		c.TimeInterval = time.Hour * 24 * 365 | ||||||
| 		c.FullLogFormat = c.LogPath + "%Y" + c.DivisionChar + c.LogFileName | 		c.FullLogFormat = c.LogPath + "%Y" + c.DivisionChar + c.LogFileName | ||||||
| 	default: | 	default: | ||||||
| @ -176,51 +150,31 @@ const ( | |||||||
| ) | ) | ||||||
|  |  | ||||||
| // defaultTimeEncoder 默认的时间处理 | // defaultTimeEncoder 默认的时间处理 | ||||||
| // |  | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 11:53 下午 2021/1/2 |  | ||||||
| func defaultTimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) { | func defaultTimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) { | ||||||
| 	sec := t.UnixNano() / 1e9 | 	sec := t.UnixNano() / 1e9 | ||||||
| 	ms := t.UnixNano() / 1e6 % 1e3 | 	ms := t.UnixNano() / 1e6 % 1e3 | ||||||
| 	ns := t.UnixNano() % 1e6 | 	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 秒级时间戳格式化 | // SecondTimeEncoder 秒级时间戳格式化 | ||||||
| // |  | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 8:34 下午 2021/1/3 |  | ||||||
| func SecondTimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) { | 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 毫秒时间格式化方法 | // MsTimeEncoder 毫秒时间格式化方法 | ||||||
| // |  | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 8:35 下午 2021/1/3 |  | ||||||
| func MsTimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) { | func MsTimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) { | ||||||
| 	sec := t.UnixNano() / 1e9 | 	sec := t.UnixNano() / 1e9 | ||||||
| 	ms := t.UnixNano() / 1e6 % 1e3 | 	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 默认的原始时间处理 | // defaultEncodeDuration 默认的原始时间处理 | ||||||
| // |  | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 11:56 下午 2021/1/2 |  | ||||||
| func defaultEncodeDuration(d time.Duration, enc zapcore.PrimitiveArrayEncoder) { | func defaultEncodeDuration(d time.Duration, enc zapcore.PrimitiveArrayEncoder) { | ||||||
| 	enc.AppendInt64(int64(d) / 1000000) | 	enc.AppendInt64(int64(d) / 1000000) | ||||||
| } | } | ||||||
|  |  | ||||||
| // OptionLogger 日志配置的选项 | // OptionLogger 日志配置的选项 | ||||||
| // |  | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 11:41 下午 2021/1/2 |  | ||||||
| type OptionLogger struct { | type OptionLogger struct { | ||||||
| 	UseJsonFormat     bool                    // 日志使用json格式 | 	UseJsonFormat     bool                    // 日志使用json格式 | ||||||
| 	MessageKey        string                  // message 字段 | 	MessageKey        string                  // message 字段 | ||||||
| @ -269,10 +223,6 @@ func WithEncoder(encoder zapcore.Encoder) SetLoggerOptionFunc { | |||||||
| } | } | ||||||
|  |  | ||||||
| // WithUseJsonFormat 日志是否使用json格式数据 | // WithUseJsonFormat 日志是否使用json格式数据 | ||||||
| // |  | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 12:30 上午 2021/1/3 |  | ||||||
| func WithUseJsonFormat(isJsonFormat bool) SetLoggerOptionFunc { | func WithUseJsonFormat(isJsonFormat bool) SetLoggerOptionFunc { | ||||||
| 	return func(o *OptionLogger) { | 	return func(o *OptionLogger) { | ||||||
| 		o.UseJsonFormat = isJsonFormat | 		o.UseJsonFormat = isJsonFormat | ||||||
| @ -280,10 +230,6 @@ func WithUseJsonFormat(isJsonFormat bool) SetLoggerOptionFunc { | |||||||
| } | } | ||||||
|  |  | ||||||
| // WithMessageKey 使用message key | // WithMessageKey 使用message key | ||||||
| // |  | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 12:32 上午 2021/1/3 |  | ||||||
| func WithMessageKey(messageKey string) SetLoggerOptionFunc { | func WithMessageKey(messageKey string) SetLoggerOptionFunc { | ||||||
| 	return func(o *OptionLogger) { | 	return func(o *OptionLogger) { | ||||||
| 		messageKey = strings.Trim(messageKey, " ") | 		messageKey = strings.Trim(messageKey, " ") | ||||||
| @ -295,10 +241,6 @@ func WithMessageKey(messageKey string) SetLoggerOptionFunc { | |||||||
| } | } | ||||||
|  |  | ||||||
| // WithLevelKey 设置level key | // WithLevelKey 设置level key | ||||||
| // |  | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 12:33 上午 2021/1/3 |  | ||||||
| func WithLevelKey(levelKey string) SetLoggerOptionFunc { | func WithLevelKey(levelKey string) SetLoggerOptionFunc { | ||||||
| 	return func(o *OptionLogger) { | 	return func(o *OptionLogger) { | ||||||
| 		levelKey = strings.Trim(levelKey, " ") | 		levelKey = strings.Trim(levelKey, " ") | ||||||
| @ -310,10 +252,6 @@ func WithLevelKey(levelKey string) SetLoggerOptionFunc { | |||||||
| } | } | ||||||
|  |  | ||||||
| // WithTimeKey 设置time key ... | // WithTimeKey 设置time key ... | ||||||
| // |  | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 12:34 上午 2021/1/3 |  | ||||||
| func WithTimeKey(timeKey string) SetLoggerOptionFunc { | func WithTimeKey(timeKey string) SetLoggerOptionFunc { | ||||||
| 	return func(o *OptionLogger) { | 	return func(o *OptionLogger) { | ||||||
| 		timeKey = strings.Trim(timeKey, " ") | 		timeKey = strings.Trim(timeKey, " ") | ||||||
| @ -325,10 +263,6 @@ func WithTimeKey(timeKey string) SetLoggerOptionFunc { | |||||||
| } | } | ||||||
|  |  | ||||||
| // WithCallerKey 设置caller key | // WithCallerKey 设置caller key | ||||||
| // |  | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 12:37 上午 2021/1/3 |  | ||||||
| func WithCallerKey(callerKey string) SetLoggerOptionFunc { | func WithCallerKey(callerKey string) SetLoggerOptionFunc { | ||||||
| 	return func(o *OptionLogger) { | 	return func(o *OptionLogger) { | ||||||
| 		callerKey = strings.Trim(callerKey, " ") | 		callerKey = strings.Trim(callerKey, " ") | ||||||
| @ -340,10 +274,6 @@ func WithCallerKey(callerKey string) SetLoggerOptionFunc { | |||||||
| } | } | ||||||
|  |  | ||||||
| // WithShortCaller 是否使用短caller格式 | // WithShortCaller 是否使用短caller格式 | ||||||
| // |  | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 12:39 上午 2021/1/3 |  | ||||||
| func WithShortCaller(useShortCaller bool) SetLoggerOptionFunc { | func WithShortCaller(useShortCaller bool) SetLoggerOptionFunc { | ||||||
| 	return func(o *OptionLogger) { | 	return func(o *OptionLogger) { | ||||||
| 		o.UseShortCaller = useShortCaller | 		o.UseShortCaller = useShortCaller | ||||||
| @ -351,10 +281,6 @@ func WithShortCaller(useShortCaller bool) SetLoggerOptionFunc { | |||||||
| } | } | ||||||
|  |  | ||||||
| // WithTimeEncoder 设置格式化时间方法 | // WithTimeEncoder 设置格式化时间方法 | ||||||
| // |  | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 12:41 上午 2021/1/3 |  | ||||||
| func WithTimeEncoder(encoder zapcore.TimeEncoder) SetLoggerOptionFunc { | func WithTimeEncoder(encoder zapcore.TimeEncoder) SetLoggerOptionFunc { | ||||||
| 	return func(o *OptionLogger) { | 	return func(o *OptionLogger) { | ||||||
| 		if nil == encoder { | 		if nil == encoder { | ||||||
| @ -365,10 +291,6 @@ func WithTimeEncoder(encoder zapcore.TimeEncoder) SetLoggerOptionFunc { | |||||||
| } | } | ||||||
|  |  | ||||||
| // WithEncodeDuration 原始时间 | // WithEncodeDuration 原始时间 | ||||||
| // |  | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 12:42 上午 2021/1/3 |  | ||||||
| func WithEncodeDuration(encoder zapcore.DurationEncoder) SetLoggerOptionFunc { | func WithEncodeDuration(encoder zapcore.DurationEncoder) SetLoggerOptionFunc { | ||||||
| 	return func(o *OptionLogger) { | 	return func(o *OptionLogger) { | ||||||
| 		if nil == encoder { | 		if nil == encoder { | ||||||
| @ -386,10 +308,6 @@ func WithZincLogCollect(zincCfg *ZincConfig) SetLoggerOptionFunc { | |||||||
| } | } | ||||||
|  |  | ||||||
| // GetEncoder 获取空中台输出的encoder | // GetEncoder 获取空中台输出的encoder | ||||||
| // |  | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 6:24 下午 2021/1/2 |  | ||||||
| func GetEncoder(option ...SetLoggerOptionFunc) zapcore.Encoder { | func GetEncoder(option ...SetLoggerOptionFunc) zapcore.Encoder { | ||||||
| 	ol := &OptionLogger{ | 	ol := &OptionLogger{ | ||||||
| 		UseJsonFormat:  defaultUseJsonFormat, | 		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() |  | ||||||
| } |  | ||||||
							
								
								
									
										33
									
								
								define.go
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								define.go
									
									
									
									
									
								
							| @ -12,7 +12,6 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"os" | 	"os" | ||||||
| 	"strings" | 	"strings" | ||||||
| 	"time" |  | ||||||
|  |  | ||||||
| 	"git.zhangdeman.cn/zhangdeman/consts" | 	"git.zhangdeman.cn/zhangdeman/consts" | ||||||
| 	"git.zhangdeman.cn/zhangdeman/network/util" | 	"git.zhangdeman.cn/zhangdeman/network/util" | ||||||
| @ -80,9 +79,9 @@ func (ld *LogData) ToFieldList() []zap.Field { | |||||||
| type InputLogConfig struct { | type InputLogConfig struct { | ||||||
| 	Name             string      `json:"name" yaml:"name"`                             // 日志文件名 | 	Name             string      `json:"name" yaml:"name"`                             // 日志文件名 | ||||||
| 	Path             string      `json:"path" yaml:"path"`                             // 日志文件路径 | 	Path             string      `json:"path" yaml:"path"`                             // 日志文件路径 | ||||||
| 	TimeIntervalType consts.LogSplit `json:"time_interval_type" yaml:"time_interval_type"` // 日志切割规则 | 	TimeIntervalType LogSplit    `json:"time_interval_type" yaml:"time_interval_type"` // 日志切割规则 | ||||||
| 	DivisionChar     string      `json:"division_char" yaml:"division_char"`           // 文件名分隔符 | 	DivisionChar     string      `json:"division_char" yaml:"division_char"`           // 文件名分隔符 | ||||||
| 	LogLevel         consts.LogLevel `json:"log_level" yaml:"log_level"`                   // 日志等级 | 	LogLevel         LogLevel    `json:"log_level" yaml:"log_level"`                   // 日志等级 | ||||||
| 	Console          bool        `json:"console" yaml:"console"`                       // 是否进行控制台日志输出 | 	Console          bool        `json:"console" yaml:"console"`                       // 是否进行控制台日志输出 | ||||||
| 	UseJson          bool        `json:"use_json" yaml:"use_json"`                     // 日志是否使用JSON格式 | 	UseJson          bool        `json:"use_json" yaml:"use_json"`                     // 日志是否使用JSON格式 | ||||||
| 	FileLine         bool        `json:"file_line" yaml:"file_line"`                   // 日志是否打印行号 | 	FileLine         bool        `json:"file_line" yaml:"file_line"`                   // 日志是否打印行号 | ||||||
| @ -92,7 +91,7 @@ type InputLogConfig struct { | |||||||
| 	CallerKey        string      `json:"caller_key" yaml:"caller_key"`                 // 记录日志的文件的代码行数 | 	CallerKey        string      `json:"caller_key" yaml:"caller_key"`                 // 记录日志的文件的代码行数 | ||||||
| 	UseShortFile     bool        `json:"use_short_file" yaml:"use_short_file"`         // 是否使用短文件格式 | 	UseShortFile     bool        `json:"use_short_file" yaml:"use_short_file"`         // 是否使用短文件格式 | ||||||
| 	CallerSkip       int         `json:"caller_skip" yaml:"caller_skip"`               // 日志记录的文件跳过多少层 | 	CallerSkip       int         `json:"caller_skip" yaml:"caller_skip"`               // 日志记录的文件跳过多少层 | ||||||
| 	MaxAge           int             `json:"max_age" yaml:"max_age"`                       // 日志最长保存时间, 单位 : 秒 | 	MaxAge           int64       `json:"max_age" yaml:"max_age"`                       // 日志最长保存时间, 单位 : 秒 | ||||||
| 	ZincSyncConfig   *ZincConfig `json:"zinc_sync_config" yaml:"zinc_sync_config"`     // 日志同步至zinc的配置 | 	ZincSyncConfig   *ZincConfig `json:"zinc_sync_config" yaml:"zinc_sync_config"`     // 日志同步至zinc的配置 | ||||||
| } | } | ||||||
|  |  | ||||||
| @ -136,10 +135,6 @@ func getStrVal(ctx context.Context, key string) string { | |||||||
| } | } | ||||||
|  |  | ||||||
| // GetLogInstanceFromInputConfig 从输入配置获取日志实例 | // GetLogInstanceFromInputConfig 从输入配置获取日志实例 | ||||||
| // |  | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 18:43 2022/6/12 |  | ||||||
| func GetLogInstanceFromInputConfig(logConf *InputLogConfig) (*zap.Logger, error) { | func GetLogInstanceFromInputConfig(logConf *InputLogConfig) (*zap.Logger, error) { | ||||||
| 	if nil == logConf { | 	if nil == logConf { | ||||||
| 		return nil, nil | 		return nil, nil | ||||||
| @ -166,7 +161,7 @@ func GetLogInstanceFromInputConfig(logConf *InputLogConfig) (*zap.Logger, error) | |||||||
| 		logConf.Name, | 		logConf.Name, | ||||||
| 		WithDivisionChar(logConf.DivisionChar), | 		WithDivisionChar(logConf.DivisionChar), | ||||||
| 		WithTimeIntervalType(logConf.TimeIntervalType), | 		WithTimeIntervalType(logConf.TimeIntervalType), | ||||||
| 		WithMaxAge(time.Duration(logConf.MaxAge)*time.Second)); nil != err { | 		WithMaxAge(logConf.MaxAge)); nil != err { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| 	if loggerInstance, err = NewLogger(logConf.LogLevel, splitConfig, logConfList...); nil != err { | 	if loggerInstance, err = NewLogger(logConf.LogLevel, splitConfig, logConfList...); nil != err { | ||||||
| @ -176,27 +171,23 @@ func GetLogInstanceFromInputConfig(logConf *InputLogConfig) (*zap.Logger, error) | |||||||
| } | } | ||||||
|  |  | ||||||
| // inputLevel2ZapLevel 输入日志等级转化为zap日志等级 | // inputLevel2ZapLevel 输入日志等级转化为zap日志等级 | ||||||
| // | func inputLevel2ZapLevel(inputLoggerLevel LogLevel) zapcore.Level { | ||||||
| // Author : go_developer@163.com<白茶清欢> | 	inputLoggerLevel = LogLevel(strings.ToUpper(inputLoggerLevel.String())) | ||||||
| // |  | ||||||
| // Date : 18:07 2024/6/24 |  | ||||||
| func inputLevel2ZapLevel(inputLoggerLevel consts.LogLevel) zapcore.Level { |  | ||||||
| 	inputLoggerLevel = consts.LogLevel(strings.ToUpper(inputLoggerLevel.String())) |  | ||||||
| 	if !inputLoggerLevel.IsValid() { | 	if !inputLoggerLevel.IsValid() { | ||||||
| 		// 非法的日志等级, 自动重定向为 info 级别 | 		// 非法的日志等级, 自动重定向为 info 级别 | ||||||
| 		inputLoggerLevel = consts.LogLevelInfo | 		inputLoggerLevel = LogLevelInfo | ||||||
| 	} | 	} | ||||||
| 	loggerLevel := zapcore.DebugLevel | 	loggerLevel := zapcore.DebugLevel | ||||||
| 	switch inputLoggerLevel { | 	switch inputLoggerLevel { | ||||||
| 	case consts.LogLevelDebug: | 	case LogLevelDebug: | ||||||
| 		loggerLevel = zapcore.DebugLevel | 		loggerLevel = zapcore.DebugLevel | ||||||
| 	case consts.LogLevelInfo: | 	case LogLevelInfo: | ||||||
| 		loggerLevel = zapcore.InfoLevel | 		loggerLevel = zapcore.InfoLevel | ||||||
| 	case consts.LogLevelWarn: | 	case LogLevelWarn: | ||||||
| 		loggerLevel = zapcore.WarnLevel | 		loggerLevel = zapcore.WarnLevel | ||||||
| 	case consts.LogLevelError: | 	case LogLevelError: | ||||||
| 		loggerLevel = zapcore.ErrorLevel | 		loggerLevel = zapcore.ErrorLevel | ||||||
| 	case consts.LogLevelPanic: | 	case LogLevelPanic: | ||||||
| 		loggerLevel = zapcore.PanicLevel | 		loggerLevel = zapcore.PanicLevel | ||||||
| 	} | 	} | ||||||
| 	return loggerLevel | 	return loggerLevel | ||||||
|  | |||||||
							
								
								
									
										24
									
								
								error.go
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								error.go
									
									
									
									
									
								
							| @ -10,55 +10,31 @@ package logger | |||||||
| import "github.com/pkg/errors" | import "github.com/pkg/errors" | ||||||
|  |  | ||||||
| // CreateLogFileError 创建日志文件失败 | // CreateLogFileError 创建日志文件失败 | ||||||
| // |  | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 2:55 下午 2021/1/2 |  | ||||||
| func CreateLogFileError(err error, logFilePath string) error { | func CreateLogFileError(err error, logFilePath string) error { | ||||||
| 	return errors.Wrapf(err, "创建日志文件失败,日志文件路径 : %s", logFilePath) | 	return errors.Wrapf(err, "创建日志文件失败,日志文件路径 : %s", logFilePath) | ||||||
| } | } | ||||||
|  |  | ||||||
| // LogPathEmptyError 日志路径为空 | // LogPathEmptyError 日志路径为空 | ||||||
| // |  | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 4:03 下午 2021/1/2 |  | ||||||
| func LogPathEmptyError() error { | func LogPathEmptyError() error { | ||||||
| 	return errors.Wrap(errors.New("日志存储路径或者日志文件名为空"), "日志存储路径或者日志文件名为空") | 	return errors.Wrap(errors.New("日志存储路径或者日志文件名为空"), "日志存储路径或者日志文件名为空") | ||||||
| } | } | ||||||
|  |  | ||||||
| // CustomTimeIntervalError 自定义日志切割时间间隔错误 | // CustomTimeIntervalError 自定义日志切割时间间隔错误 | ||||||
| // |  | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 4:11 下午 2021/1/2 |  | ||||||
| func CustomTimeIntervalError() error { | func CustomTimeIntervalError() error { | ||||||
| 	return errors.Wrap(errors.New("自定义时间间隔错误,必须是大于0的值"), "自定义时间间隔错误,必须是大于0的值") | 	return errors.Wrap(errors.New("自定义时间间隔错误,必须是大于0的值"), "自定义时间间隔错误,必须是大于0的值") | ||||||
| } | } | ||||||
|  |  | ||||||
| // DealLogPathError 日志路径处理异常 | // DealLogPathError 日志路径处理异常 | ||||||
| // |  | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 4:31 下午 2021/1/2 |  | ||||||
| func DealLogPathError(err error, logPath string) error { | func DealLogPathError(err error, logPath string) error { | ||||||
| 	return errors.Wrapf(err, "日志路径检测处理异常, 日志路径 : %s", logPath) | 	return errors.Wrapf(err, "日志路径检测处理异常, 日志路径 : %s", logPath) | ||||||
| } | } | ||||||
|  |  | ||||||
| // LogSplitTypeError 日志切割类型错误 | // LogSplitTypeError 日志切割类型错误 | ||||||
| // |  | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 4:50 下午 2021/1/2 |  | ||||||
| func LogSplitTypeError(splitType string) error { | func LogSplitTypeError(splitType string) error { | ||||||
| 	return errors.Wrapf(errors.New("日志切割时间类型错误"), "日志切割时间类型错误, 传入类型 : %v", splitType) | 	return errors.Wrapf(errors.New("日志切割时间类型错误"), "日志切割时间类型错误, 传入类型 : %v", splitType) | ||||||
| } | } | ||||||
|  |  | ||||||
| // CreateIOWriteError 创建日志实例失败 | // CreateIOWriteError 创建日志实例失败 | ||||||
| // |  | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 5:20 下午 2021/1/2 |  | ||||||
| func CreateIOWriteError(err error) error { | func CreateIOWriteError(err error) error { | ||||||
| 	return errors.Wrapf(err, "创建日志实例失败") | 	return errors.Wrapf(err, "创建日志实例失败") | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										21
									
								
								logger.go
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								logger.go
									
									
									
									
									
								
							| @ -10,6 +10,7 @@ package logger | |||||||
| import ( | import ( | ||||||
| 	"io" | 	"io" | ||||||
| 	"os" | 	"os" | ||||||
|  | 	"time" | ||||||
|  |  | ||||||
| 	"git.zhangdeman.cn/zhangdeman/consts" | 	"git.zhangdeman.cn/zhangdeman/consts" | ||||||
|  |  | ||||||
| @ -23,11 +24,7 @@ import ( | |||||||
| ) | ) | ||||||
|  |  | ||||||
| // NewLogger 获取日志实例 | // NewLogger 获取日志实例 | ||||||
| // | func NewLogger(inputLoggerLevel LogLevel, splitConfig *RotateLogConfig, optionFunc ...SetLoggerOptionFunc) (*zap.Logger, error) { | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 5:05 下午 2021/1/2 |  | ||||||
| func NewLogger(inputLoggerLevel consts.LogLevel, splitConfig *RotateLogConfig, optionFunc ...SetLoggerOptionFunc) (*zap.Logger, error) { |  | ||||||
| 	if nil == splitConfig { | 	if nil == splitConfig { | ||||||
| 		return nil, errors.New("未配置日志切割规则") | 		return nil, errors.New("未配置日志切割规则") | ||||||
| 	} | 	} | ||||||
| @ -87,10 +84,6 @@ func NewLogger(inputLoggerLevel consts.LogLevel, splitConfig *RotateLogConfig, o | |||||||
| } | } | ||||||
|  |  | ||||||
| // NewConsoleLogger 获取控制台输出的日志实例 | // NewConsoleLogger 获取控制台输出的日志实例 | ||||||
| // |  | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 8:22 下午 2021/4/17 |  | ||||||
| func NewConsoleLogger(loggerLevel zapcore.Level, optionFunc ...SetLoggerOptionFunc) (*zap.Logger, error) { | func NewConsoleLogger(loggerLevel zapcore.Level, optionFunc ...SetLoggerOptionFunc) (*zap.Logger, error) { | ||||||
| 	o := &OptionLogger{} | 	o := &OptionLogger{} | ||||||
|  |  | ||||||
| @ -124,15 +117,11 @@ type Logger struct { | |||||||
| } | } | ||||||
|  |  | ||||||
| // getWriter 获取日志实例 | // getWriter 获取日志实例 | ||||||
| // |  | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 5:08 下午 2021/1/2 |  | ||||||
| func (l *Logger) getWriter() (io.Writer, error) { | func (l *Logger) getWriter() (io.Writer, error) { | ||||||
| 	option := make([]rotatelogs.Option, 0) | 	option := make([]rotatelogs.Option, 0) | ||||||
| 	option = append(option, rotatelogs.WithRotationTime(l.splitConfig.TimeInterval)) | 	option = append(option, rotatelogs.WithRotationTime(l.splitConfig.TimeInterval)) | ||||||
| 	if l.splitConfig.MaxAge > 0 { | 	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 ( | 	var ( | ||||||
| 		hook *rotatelogs.RotateLogs | 		hook *rotatelogs.RotateLogs | ||||||
| @ -149,10 +138,6 @@ type wsWriter struct { | |||||||
| } | } | ||||||
|  |  | ||||||
| // Write ws的writer | // Write ws的writer | ||||||
| // |  | ||||||
| // Author : go_developer@163.com<白茶清欢> |  | ||||||
| // |  | ||||||
| // Date : 22:24 2024/7/22 |  | ||||||
| func (w *wsWriter) Write(p []byte) (n int, err error) { | func (w *wsWriter) Write(p []byte) (n int, err error) { | ||||||
| 	if nil == wsLoggerConnect { | 	if nil == wsLoggerConnect { | ||||||
| 		return 0, nil | 		return 0, nil | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user