1 Star 0 Fork 0

h79/goutils

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
log.go 7.62 KB
一键复制 编辑 原始数据 按行查看 历史
package logger
import (
"flag"
"fmt"
"gitee.com/h79/goutils/common/system"
"github.com/natefinch/lumberjack"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"io"
"os"
"path"
"runtime/debug"
)
var (
NDebugEnabled = false
logger *zap.Logger
)
type Config struct {
Level int8 `json:"level" yaml:"level" xml:"level"`
NDebug string `json:"ndebug" yaml:"ndebug" xml:"ndebug"`
WriterEnabled bool `json:"writerEnabled" yaml:"writerEnabled" xml:"writerEnabled"` // 自己实现writer
ConsoleEnabled bool `json:"console" yaml:"console" xml:"console"`
FileEnabled bool `json:"fileEnabled" yaml:"fileEnabled" xml:"fileEnabled"`
EncoderFormat string `json:"encoderFormat" yaml:"encoderFormat" xml:"encoderFormat"`
FilePath string `json:"filePath" yaml:"filePath" xml:"filePath"`
FileConfigs []FileConfig `json:"fileConfigs" yaml:"fileConfigs" xml:"fileConfigs"`
WriterConfigs []WriterConfig `json:"writerConfigs" yaml:"writerConfigs" xml:"writerConfigs"`
}
type LevelRange struct {
MinLevel int8 `json:"minLevel" yaml:"minLevel" xml:"minLevel"`
MaxLevel int8 `json:"maxLevel" yaml:"maxLevel" xml:"maxLevel"`
}
type FileConfig struct {
LevelRange
// Name is the name of the logfile which will be placed inside the directory
Name string `json:"name" yaml:"name" xml:"name"`
// MaxSize the max size in MB of the logfile before it's rolled
MaxSize int `json:"maxSize" yaml:"maxSize" xml:"maxSize"`
// MaxBackups the max number of rolled files to keep
MaxBackups int `json:"backupNum" yaml:"backupNum" xml:"backupNum"`
// MaxAge the max age in days to keep a logfile
MaxAge int `json:"days" json:"days" xml:"days"`
}
type WriterConfig struct {
LevelRange
W io.Writer
}
// 对外进行统一的封装
const (
// RecoverLevel ()
RecoverLevel = int8(-3)
// NDebugLevel ()
NDebugLevel = int8(-2)
DebugLevel = int8(zap.DebugLevel)
InfoLevel = int8(zap.InfoLevel)
// WarnLevel defines warn log level.
WarnLevel = int8(zap.WarnLevel)
// ErrorLevel defines error log level.
ErrorLevel = int8(zap.ErrorLevel)
// FatalLevel defines fatal log level.
FatalLevel = int8(zap.FatalLevel)
// PanicLevel defines panic log level.
PanicLevel = int8(zap.PanicLevel)
)
func init() {
flag.BoolVar(&NDebugEnabled, "ndebug", true, "not output debug log in release.")
system.DefRecoverFunc = func(r any) {
Recover(6, r)
}
if err := Configure(Config{ConsoleEnabled: true, Level: int8(zap.DebugLevel)}); err != nil {
panic("init log failure")
}
}
func Byte2(level int8, b []byte) string {
if level == NDebugLevel {
if NDebugEnabled {
return string(b)
}
return ""
}
if zap.L().Core().Enabled(zapcore.Level(level)) {
return string(b)
}
return ""
}
// Info defines info log level.
func Info(format string, args ...interface{}) {
if ce := logger.Check(zapcore.InfoLevel, ""); ce != nil {
ce.Write(ZLogf(format, args...))
}
}
// Warn defines warn log level.
func Warn(format string, args ...interface{}) {
if ce := logger.Check(zapcore.WarnLevel, ""); ce != nil {
ce.Write(ZLogf(format, args...))
}
}
// Error defines error log level.
func Error(format string, args ...interface{}) {
if ce := logger.Check(zapcore.ErrorLevel, ""); ce != nil {
ce.Write(ZLogf(format, args...))
}
}
// Recover defines error log level.
func Recover(callerSkip int, err interface{}) {
if callerSkip <= 0 {
callerSkip = 2
}
lg := zap.L()
lg = lg.WithOptions(zap.AddCallerSkip(callerSkip))
if ce := lg.Check(zapcore.Level(RecoverLevel), "recover"); ce != nil {
ce.Write(zap.Any("err", err), zap.String("stack", string(debug.Stack())))
}
}
// Fatal defines fatal log level.
func Fatal(format string, args ...interface{}) {
if ce := logger.Check(zapcore.FatalLevel, ""); ce != nil {
ce.Write(ZLogf(format, args...))
}
}
// Panic (format string, args ...interface{}) { defines panic log level.
func Panic(format string, args ...interface{}) {
if ce := logger.Check(zapcore.PanicLevel, ""); ce != nil {
ce.Write(ZLogf(format, args...))
}
}
func Debug(format string, args ...interface{}) {
if ce := logger.Check(zapcore.DebugLevel, ""); ce != nil {
ce.Write(ZLogf(format, args...))
}
}
// NDebug
/**
正式环境,不输出日志
*/
func NDebug(format string, args ...interface{}) {
if !NDebugEnabled {
return
}
if ce := logger.Check(zapcore.DebugLevel, ""); ce != nil {
ce.Write(ZLogf(format, args...))
}
}
func SpecW(level int8, msg string, fields ...zapcore.Field) {
if ce := logger.Check(zapcore.Level(level), msg); ce != nil {
ce.Write(fields...)
}
}
func ZLog(info string) zap.Field {
return zap.String("log", info)
}
func ZLogf(format string, args ...any) zap.Field {
return zap.String("log", fmt.Sprintf(format, args...))
}
type Options struct {
FileConfig *FileConfig
WriterConfig *WriterConfig
}
type OptionFunc func(opts *Options)
func Configure(config Config, opts ...OptionFunc) error {
var (
cores []zapcore.Core
encoder zapcore.Encoder
)
if config.NDebug == "true" {
NDebugEnabled = true
} else if config.NDebug == "false" {
NDebugEnabled = false
}
if config.ConsoleEnabled {
writer := zapcore.Lock(os.Stdout)
encoder = zapcore.NewConsoleEncoder(zap.NewDevelopmentEncoderConfig())
cores = append(cores, zapcore.NewCore(encoder, writer, zapcore.Level(config.Level)))
}
if config.EncoderFormat == "console" {
encoder = zapcore.NewConsoleEncoder(zap.NewProductionEncoderConfig())
} else {
encoder = jsonEncoder()
}
//可以按级别写入不同的文件 zap.LevelEnablerFunc()
if config.FileEnabled {
if err := os.MkdirAll(config.FilePath, 0744); err != nil {
return fmt.Errorf("can't create log directory, path= '%s'", config.FilePath)
}
for i := range config.FileConfigs {
for ii := range opts {
opts[ii](&Options{FileConfig: &config.FileConfigs[i]})
}
var fileConfig = config.FileConfigs[i]
var levelEnable = zap.LevelEnablerFunc(func(level zapcore.Level) bool {
return level < zapcore.Level(fileConfig.MaxLevel) && level >= zapcore.Level(fileConfig.MinLevel)
})
fileConfig.Name = path.Join(config.FilePath, fileConfig.Name)
w, err := newRollingFile(fileConfig)
if err != nil {
return err
}
writer := zapcore.AddSync(w)
cores = append(cores, zapcore.NewCore(encoder, writer, levelEnable))
}
}
if config.WriterEnabled {
for i := range config.WriterConfigs {
for ii := range opts {
opts[ii](&Options{WriterConfig: &config.WriterConfigs[i]})
}
var writerConfig = config.WriterConfigs[i]
var levelEnable = zap.LevelEnablerFunc(func(level zapcore.Level) bool {
return level < zapcore.Level(writerConfig.MaxLevel) && level >= zapcore.Level(writerConfig.MinLevel)
})
if writerConfig.W == nil {
continue
}
writer := zapcore.AddSync(writerConfig.W)
cores = append(cores, zapcore.NewCore(encoder, writer, levelEnable))
}
}
if len(cores) > 0 {
lg := zap.New(zapcore.NewTee(cores...), zap.AddCaller())
zap.ReplaceGlobals(lg)
}
logger = zap.L().WithOptions(zap.AddCallerSkip(1))
return nil
}
func jsonEncoder() zapcore.Encoder {
encoderConfig := zap.NewProductionEncoderConfig()
encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
encoderConfig.EncodeDuration = zapcore.SecondsDurationEncoder
encoderConfig.EncodeCaller = zapcore.ShortCallerEncoder
encoderConfig.TimeKey = "time"
return zapcore.NewJSONEncoder(encoderConfig)
}
func Context() *zap.Logger {
return zap.L()
}
func newRollingFile(file FileConfig) (io.Writer, error) {
return &lumberjack.Logger{
Filename: file.Name,
MaxBackups: file.MaxBackups, // files
MaxSize: file.MaxSize, // megabytes
MaxAge: file.MaxAge, // days
}, nil
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/h79/goutils.git
git@gitee.com:h79/goutils.git
h79
goutils
goutils
v1.8.42

搜索帮助

A270a887 8829481 3d7a4017 8829481