1 Star 2 Fork 3

kristas/booting-go

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
log_adapter.go 2.99 KB
一键复制 编辑 原始数据 按行查看 历史
package logging
import (
"fmt"
"gitee.com/kristas/booting-go/framework/config"
"github.com/sirupsen/logrus"
"runtime"
"strings"
)
func CreateLog(name string) interface{} {
switch name {
case "", "logrus", "logrus.Logger":
return new(logrusAdapter).createLog()
default:
return new(logrusAdapter).createLog()
}
}
type Config struct {
Level string `yaml:"level"`
}
type logrusAdapter struct {
}
func (r *logrusAdapter) createLog() *logrus.Logger {
c := new(Config)
config.ReadConfig("logging",c)
logger := logrus.New()
level, err := logrus.ParseLevel(c.Level)
if err != nil {
level, _ = logrus.ParseLevel("INFO")
}
logger.SetLevel(level)
logger.SetReportCaller(true)
logger.SetFormatter(new(FrameFormatter))
logger.AddHook(&lineHook{
Skip: 3,
})
return logger
}
type FrameFormatter struct {
}
func (f *FrameFormatter) Format(entry *logrus.Entry) ([]byte, error) {
data := entry.Data
s := fmt.Sprintf("[%s][%5s][%s][%s] - %s ",
entry.Time.Format("2006-01-02 15:04:05.000"),
strings.ToUpper(entry.Level.String()),
fmt.Sprintf("%s:%d", data["file"], data["line"]),
fmt.Sprintf("%s.%s", data["packageName"], data["funcName"]),
entry.Message)
var skipField = []string{"file", "line", "packageName", "funcName"}
for k, v := range data {
if !contains(skipField, k) {
s += fmt.Sprintf("[%s = %s]", k, v)
}
}
return append([]byte(s), '\n'), nil
}
func contains(arr []string, str string) bool {
for i := range arr {
if arr[i] == str {
return true
}
}
return false
}
// line number hook for log the call context,
type lineHook struct {
// skip为遍历调用栈开始的索引位置
Skip int
levels []logrus.Level
}
// Levels implement levels
func (hook lineHook) Levels() []logrus.Level {
return logrus.AllLevels
}
// Fire implement fire
func (hook lineHook) Fire(entry *logrus.Entry) error {
packageName, funcName, file, line := findCaller(hook.Skip)
entry.Data["packageName"] = packageName
entry.Data["funcName"] = funcName
entry.Data["file"] = file
entry.Data["line"] = line
return nil
}
func findCaller(skip int) (string, string, string, int) {
file := ""
line := 0
var pc uintptr
// 遍历调用栈的最大索引为第11层.
for i := 0; i < 11; i++ {
file, line, pc = getCaller(skip + i)
// 过滤掉所有logrus包,即可得到生成代码信息
if !strings.HasPrefix(file, "logrus") {
break
}
}
fullFnName := runtime.FuncForPC(pc)
funcName := ""
if fullFnName != nil {
fnNameStr := fullFnName.Name()
// 取得函数名
parts := strings.Split(fnNameStr, ".")
funcName = parts[len(parts)-1]
}
//return fmt.Sprintf("%s:%d:%s()", file, line, fnName)
var packageName = file[:strings.Index(file, "/")]
return packageName, funcName, file, line
}
func getCaller(skip int) (string, int, uintptr) {
pc, file, line, ok := runtime.Caller(skip)
if !ok {
return "", 0, pc
}
n := 0
// 获取包名
for i := len(file) - 1; i > 0; i-- {
if file[i] == '/' {
n++
if n >= 2 {
file = file[i+1:]
break
}
}
}
return file, line, pc
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/kristas/booting-go.git
git@gitee.com:kristas/booting-go.git
kristas
booting-go
booting-go
v1.0.5

搜索帮助