Files
v2ray_simple/utils/log.go
2023-01-01 00:30:32 +08:00

216 lines
5.3 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package utils
import (
"fmt"
"log"
"os"
"github.com/natefinch/lumberjack"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
const (
Log_debug = iota
Log_info
Log_warning
Log_error //error一般用于输出 some 连接/客户端协议 错误, 但不致命
Log_dpanic
Log_panic
Log_fatal
log_off //不支持不打印致命输出。既然致命 那么我们一定要尸检然后查看病因
DefaultLL = Log_info
)
// LogLevel 值越小越唠叨, 废话越多值越大打印的越少见log_开头的常量;
//
// 我们的loglevel具体值 与 zap的 loglevel+1 的含义等价
var (
LogLevel int
LogLevelForFile int = -1 //这一项如果非负,则控制台的日志等级按 LogLevel 走,日志文件登记按 LogLevelForFile 走, 否则都按 LogLevel 走
ZapLogger *zap.Logger
//日志输出文件名称
LogOutFileName string
)
func LogLevelStrList() (sl []string) {
sl = make([]string, 0, log_off)
for i := 0; i < log_off; i++ {
sl = append(sl, LogLevelStr(i))
}
return
}
func LogLevelStr(lvl int) string {
return zapcore.Level(lvl - 1).String()
}
func getZapLogFileWriteSyncer(fn string) zapcore.WriteSyncer {
return zapcore.AddSync(&lumberjack.Logger{
Filename: fn, //如果给出的路径不存在,则 lumberjack 包 会自动帮助我们创建文件夹
MaxSize: 10,
MaxBackups: 10,
MaxAge: 30,
Compress: false,
})
}
func LogLevel5CharList() (sl []string) {
sl = make([]string, 0, log_off)
for i := -1; i < log_off-1; i++ {
sl = append(sl, levelCapitalStrWith5Chars(zapcore.Level(i)))
}
return
}
// 为了输出日志保持整齐, 统一使用5字节长度的字符串, 少的加尾缀空格, 多的以 点号 进行缩写。
func levelCapitalStrWith5Chars(l zapcore.Level) string {
switch l {
case zapcore.DebugLevel:
return "DEBUG"
case zapcore.InfoLevel:
return "INFO "
case zapcore.WarnLevel:
return "WARN "
case zapcore.ErrorLevel:
return "ERROR"
case zapcore.DPanicLevel:
return "DPAN."
case zapcore.PanicLevel:
return "PANIC"
case zapcore.FatalLevel:
return "FATAL"
default:
return fmt.Sprintf("LVL.%d", l)
}
}
func capitalLevelEncoderWith5Chars(l zapcore.Level, enc zapcore.PrimitiveArrayEncoder) {
enc.AppendString(levelCapitalStrWith5Chars(l))
}
// 本作大量用到zap打印输出, 所以必须调用InitLog函数来初始化否则就会闪退
func InitLog(firstMsg string) {
atomicLevel := zap.NewAtomicLevel()
atomicLevel.SetLevel(zapcore.Level(LogLevel - 1))
consoleCore := zapcore.NewCore(zapcore.NewConsoleEncoder(zapcore.EncoderConfig{
MessageKey: "M",
LevelKey: "L",
TimeKey: "T",
FunctionKey: "func",
EncodeLevel: zapcore.CapitalColorLevelEncoder,
EncodeTime: zapcore.TimeEncoderOfLayout("2006-01-02 15:04:05.000"),
}), zapcore.AddSync(os.Stdout), atomicLevel)
willLogToFile := LogOutFileName != ""
if willLogToFile {
jsonConf := zap.NewProductionEncoderConfig()
jsonConf.EncodeTime = zapcore.TimeEncoderOfLayout("060102 150405.000") //用一种比较简短的方式输出时间,年月日 时分秒.毫秒。 年只需输出后两位数字即可, 不管Y2K问题
jsonConf.LevelKey = "L"
jsonConf.TimeKey = "T"
jsonConf.MessageKey = "M"
jsonConf.EncodeLevel = capitalLevelEncoderWith5Chars
var logfileLevel zapcore.LevelEnabler = atomicLevel
if LogLevelForFile >= 0 {
lff := zapcore.Level(LogLevelForFile - 1)
logfileLevel = zap.LevelEnablerFunc(func(lev zapcore.Level) bool {
return lev >= lff
})
}
jsonCore := zapcore.NewCore(zapcore.NewJSONEncoder(jsonConf), getZapLogFileWriteSyncer(LogOutFileName), logfileLevel)
ZapLogger = zap.New(zapcore.NewTee(consoleCore, jsonCore))
} else {
ZapLogger = zap.New(consoleCore)
}
if firstMsg != "" {
ZapLogger.Info(firstMsg, zap.Int("loglvl", LogLevel))
log.Println(firstMsg, LogLevel)
}
if willLogToFile {
ZapLogger.Info("zap log init complete.", zap.String("logfile", GetFilePath(LogOutFileName)))
} else {
ZapLogger.Info("zap log init complete.")
}
}
// assume ZapLogger is not nil.
func CanLogLevel(l int, msg string) *zapcore.CheckedEntry {
return ZapLogger.Check(zapcore.Level(l-1), msg)
}
func CanLogErr(msg string) *zapcore.CheckedEntry {
if LogLevel > Log_error || ZapLogger == nil {
return nil
}
return ZapLogger.Check(zap.ErrorLevel, msg)
}
func CanLogInfo(msg string) *zapcore.CheckedEntry {
if LogLevel > Log_info || ZapLogger == nil {
return nil
}
return ZapLogger.Check(zap.InfoLevel, msg)
}
func CanLogWarn(msg string) *zapcore.CheckedEntry {
if LogLevel > Log_warning || ZapLogger == nil {
return nil
}
return ZapLogger.Check(zap.WarnLevel, msg)
}
func CanLogDebug(msg string) *zapcore.CheckedEntry {
if LogLevel > Log_debug || ZapLogger == nil {
return nil
}
return ZapLogger.Check(zap.DebugLevel, msg)
}
func CanLogFatal(msg string) *zapcore.CheckedEntry {
if LogLevel > Log_fatal || ZapLogger == nil {
return nil
}
return ZapLogger.Check(zap.FatalLevel, msg)
}
// assume ZapLogger is not nil.
func Debug(msg string) {
ZapLogger.Debug(msg)
}
// assume ZapLogger is not nil.
func Info(msg string) {
ZapLogger.Info(msg)
}
// assume ZapLogger is not nil.
func Warn(msg string) {
ZapLogger.Warn(msg)
}
// assume ZapLogger is not nil.
func Error(msg string) {
ZapLogger.Error(msg)
}
// assume ZapLogger is not nil.
func Fatal(msg string) {
ZapLogger.Fatal(msg)
}