博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
go包之logrus显示日志文件与行号
阅读量:6281 次
发布时间:2019-06-22

本文共 2669 字,大约阅读时间需要 8 分钟。

前言:

logrus是go中比较好的一个log模块.github上的很多开源项目都在使用这个模块, 我在写这个博文时, github上的logrus的stars数已经有8214了.最近在用这个模块时,发现不能打印日志所在文件和行数.在开发过程中, 感觉这就不是很友好了. 

项目地址: 

提醒:此方法在并发情况下, 会导致系统奔溃. 请谨慎使用

 

不记录文件名和行号处理办法

logrus支持自定义的hook, 我这里就是使用hook的方式来记录

一个Entry为一条日志记录, 我们的Hook需要做的就是在每一个条的日志记录里面添加调用时的文件名和行号. 核心就是实现自己的Fire方法, 以下是参考实现:

1. 我们新建一个hook的文件. 写入如下代码

package hooksimport (    "fmt"    "runtime"    "strings"    "github.com/sirupsen/logrus")// ContextHook for log the call contexttype contextHook struct {    Field  string    Skip   int    levels []logrus.Level}// NewContextHook use to make an hook// 根据上面的推断, 我们递归深度可以设置到5即可.func NewContextHook(levels ...logrus.Level) logrus.Hook {    hook := contextHook{        Field:  "line",        Skip:   5,        levels: levels,    }    if len(hook.levels) == 0 {        hook.levels = logrus.AllLevels    }    return &hook}// Levels implement levelsfunc (hook contextHook) Levels() []logrus.Level {    return logrus.AllLevels}// Fire implement firefunc (hook contextHook) Fire(entry *logrus.Entry) error {    entry.Data[hook.Field] = findCaller(hook.Skip)    return nil}// 对caller进行递归查询, 直到找到非logrus包产生的第一个调用.// 因为filename我获取到了上层目录名, 因此所有logrus包的调用的文件名都是 logrus/...// 因此通过排除logrus开头的文件名, 就可以排除所有logrus包的自己的函数调用func findCaller(skip int) string {    file := ""    line := 0    for i := 0; i < 10; i++ {        file, line = getCaller(skip + i)        if !strings.HasPrefix(file, "logrus") {            break        }    }    return fmt.Sprintf("%s:%d", file, line)}// 这里其实可以获取函数名称的: fnName := runtime.FuncForPC(pc).Name()// 但是我觉得有 文件名和行号就够定位问题, 因此忽略了caller返回的第一个值:pc// 在标准库log里面我们可以选择记录文件的全路径或者文件名, 但是在使用过程成并发最合适的,// 因为文件的全路径往往很长, 而文件名在多个包中往往有重复, 因此这里选择多取一层, 取到文件所在的上层目录那层.func getCaller(skip int) (string, int) {    _, file, line, ok := runtime.Caller(skip)    //fmt.Println(file)    //fmt.Println(line)    if !ok {        return "", 0    }    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}

 

2. 添加hook到logrus  -- ( logrus定义为了全局使用 )

package mainimport (    log "github.com/sirupsen/logrus"    zzxHook "study/ginStudy/hook")func main() {
var Logger = log.New() Logger.Hooks.Add(zzxHook.NewContextHook()) Logger.WithFields(log.Fields{ "animal": "walrus", }).Info("A walrus appears")}

效果:

 

 

 

2. 添加hook到logrus  -- ( logrus普通使用方式 )

package mainimport (    log "github.com/sirupsen/logrus"    zzxHook "study/ginStudy/hook")func main() {    log.AddHook(zzxHook.NewContextHook())    log.WithFields(log.Fields{        "animal": "walrus",    }).Info("A walrus appears")    }

效果:

 

转载地址:http://yhnva.baihongyu.com/

你可能感兴趣的文章
【B/S学习总结】我的第100篇CSDN博客
查看>>
[Hadoop]chukwa与ganglia的区别
查看>>
数据挖掘工具分析北京房价 (一) 数据爬取采集
查看>>
IOS项目之弹出动画终结篇
查看>>
iOS开发UI篇—ios应用数据存储方式(XML属性列表-plist)
查看>>
OSS移动开发实战2 (30分钟快速搭建移动应用上传回调服务)
查看>>
Swift语言学习No.2: 二维数组
查看>>
jvm gc相关
查看>>
王亟亟的Python学习之路(四)-循环,条件,Range,list和tuple
查看>>
Greenplum 激活standby master失败后的异常修复
查看>>
nanomsg实验——survey
查看>>
Java设计模式(八)----代理模式
查看>>
LinkedList的用法小结
查看>>
Using mongoDB's Profiler analyze the performance of database operations
查看>>
python range() function like postgresql generate_series()
查看>>
一则优化案例
查看>>
[实践]Sonar Xcode8兼容
查看>>
Canvas应用
查看>>
node inspect chrome日志调试
查看>>
书写可维护代码的重要性
查看>>