1 Star 0 Fork 0

h79/goutils

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
log.go 10.51 KB
一键复制 编辑 原始数据 按行查看 历史
huqiuyun 提交于 2023-12-15 18:58 . add writeType in WriteConfig
package logger
import (
"context"
"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 bool `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"`
hooks []func(entry zapcore.Entry) error
}
type FileConfig struct {
MinLevel int8 `json:"minLevel" yaml:"minLevel" xml:"minLevel"`
MaxLevel int8 `json:"maxLevel" yaml:"maxLevel" xml:"maxLevel"`
// 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 {
MinLevel int8 `json:"minLevel" yaml:"minLevel" xml:"minLevel"`
MaxLevel int8 `json:"maxLevel" yaml:"maxLevel" xml:"maxLevel"`
WriteType string `json:"type" yaml:"type" xml:"type"`
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 ""
}
const msg = "system"
// Info defines info log level.
func Info(format string, args ...interface{}) {
if ce := logger.Check(zapcore.InfoLevel, msg); ce != nil {
ce.Write(ZLogf(format, args...))
}
}
// I defines info log level.
func I(msg, format string, args ...interface{}) {
if ce := logger.Check(zapcore.InfoLevel, msg); ce != nil {
ce.Write(ZLogf(format, args...))
}
}
// Warn defines warn log level.
func Warn(format string, args ...interface{}) {
if ce := logger.Check(zapcore.WarnLevel, msg); ce != nil {
ce.Write(ZLogf(format, args...))
}
}
// W defines warn log level.
func W(msg, format string, args ...interface{}) {
if ce := logger.Check(zapcore.WarnLevel, msg); ce != nil {
ce.Write(ZLogf(format, args...))
}
}
// Error defines error log level.
func Error(format string, args ...interface{}) {
if ce := logger.Check(zapcore.ErrorLevel, msg); ce != nil {
ce.Write(ZLogf(format, args...))
}
}
// E defines error log level.
func E(msg, format string, args ...interface{}) {
if ce := logger.Check(zapcore.ErrorLevel, msg); 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, msg); ce != nil {
ce.Write(ZLogf(format, args...))
}
}
// F defines fatal log level.
func F(msg, format string, args ...interface{}) {
if ce := logger.Check(zapcore.FatalLevel, msg); 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, msg); ce != nil {
ce.Write(ZLogf(format, args...))
}
}
// P (format string, args ...interface{}) { defines panic log level.
func P(msg, format string, args ...interface{}) {
if ce := logger.Check(zapcore.PanicLevel, msg); ce != nil {
ce.Write(ZLogf(format, args...))
}
}
func Debug(format string, args ...interface{}) {
if ce := logger.Check(zapcore.DebugLevel, msg); ce != nil {
ce.Write(ZLogf(format, args...))
}
}
func D(msg, format string, args ...interface{}) {
if ce := logger.Check(zapcore.DebugLevel, msg); ce != nil {
ce.Write(ZLogf(format, args...))
}
}
// NDebug
/**
正式环境,不输出日志
*/
func NDebug(format string, args ...interface{}) {
if !ndebugEnabled {
return
}
if ce := logger.Check(zapcore.DebugLevel, msg); ce != nil {
ce.Write(ZLogf(format, args...))
}
}
func N(msg, format string, args ...interface{}) {
if !ndebugEnabled {
return
}
if ce := logger.Check(zapcore.DebugLevel, msg); 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...))
}
func TraceId(ctx context.Context) string {
ret, ok := ctx.Value("traceId").(string)
if ok {
return ret
}
return ""
}
func NTraceId(ctx context.Context) string {
if !ndebugEnabled {
return ""
}
return DTraceId(ctx)
}
func DTraceId(ctx context.Context) string {
if L().Core().Enabled(zapcore.DebugLevel) {
return TraceId(ctx)
}
return ""
}
func WTraceId(ctx context.Context) string {
if L().Core().Enabled(zapcore.WarnLevel) {
return TraceId(ctx)
}
return ""
}
func ITraceId(ctx context.Context) string {
if L().Core().Enabled(zapcore.InfoLevel) {
return TraceId(ctx)
}
return ""
}
func ETraceId(ctx context.Context) string {
if L().Core().Enabled(zapcore.ErrorLevel) {
return TraceId(ctx)
}
return ""
}
type Option func(config *Config)
func WithWriterLevel(level int8, w io.Writer) Option {
return func(config *Config) {
if !config.WriterEnabled {
return
}
for i := range config.WriterConfigs {
if config.WriterConfigs[i].MinLevel == level {
config.WriterConfigs[i].w = w
}
}
}
}
func WithWriterType(writeType string, w io.Writer) Option {
return func(config *Config) {
if !config.WriterEnabled {
return
}
for i := range config.WriterConfigs {
if config.WriterConfigs[i].WriteType == writeType {
config.WriterConfigs[i].w = w
}
}
}
}
func WithHook(hook func(entry zapcore.Entry) error) Option {
return func(config *Config) {
config.hooks = append(config.hooks, hook)
}
}
func WithNDebug(enabled bool) Option {
return func(config *Config) {
config.NDebug = enabled
}
}
func SetNDebug(enable bool) {
ndebugEnabled = enable
}
func IsNDebug() bool {
return ndebugEnabled
}
func Configure(config Config, opts ...Option) error {
var cores []zapcore.Core
var encoder zapcore.Encoder
for ii := range opts {
opts[ii](&config)
}
SetNDebug(config.NDebug)
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 {
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 {
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), zap.Hooks(config.hooks...))
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)
}
// Context
// Deprecated: this function simply calls L.
func Context() *zap.Logger {
return zap.L()
}
func L() *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.20.24

搜索帮助