4 Star 6 Fork 3

王军 / golib

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
log.go 10.00 KB
一键复制 编辑 原始数据 按行查看 历史
王军 提交于 2024-04-30 13:13 . .
package logs
import (
"encoding/json"
"fmt"
"io"
"os"
"path/filepath"
"runtime"
"strconv"
"strings"
"gitee.com/haodreams/libs/easy"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"gopkg.in/natefinch/lumberjack.v2"
)
var log *zap.Logger
var sugar *zap.SugaredLogger
// var config zapcore.EncoderConfig
var level *zap.AtomicLevel
var appName string
// 常量定义
const (
// LevelDebug defines debug log level.
LevelDebug = zap.DebugLevel
// LevelInfo defines info log level.
LevelInfo = zap.InfoLevel
// LevelWarn defines warn log level.
LevelWarn = zap.WarnLevel
// LevelError defines error log level.
LevelError = zap.ErrorLevel
AdapterConsole = "console"
AdapterFile = "file"
)
var multi = new(multiWriter)
func init() {
binaryPath, _ := filepath.Abs(os.Args[0])
name := filepath.Base(binaryPath)
appName = strings.TrimSuffix(name, filepath.Ext(name))
//默认的配置
log, _ = zap.NewProduction()
// sugar = log.Sugar()
config := zap.NewProductionEncoderConfig()
config.EncodeTime = zapcore.TimeEncoderOfLayout(easy.YYYYMMDDHHMMSSMill)
config.TimeKey = "time"
config.MessageKey = "message"
var encoder = zapcore.NewConsoleEncoder(config)
level = new(zap.AtomicLevel)
*level = zap.NewAtomicLevelAt(LevelDebug)
core := zapcore.NewCore(encoder, os.Stderr, level)
log = zap.New(core)
sugar = log.Sugar()
}
type multiWriter struct {
writers []zapcore.WriteSyncer
}
func (m *multiWriter) Sync() error {
for _, w := range m.writers {
w.Sync()
}
return nil
}
/**
* @description:
* @param {*}
* @return {*}
*/
func GetWriter() io.Writer {
return multi
}
func (m *multiWriter) Write(p []byte) (n int, err error) {
for _, w := range m.writers {
n, err = w.Write(p)
if err != nil {
return
}
if n != len(p) {
err = io.ErrShortWrite
return
}
}
return len(p), nil
}
/**
* @description: 获取app的名称
* @param {*}
* @return {*}
*/
func GetAppName() string {
return appName
}
func Exit(msg string, exitCode ...int) {
defer func() {
code := 255
if len(exitCode) > 0 {
code = exitCode[0]
}
os.Exit(code)
}()
if sugar == nil {
fmt.Println(msg)
} else {
Warn(msg)
}
f, err := os.OpenFile(appName+".log", os.O_RDWR|os.O_CREATE, 0666)
if err != nil {
fmt.Println("打开日志文件错误")
return
}
defer f.Close()
f.WriteString(msg)
f.WriteString("\n")
}
/**
* @description: 日志初始化
* @param {string} logType 日志类型 json/txt
* @param {bool} haveColor 日志是否输出颜色
* @return {*}
*/
func Init(logType string, haveColor bool) {
config := zap.NewProductionEncoderConfig()
config.EncodeTime = zapcore.TimeEncoderOfLayout(easy.YYYYMMDDHHMMSSMill)
if haveColor {
config.EncodeLevel = zapcore.CapitalColorLevelEncoder
}
config.TimeKey = "time"
config.MessageKey = "message"
var encoder zapcore.Encoder
if logType == "json" {
encoder = zapcore.NewJSONEncoder(config)
} else {
encoder = zapcore.NewConsoleEncoder(config)
}
level = new(zap.AtomicLevel)
*level = zap.NewAtomicLevelAt(LevelInfo)
core := zapcore.NewCore(encoder, multi, level)
log = zap.New(core)
sugar = log.Sugar()
}
// SetLevel sets the global log level used by the simple logger.
func SetLevel(l zapcore.Level) {
level.SetLevel(l)
level.Level()
}
func Level() int {
return int(level.Level())
}
/**
* @description: 用字符串的方式设置日志级别
* @param {string} l
* @return {*}
*/
func SetStringLevel(l string) {
l = strings.ToLower(l)
switch l {
case "error":
SetLevel(LevelError)
case "warn", "warning":
SetLevel(LevelWarn)
case "info", "informational":
SetLevel(LevelInfo)
case "debug":
SetLevel(LevelDebug)
}
}
// SetLogFuncCall set the CallDepth, default is 4
// func SetLogFuncCall(b bool) {
// //logger = logger.Hook(ch)
// }
// SetLogFuncCallDepth set log funcCallDepth
// func SetLogFuncCallDepth(d int) {
// //ch.callerSkipFrameCount = d + 1
// }
// SetLogger sets a new logger.
// 每种类型只能调用一次
func SetLogger(adapter string, config ...string) error {
switch adapter {
case AdapterConsole:
multi.writers = append(multi.writers, os.Stdout)
case AdapterFile:
l := new(lumberjack.Logger)
l.LocalTime = true
if len(config) > 0 {
err := json.Unmarshal([]byte(config[0]), l)
if err != nil {
fmt.Println(err)
}
}
if l.MaxAge <= 0 {
l.MaxAge = 30
}
l.MaxSize /= 1024 * 1024
if l.MaxSize <= 0 {
l.MaxSize = 1
}
if l.MaxSize > 50 {
l.MaxSize = 50
}
multi.writers = append(multi.writers, zapcore.AddSync(l))
default:
return fmt.Errorf("%s 不支持的log 记录器", adapter)
}
return nil
}
// AddWriter .
func AddWriter(w io.Writer) {
multi.writers = append(multi.writers, zapcore.AddSync(w))
}
// Errorf logs a message at error level.
func Errorf(f string, v ...interface{}) {
if !level.Enabled(zap.ErrorLevel) {
return
}
sugar.Errorw(formatLogf(Where(2)+f, v...))
}
// Warnf compatibility alias for Warning()
func Warnf(f string, v ...interface{}) {
if !level.Enabled(zap.WarnLevel) {
return
}
sugar.Warnw(formatLogf(Where(2)+f, v...))
}
// Infof compatibility alias for Warning()
func Infof(f string, v ...interface{}) {
if !level.Enabled(zap.InfoLevel) {
return
}
sugar.Infow(formatLogf(Where(2)+f, v...))
}
// Debugf logs a message at debug level.
func Debugf(f string, v ...interface{}) {
if !level.Enabled(zap.DebugLevel) {
return
}
sugar.Debugw(formatLogf(Where(2)+f, v...))
}
// Error logs a message at error level.
func Error(v ...interface{}) {
if !level.Enabled(zap.ErrorLevel) {
return
}
sugar.Errorw(Where(2) + formatLog(v...))
}
// Warn compatibility alias for Warning()
func Warn(v ...interface{}) {
if !level.Enabled(zap.WarnLevel) {
return
}
sugar.Warnw(Where(2) + formatLog(v...))
}
// Info compatibility alias for Warning()
func Info(v ...interface{}) {
if !level.Enabled(zap.InfoLevel) {
return
}
sugar.Infow(Where(2) + formatLog(v...))
}
// Debug logs a message at debug level.
func Debug(v ...interface{}) {
if !level.Enabled(zap.DebugLevel) {
return
}
sugar.Debugw(Where(2) + formatLog(v...))
}
// Error logs a message at error level.
func LiteError(s string, v ...interface{}) {
if !level.Enabled(zap.ErrorLevel) {
return
}
sugar.Errorw(s + formatLog(v...))
}
// Warn compatibility alias for Warning()
func LiteWarn(s string, v ...interface{}) {
if !level.Enabled(zap.WarnLevel) {
return
}
sugar.Warnw(s + formatLog(v...))
}
// Info compatibility alias for Warning()
func LiteInfo(s string, v ...interface{}) {
if !level.Enabled(zap.InfoLevel) {
return
}
sugar.Infow(s + formatLog(v...))
}
// Debug logs a message at debug level.
func LiteDebug(s string, v ...interface{}) {
if !level.Enabled(zap.DebugLevel) {
return
}
sugar.Debugw(s + formatLog(v...))
}
// Info compatibility alias for Warning()
func Msg(msg string, level ...int) {
if len(level) == 0 {
sugar.Infow(msg)
return
}
switch level[0] {
case 0:
sugar.Errorw(msg)
case 1:
sugar.Warnw(msg)
case 3:
sugar.Debugw(msg)
default:
sugar.Infow(msg)
}
}
// CbError logs a message at error level.
func CbError(v ...interface{}) {
if !level.Enabled(zap.ErrorLevel) {
return
}
sugar.Errorw(Where(3) + formatLog(v...))
}
// CbWarn compatibility alias for Warning()
func CbWarn(v ...interface{}) {
if !level.Enabled(zap.WarnLevel) {
return
}
sugar.Warnw(Where(3) + formatLog(v...))
}
// CbInfo compatibility alias for Warning()
func CbInfo(v ...interface{}) {
if !level.Enabled(zap.InfoLevel) {
return
}
sugar.Infow(Where(3) + formatLog(v...))
}
// CbDebug logs a message at debug level.
func CbDebug(v ...interface{}) {
if !level.Enabled(zap.DebugLevel) {
return
}
sugar.Debugw(Where(3) + formatLog(v...))
}
// CbErrorf logs a message at error level.
func CbErrorf(format string, v ...interface{}) {
if !level.Enabled(zap.ErrorLevel) {
return
}
sugar.Errorw(formatLogf(Where(3)+format, v...))
}
// CbWarnf compatibility alias for Warning()
func CbWarnf(format string, v ...interface{}) {
if !level.Enabled(zap.WarnLevel) {
return
}
sugar.Warnw(formatLogf(Where(3)+format, v...))
}
// CbInfof compatibility alias for Warning()
func CbInfof(format string, v ...interface{}) {
if !level.Enabled(zap.InfoLevel) {
return
}
sugar.Infow(formatLogf(Where(3)+format, v...))
}
// CbDebugf logs a message at debug level.
func CbDebugf(format string, v ...interface{}) {
if !level.Enabled(zap.DebugLevel) {
return
}
sugar.Debugw(formatLogf(Where(3)+format, v...))
}
// Where .
func Where(l int) string {
frame, ok := GetCallerFrame(l)
if ok {
return TrimmedPath(frame) + " "
}
return "??? "
}
func formatLogf(msg string, v ...interface{}) string {
if strings.Contains(msg, "%") && !strings.Contains(msg, "%%") {
//format string
} else {
//do not contain format char
msg += strings.Repeat(" %v", len(v))
}
return fmt.Sprintf(msg, v...)
}
func formatLog(v ...interface{}) string {
msg := fmt.Sprintln(v...)
n := len(msg)
if n > 0 {
msg = msg[:n-1]
}
return msg
}
func GetCallerFrame(skip int) (frame *runtime.Frame, ok bool) {
const skipOffset = 2 // skip getCallerFrame and Callers
pc := make([]uintptr, 1)
numFrames := runtime.Callers(skip+skipOffset, pc)
if numFrames < 1 {
return
}
frame1, _ := runtime.CallersFrames(pc).Next()
frame = &frame1
return frame, frame.PC != 0
}
func TrimmedPath(frame *runtime.Frame) string {
idx := strings.LastIndexByte(frame.File, '/')
if idx == -1 {
return frame.File + ":" + strconv.Itoa(frame.Line)
}
// Find the penultimate separator.
idx = strings.LastIndexByte(frame.File[:idx], '/')
if idx == -1 {
return frame.File + ":" + strconv.Itoa(frame.Line)
}
return frame.File[idx+1:] + ":" + strconv.Itoa(frame.Line)
}
Go
1
https://gitee.com/haodreams/golib.git
git@gitee.com:haodreams/golib.git
haodreams
golib
golib
56c05e20dd3e

搜索帮助