mirror of
https://github.com/e1732a364fed/v2ray_simple.git
synced 2025-12-24 13:27:56 +08:00
206 lines
5.0 KiB
Go
206 lines
5.0 KiB
Go
package utils
|
||
|
||
import (
|
||
"fmt"
|
||
"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,
|
||
})
|
||
}
|
||
|
||
// 为了输出日志保持整齐, 统一使用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)
|
||
}
|
||
|
||
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)
|
||
}
|