zaq寫入日誌

技术颜良發表於2024-07-02

func InitLogger() {
encoder := getEncoder()
writeSyncer := getLogWriter()
core := zapcore.NewCore(encoder, writeSyncer, zapcore.DebugLevel)

logger := zap.New(core)
sugarLogger = logger.Sugar()
}

func getEncoder() zapcore.Encoder {
return zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig())
}

func getLogWriter() zapcore.WriteSyncer {
file, _ := os.Create("./log/demo.log")
return zapcore.AddSync(file)
}
————————————————

版權宣告:本文為博主原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連結和本宣告。

原文連結:https://blog.csdn.net/qq_54015483/article/details/133795195

// Copyright © 2022 sealos.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package logger

import (
"fmt"
"os"
"strings"
"time"

"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"gopkg.in/natefinch/lumberjack.v2"
)

var (
defaultLogger *zap.Logger
)

// init default logger with only console output info above
func init() {
encoder := getEncoder()
writeSyncer := getLogWriter()
core := zapcore.NewCore(encoder, writeSyncer, zapcore.DebugLevel)
defaultLogger = zap.New(core)
}
func getEncoder() zapcore.Encoder {
return zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig())
}

func getLogWriter() zapcore.WriteSyncer {
file, _ := os.Create("./log/demo.log")
return zapcore.AddSync(file)
}

// CfgConsoleLogger config for console logs
// cfg donot support concurrent calls (as any package should init cfg at startup once)
func CfgConsoleLogger(debugMode bool, showPath bool) {
level, zos := genConfigs(debugMode, showPath)

zc := zapcore.NewTee(newConsoleCore(level))

defaultLogger = zap.New(zc, zos...)
}

// TODO: export more file configs
// CfgConsoleAndFileLogger config for both console and file logs
// cfg donot support concurrent calls (as any package should init cfg at startup once)
func CfgConsoleAndFileLogger(debugMode bool, logDir, name string, showPath bool) {
level, zos := genConfigs(debugMode, showPath)

filename := fmt.Sprintf("%s/%s.log", logDir, name)

zc := zapcore.NewTee(newConsoleCore(level), newFileCore(filename, level))

defaultLogger = zap.New(zc, zos...)
}

func genConfigs(debugMode bool, showPath bool) (zapcore.LevelEnabler, []zap.Option) {
level := zapcore.InfoLevel
if debugMode {
level = zapcore.DebugLevel
}

zos := []zap.Option{
// zap.AddStacktrace(zapcore.WarnLevel),
}
if showPath {
// skip self wrapper
zos = append(zos, zap.AddCaller(), zap.AddCallerSkip(2))
}

return level, zos
}

func newConsoleCore(le zapcore.LevelEnabler) zapcore.Core {
consoleLogger := zapcore.Lock(os.Stdout)

zec := zap.NewProductionEncoderConfig()
zec.EncodeLevel = zapcore.LowercaseColorLevelEncoder
zec.EncodeTime = zapcore.ISO8601TimeEncoder
zec.EncodeTime = shortTimeEncoder
// zec.EncodeTime = zapcore.ISO8601TimeEncoder
zec.ConsoleSeparator = " "

consoleEncoder := zapcore.NewConsoleEncoder(zec)

return zapcore.NewCore(consoleEncoder, consoleLogger, le)
}

func newFileCore(filename string, le zapcore.LevelEnabler) zapcore.Core {
//TODO: export more rotate configs
fileLogger := zapcore.AddSync(&lumberjack.Logger{
Filename: filename,
MaxSize: 10, // megabytes per file
})

zec := zap.NewProductionEncoderConfig()
zec.EncodeTime = zapcore.ISO8601TimeEncoder

fileEncoder := zapcore.NewJSONEncoder(zec)
return zapcore.NewCore(fileEncoder, fileLogger, le)
}

const shortTimeLayout = "2006-01-02T15:04:05"

func shortTimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
enc.AppendString(t.Format(shortTimeLayout))
}

// IsDebugMode check DebugLevel enabled
func IsDebugMode() bool {
return defaultLogger.Core().Enabled(zapcore.DebugLevel)
}

// Fatal logs a message at emergency level and exit.
func Fatal(f interface{}, v ...interface{}) {
defaultLogger.Sugar().Fatalf(formatLog(zapcore.FatalLevel, f, v...))
}

// Panic logs a message at emergency level and exit.
func Panic(f interface{}, v ...interface{}) {
defaultLogger.Sugar().Panicf(formatLog(zapcore.PanicLevel, f, v...))
}

// Error logs a message at error level.
func Error(f interface{}, v ...interface{}) {
defaultLogger.Sugar().Errorf(formatLog(zapcore.ErrorLevel, f, v...))
}

// Warn logs a message at warning level.
func Warn(f interface{}, v ...interface{}) {
defaultLogger.Sugar().Warnf(formatLog(zapcore.WarnLevel, f, v...))
}

// Info logs a message at info level.
func Info(f interface{}, v ...interface{}) {
defaultLogger.Sugar().Infof(formatLog(zapcore.InfoLevel, f, v...))
}

// Debug logs a message at debug level.
func Debug(f interface{}, v ...interface{}) {
defaultLogger.Sugar().Debugf(formatLog(zapcore.DebugLevel, f, v...))
}

func formatLog(l zapcore.Level, f interface{}, v ...interface{}) string {
var msg string
switch f := f.(type) {
case string:
msg = f
if len(v) == 0 {
return appendColor(l, msg)
}
if !strings.Contains(msg, "%") || strings.Contains(msg, "%%") {
// do not contain format char
msg += strings.Repeat(" %v", len(v))
}
default:
msg = fmt.Sprint(f)
if len(v) == 0 {
return appendColor(l, msg)
}
msg += strings.Repeat(" %v", len(v))
}
return appendColor(l, fmt.Sprintf(msg, v...))
}

func appendColor(l zapcore.Level, s string) string {
// default all red
c := uint8(31)
switch l {
case zapcore.DebugLevel:
c = uint8(35) // Magenta
case zapcore.InfoLevel:
c = uint8(34) // Blue
case zapcore.WarnLevel:
c = uint8(33) // Yellow
}
return fmt.Sprintf("\x1b[%dm%s\x1b[0m", c, s)
}

相關文章