golang中日志打印使用的工具zap
- zap是Uber开源的日志库;
- 很多的公司都在使用;
- 跟seelog、logrus等类库相比,高性能是它最突出的优势.
zap基本配置的介绍
EncoderConfig配置说明
- MessageKey:输入信息的key名;
- LevelKey:输出日志级别的key名;
- TimeKey:输出时间的key名;
- LineEnding:每行的分隔符;
- EncodeTime:输出的时间格式;
- ConsoleSeparator`:每行日志中每个field之间的分隔符
zap的使用
1、定义全局变量和日志标识
var logger *zap.Logger
var logKeyMap = map[string]interface{}{
"RequestId": 1001,
"LogMark": 1002,
"LogMsg": 1003,
}
2、定义EncodeTime的获取函数:
func GetEncoderTime() func(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
return func(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
enc.AppendString(strings.Join([]string{"TestLogFormat", t.Format("2006-01-02 15:04:05")}, "|"))
}
}
3、定义Logger的初始化函数
func GetLogger() {encoder := zapcore.NewConsoleEncoder(
zapcore.EncoderConfig{
TimeKey: "ts",
LevelKey: "level",
MessageKey: "msg",
LineEnding: "\n",
EncodeTime: GetEncoderTime(),
ConsoleSeparator: "|",
},
)
logPath := "d:/log.txt"
writer, _ := os.OpenFile(logPath, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0666)
// logWritter := zapcore.AddSync(os.Stdout)
logWritter := zapcore.AddSync(writer)
logger = zap.New(zapcore.NewCore(encoder, logWritter, zapcore.DebugLevel))
defer logger.Sync()
}
4、定义将任意类型转化为String的函数
func String(any interface{}) string {
if any == nil {
return ""
}
switch value := any.(type) {
case int:
return strconv.Itoa(value)
case int8:
return strconv.Itoa(int(value))
case int16:
return strconv.Itoa(int(value))
case int32:
return strconv.Itoa(int(value))
case int64:
return strconv.FormatInt(value, 10)
case uint:
return strconv.FormatUint(uint64(value), 10)
case uint8:
return strconv.FormatUint(uint64(value), 10)
case uint16:
return strconv.FormatUint(uint64(value), 10)
case uint32:
return strconv.FormatUint(uint64(value), 10)
case uint64:
return strconv.FormatUint(value, 10)
case float32:
return strconv.FormatFloat(float64(value), 'f', -1, 32)
case float64:
return strconv.FormatFloat(value, 'f', -1, 64)
case bool:
return strconv.FormatBool(value)
case string:
return value
case []byte:
return string(value)
case time.Time:
if value.IsZero() {
return ""
}
return value.String()
case *time.Time:
if value == nil {
return ""
}
return value.String()
default:
// Empty checks.
if value == nil {
return ""
}
// Reflect checks.
var (
rv = reflect.ValueOf(value)
kind = rv.Kind()
)
switch kind {
case reflect.Chan,
reflect.Map,
reflect.Slice,
reflect.Func,
reflect.Ptr,
reflect.Interface,
reflect.UnsafePointer:
if rv.IsNil() {
return ""
}
case reflect.String:
return rv.String()
}
if kind == reflect.Ptr {
return String(rv.Elem().Interface())
}
// Finally we use json.Marshal to convert.
if jsonContent, err := json.Marshal(value); err != nil {
return fmt.Sprint(value)
} else {
return string(jsonContent)
}
}
}
5、定义Info日志打印函数
func Info(msg, mark string) {
logMap := make(map[interface{}]interface{})
logMap["Info"] = "test log info....."
logMap["LogMark"] = mark
logMap["LogMsg"] = msg
logMap["RequestId"] = "testRequestId"
logField := make([]zap.Field, 0)
for key, value := range logMap {
keyIndex, ok := logKeyMap[String(key)]
if ok {
logField = append(logField, zap.Reflect(String(keyIndex), value))
} else {
logField = append(logField, zap.Reflect(String(key), value))
}
}
logger.Info("INFO", logField...)
}
6、调用函数打印日志,日志格式如下:
Info("how log can print in terminal....", "TestMark")
TestLogFormat|2024-06-25 15:52:00|INFO|{"Info": "test log info.....", "1002": "TestMark", "1003": "how log can print in terminal....", "1001": "testRequestId"}