go包之logrus显示日志文件与行号
前言:
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显示日志文件与行号的更多相关文章
- __file__, sys._getframe().f_lineno 当前文件的行号
当前文件的行号 try: f = open(sys.argv[1], "rb") address_book.ParseFromString(f.read()) f.close()e ...
- NO17 第二关考试: 返回上次目录和ls -lrt倒序看文件--删除7天前的日志--查看日志更新--记录行号
第二题:不用cd /ildboy命令如何回到上一次的目录: 假如当前目录是: [root@localhost oldboy]# pwd/oldboy现在因为需要进入到了/tmp目录下进行操作,执行的命 ...
- log4j日志文件名与行号显示乱码? 问号? 参数问号? 日志问号?【转】【补】
log4j本来设置了要打印行号与文件名的,结果有的能打印出来,有的却是乱码,查了些文档之后才发现,原来打印问题是因为编绎时没有编绎进去调试信息,所以没办法打印,好像有的系统又会显示(Unknown S ...
- 技巧:Python中print打印信息的同时打印文件、行号
import sys def Log(msg): print('Print Message: '+msg+' ,File: "'+__file__+'", Line '+str(s ...
- 网上都没有提到的教程:python捕获异常后,怎么输出错误文件和行号
1.假设输出不存在的变量 a try: print(a) except NameError as e: print('发生错误的文件:', e.__traceback__.tb_frame.f_glo ...
- php:file()与file_get_contents():讲日志文件没行读为数组形式
file()与file_get_contents()一样,都是读取某文件的内容.file_get_contents()输出的是整个文件(不能读取TXT里的首行缩进和换行符). file() 函数把整个 ...
- Gin 框架 - 使用 logrus 进行日志记录
目录 概述 日志格式 Logrus 使用 推荐阅读 概述 上篇文章分享了 Gin 框架的路由配置,这篇文章分享日志记录. 查了很多资料,Go 的日志记录用的最多的还是 github.com/sirup ...
- Gin框架 - 使用 Logrus 进行日志记录
概述 上篇文章分享了 Gin 框架的路由配置,这篇文章分享日志记录. 查了很多资料,Go 的日志记录用的最多的还是 github.com/sirupsen/logrus. Logrus is a st ...
- 使用jar包格式化Docker 容器日志
前面使用JS格式化textarea中的日志内容,但局限于JS语言性能,在日志内容较多时效率无法接受,建议日志内容大于5000行时转投本java程序,文末提供jar包下载. LogsFormat.jav ...
随机推荐
- Java类加载双亲委托模式优点
启动类加载器可以抢在标准扩展类加载器之前去装载类,而标准扩展类装载器可以抢在类路径加载器之前去加载那个类,类路径装载器又可以抢在自定义类装载器之前去加载类.所以Java虚拟机先从最可信的Java核心A ...
- Oracle 服务器运行健康状况监控利器 Spotlight on Oracle 的安装与使用
1.使用教程;https://blog.csdn.net/defonds/article/details/52936664 2.下载链接:https://pan.baidu.com/s/1cn7tE_ ...
- CVE-2019-0797漏洞:Windows操作系统中的新零日在攻击中被利用
https://securelist.com/cve-2019-0797-zero-day-vulnerability/89885/ 前言 在2019年2月,卡巴实验室的自动漏洞防护(AEP)系统检测 ...
- inception v1-v3 & Xception
inception v1-v3:通过多尺度卷积核学习不同尺度的空间信息并进行耦合:通过多个小卷积核来代替大卷积核的功能从而降低计算量: 通常,在一组特征图上进行卷积需要三维的卷积核,也即卷积核需要同时 ...
- 范围for语句
C++11 新标准引入了一种更简单的for语句,这种语句可以遍历容器或其他序列的所有元素.范围for语句(range for statement)的语法形式是: for (declaration : ...
- 【Linux】Swap与Memory
背景介绍 Memory指机器物理内存,读写速度低于CPU一个量级,但是高于磁盘不止一个量级.所以,程序和数据如果在内存的话,会有非常快的读写速度.但是,内存的造价是要高于磁盘的,且内存的断电丢失数据也 ...
- mybatis:访问静态变量或方法
访问方法: <if test="@com.csget.constant.ConstantApp@getUser('mobile')== 'kf'"> <![CDA ...
- 【原创】大数据基础之Kerberos(1)简介、安装、使用
kerberos5-1.17 官方:https://kerberos.org/ 一 简介 The Kerberos protocol is designed to provide reliable a ...
- layui框架中关于table方法级渲染和自动化渲染之间的区别简单介绍
方法级渲染: <table class="layui-hide" id="LAY_table_user" lay-filter="user&qu ...
- 39)django-XSS 过滤
使用kingedit别人是可以输入script代码.这在后台是不允许script代码运行的. 这里主要使用beatifulSoup过滤 示例1 beatufulsoup4 from bs4 impor ...