Loading

封装 logrus

封装 logrus

Golang 常用的 log 库

golang 标准库的 log 也很好用,但是缺乏一些特性功能,新能较差,所以社区衍生出如下日志库:

  • logrus 可能是最早的第三方日志库
  • uber_zap 优步推出的高性能日志库
  • go-kit 基于 kit 产生了很多的衍生品,例如:
  • google_glog_分支klog 大名鼎鼎的 kubernetes 使用的日志库特点在于增加了缓存,flush 机制。

我遇见的问题

例如:

package main

import (
	log "github.com/sirupsen/logrus"
)

func main() {
    // Add this line for logging filename and line number!
	log.SetReportCaller(true)

	log.Println("hello world")
}

输出:

INFO[0000]/Users/hello/go/src/github.com/bob/test/main.go:17 main.main() hello world

如何曲线救国

go build -v -a -ldflags '-w -s' \
    -gcflags="all=-trimpath=${PWD}" \
    -asmflags="all=-trimpath=${PWD}" \
    -o ./app main.go

官方解决方案

社区 issue:

虽然官方提供了一个解决方案:

但是在我的项目里调用的时候总觉得奇奇怪怪:

例如:

// log pkg
package mylog

import (
    "github.com/sirupsen/logrus"
) 

var Log = logrus.New()

func init(){
    log.SetReportCaller(true)
	log.Formatter = &logrus.TextFormatter{
		CallerPrettyfier: func(f *runtime.Frame) (string, string) {
			repopath := fmt.Sprintf("%s/src/github.com/bob", os.Getenv("GOPATH"))
			filename := strings.Replace(f.File, repopath, "", -1)
			return fmt.Sprintf("%s()", f.Function), fmt.Sprintf("%s:%d", filename, f.Line)
		},
	}

}

// caller func
package app
import (
    "myapp/mylog"
)

func AppFunc(){
    // 这里要多写一层
    mylog.Log.Info("hello world")
}

封装 logrus

// mylog

package mylog

import (
	"fmt"
	"os"
	"path"
	"runtime"

	"github.com/sirupsen/logrus"
)

type mylogger struct {
	fp    string
	funcn string
	l     *logrus.Logger
}

var log = &mylogger{
	l: logrus.New(),
}

func init() {
	log.l.SetOutput(os.Stdout)
	log.l.SetFormatter(&logrus.JSONFormatter{
		TimestampFormat: "2006-01-02T15:04:05",
	})
}

// getCallerInfo 获取调用者的函数名,调用行
func (l *mylogger) getCallerInfo() {
	// 调用链往上翻三层,找到调用函数的信息
	pc, file, line, ok := runtime.Caller(3)
	if !ok {
		return
	}
	funcName := runtime.FuncForPC(pc).Name()
	l.funcn = path.Base(funcName)

	_, fileName := path.Split(file)
	l.fp = fmt.Sprintf("%s:%d", fileName, line)
}

// printer 日志处理函数
func (l *mylogger) printer(level logrus.Level, msg ...interface{}) {
	log.getCallerInfo()
	l.l.WithFields(logrus.Fields{"filePath": l.fp, "func": l.funcn}).Log(level, msg...)
}

// printerf 格式化日志处理
func (l *mylogger) printerf(level logrus.Level, format string, msg ...interface{}) {
	log.getCallerInfo()
	l.l.WithFields(logrus.Fields{"filePath": l.fp, "func": l.funcn}).Logf(level, format, msg...)
}

func Info(msg ...interface{}) {
	log.printer(logrus.InfoLevel, msg...)
}

func Infof(format string, msg ...interface{}) {
	log.printerf(logrus.InfoLevel, format, msg...)
}

func Debug(msg ...interface{}) {
	log.printer(logrus.DebugLevel, msg...)
}

func Error(msg ...interface{}) {
	log.printer(logrus.ErrorLevel, msg...)
}

func Errorf(format string, msg ...interface{}) {
	log.printerf(logrus.ErrorLevel, format, msg...)
}
posted @ 2022-09-15 15:22  尚墨  阅读(702)  评论(0编辑  收藏  举报