前言:

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

项目地址: logrus github 地址

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

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

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

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

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

package hooks

import (
"fmt"
"runtime"
"strings"
"github.com/sirupsen/logrus"
)
// ContextHook for log the call context
type 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: ,
levels: levels,
}
if len(hook.levels) == {
hook.levels = logrus.AllLevels
}
return &hook
} // Levels implement levels
func (hook contextHook) Levels() []logrus.Level {
return logrus.AllLevels
} // Fire implement fire
func (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 :=
for i := ; i < ; 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 "",
}
n :=
for i := len(file) - ; i > ; i-- {
if file[i] == '/' {
n++
if n >= {
file = file[i+:]
break
}
}
}
return file, line
}

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

package main

import (
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 main

import (
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") }

效果:

go包之logrus显示日志文件与行号的更多相关文章

  1. __file__, sys._getframe().f_lineno 当前文件的行号

    当前文件的行号 try: f = open(sys.argv[1], "rb") address_book.ParseFromString(f.read()) f.close()e ...

  2. NO17 第二关考试: 返回上次目录和ls -lrt倒序看文件--删除7天前的日志--查看日志更新--记录行号

    第二题:不用cd /ildboy命令如何回到上一次的目录: 假如当前目录是: [root@localhost oldboy]# pwd/oldboy现在因为需要进入到了/tmp目录下进行操作,执行的命 ...

  3. log4j日志文件名与行号显示乱码? 问号? 参数问号? 日志问号?【转】【补】

    log4j本来设置了要打印行号与文件名的,结果有的能打印出来,有的却是乱码,查了些文档之后才发现,原来打印问题是因为编绎时没有编绎进去调试信息,所以没办法打印,好像有的系统又会显示(Unknown S ...

  4. 技巧:Python中print打印信息的同时打印文件、行号

    import sys def Log(msg): print('Print Message: '+msg+' ,File: "'+__file__+'", Line '+str(s ...

  5. 网上都没有提到的教程:python捕获异常后,怎么输出错误文件和行号

    1.假设输出不存在的变量 a try: print(a) except NameError as e: print('发生错误的文件:', e.__traceback__.tb_frame.f_glo ...

  6. php:file()与file_get_contents():讲日志文件没行读为数组形式

    file()与file_get_contents()一样,都是读取某文件的内容.file_get_contents()输出的是整个文件(不能读取TXT里的首行缩进和换行符). file() 函数把整个 ...

  7. Gin 框架 - 使用 logrus 进行日志记录

    目录 概述 日志格式 Logrus 使用 推荐阅读 概述 上篇文章分享了 Gin 框架的路由配置,这篇文章分享日志记录. 查了很多资料,Go 的日志记录用的最多的还是 github.com/sirup ...

  8. Gin框架 - 使用 Logrus 进行日志记录

    概述 上篇文章分享了 Gin 框架的路由配置,这篇文章分享日志记录. 查了很多资料,Go 的日志记录用的最多的还是 github.com/sirupsen/logrus. Logrus is a st ...

  9. 使用jar包格式化Docker 容器日志

    前面使用JS格式化textarea中的日志内容,但局限于JS语言性能,在日志内容较多时效率无法接受,建议日志内容大于5000行时转投本java程序,文末提供jar包下载. LogsFormat.jav ...

随机推荐

  1. AngularJS--及其他js框架对比

    ----和 **类似?? Angular 2.谷歌的 React   Facebook的 Vue.js. Ember.js. https://github.com/angular/angular.js ...

  2. 51nod 1437 迈克步 单调栈

    利用单调栈高效的求出,一个数a[i]在哪个区间内可作为最小值存在. 正向扫描,求出a[i]可做为最小值的区间的左边界 反向扫描,求出a[i]可作为最小值的区间的右边界 r[i] - l[i] +1 就 ...

  3. linux下cmake安装mysql 源码

    1.假设已经有mysql-5.6.21.tar.gz以及cmake-2.8.4.tar.gz两个源文件 (1)先安装cmake(mysql5.5以后是通过cmake来编译的) [root@ rhel5 ...

  4. Oracle根据【日期】组,其他条件根据PIVOT行转列。使每个日期条件关联的其他数据只有一行。

    select OPER_TIME, MICROPAY, REFUND from ( select trunc(oper_time) oper_time, class_name, sum(total_f ...

  5. Crash工具实战-变量解析【转】

    转自:http://blog.chinaunix.net/uid-14528823-id-4358785.html Crash工具实战-变量解析 Crash工具用于解析Vmcore文件,Vmcore文 ...

  6. Nginx 开启目录下载

    平时应用中,我们大都用apache搭建下载页面.毕竟Apache搭建起来非常方便,yum安装,创建目录就可以了. 但有时还是需要用nginx配置下载页面.这里就是一个简单的配置nginx下载页面的过程 ...

  7. 开源录屏工具 Best Screen Recording Open Source Software For Windows 2017

    OBS Studio OBS (Open Broadcaster Software) - Free and open source software for live streaming and sc ...

  8. zabbix添加对centos系统cpu使用率百分比的监控

    cpu使用率key: system.cpu.util[] 在grafana现实的时候配置,单位选择percent(0-100),范围0-100

  9. hue的历史查询记录querys乱码问题解决

    hue的历史查询记录querys乱码问题解决: master1中配置文件/home/hadoop/.versions/hue-3.10.0/desktop/conf/hue.ini 可以看到连接的是m ...

  10. winform生成条形码和二维码(ZXing.Net)

    首先在项目添加ZXing.Net. 工具-->Nuget包管理器-->Nuget程序包  在所搜栏输入 ZXing.Net 如下图: 添加完成后会看见: 效果图: 所有代码: /// &l ...