最近接手一份代码,采用的是golang revel web框架,期间不停的有运营,测试来骚扰,新手必须要老实,有问必答,来一个我就去日志文件查看一下,“尼玛,不停的刷屏,怎么看,大概什么时间,给个订单号呗”,这是我做的最多的事情。实在是看的心累,日志记录内容太少,关键字太少,并发请求太多,分不清是不是一个请求的。程序员得用程序解放劳动力,怎么能浪费在看日志的时间上。有了需求点,那么对日志的记录就得规范。总结几个记日志的关键点。
1. 入口打印请求参数,出口打印返回值。–便于和前后端扯皮,什么参数传错了,没返回等等
2.日志关键字明确,时间,级别,行号函数名。–便于grep 各种搜索,随时定位代码
3.一个请求有一个唯一请求ID ,一路追踪,无论多少次rpc,或者函数调用
1.2 这两个问题很好解决,第3个就很麻烦,在网上查了很多问题资料,看到一个google的分布式跟踪的,但这个主要是基于rpc 的,但是我想的是基于函数调用的,一个请求,无论调用多少层函数,那么函数里面日志都携带一个唯一表示此请求的ID,别的请求调用的就携带别的ID,不能重。 鉴于需求是这样,那么我想到一个方案,每一次函数调用时都多传一个ID,传入log 这样,但这样太麻烦了,还要改动所有log 调用的地方,不可取。其实这个问题,仔细分析变成了找多个请求调用多个函数调用的共同点, 什么是共同的1.请求是共同的,但这个传入,log 侵入代码成本太高, 还有一个是共同的,顺着函数堆栈往上追,都能追到请求处理的初始函数,但我们还要区分不同请求,不能只是追踪调用路线,想到一个办法,就是能不能根据每一个调用堆栈分配一个ID,在各个字函数里面能获取所在堆栈的ID,但这个只是我的设想不知道,怎么实现。
终于找到了还有一个共同点,每一次请求都是go 一个协程,而里面的调用各个函数都是在这个协程里的,这样只需要获取所在协程的ID 不就是唯一对应这个请求吗。 问题终于解决了。
下面是golang 获取协程ID的一些方法 资料。
1. https://www.zhihu.com/question/39863941/answer/83575802
2.http://blog.sgmansfield.com/2015/12/goroutine-ids/
3.https://github.com/huandu/goroutine