Merge pull request '优化日志数据结构以及数据构建' (#6) from feature/upgrade_logger into master

Reviewed-on: #6
This commit is contained in:
2025-10-31 12:29:50 +08:00
9 changed files with 244 additions and 346 deletions

126
config.go
View File

@ -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
View 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" // 缓存日志
)

View File

@ -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
View File

@ -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

View File

@ -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, "创建日志实例失败")
}

View File

@ -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
View File

@ -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/op_any"
"go.uber.org/zap"
)
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 ""
}
// 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
}

View File

@ -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
}

View File

@ -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 {