本文主要是介绍awk计算到纳秒级的bug,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
在对日志信息进行实时监控分析时,需要对日志中纳秒级的时间进行计算,逻辑比较简单:找出开始时间、结束时间,遇到结束时间后输出时间间隔。
日志中的部分数据如下:
1 2 | 2016 - 01 - 30 19 : 37 : 30 1454153850967748663 remove alive file 2016 - 01 - 30 19 : 37 : 34 1454153854621122459 role change to FAULT |
一开始写出来是这样的:
1 2 3 4 5 6 7 8 9 10 11 | awk ' /remove alive file/ { start=$3 printf "%6s: %d\n","START",start } /role change to FAULT/ { end=$3; printf "%6s: %d\n","END",end diff=(end-start)/1000^3 printf "%6s: %0.9f(s)\n","DIFF",diff }' |
输出结果看似就是我想要的:
1 2 3 | START : 1454153850967748608 END : 1454153854621122560 DIFF : 3.653373952 ( s ) |
有的朋友可能看到这个结果后就直接使用了,但是较真的我还是把输出结果和bc的结算结果比较了一下,没问题。
接下来我习惯性的到日志中把每个输出结果进行确认,略一看没什么不对的地方,仔细一对比,发现日志中纳秒级的时间被awk处理后竟然变了。为了进行确认,写了如下代码:
1 2 3 4 5 6 7 8 9 | awk 'BEGIN { printf "%20s == %-20s\n","0X2FFFFFFFFFFFFF","13510798882111487" printf "%20X %d\n",0X2FFFFFFFFFFFFF,0X2FFFFFFFFFFFFF printf "%20X %d\n",13510798882111487,13510798882111487 printf "---------------------------------------------\n" printf "%20s == %-20s\n","0X2FFFFFFFFFFFFE","13510798882111486" printf "%20X %d\n",0X2FFFFFFFFFFFFE,0X2FFFFFFFFFFFFE printf "%20X %d\n",13510798882111486,13510798882111486 }' |
输出结果如下:
1 2 3 4 5 6 7 | 0X2FFFFFFFFFFFFF == 13510798882111487 30000000000000 13510798882111488 30000000000000 13510798882111488 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - 0X2FFFFFFFFFFFFE == 13510798882111486 2FFFFFFFFFFFFE 13510798882111486 2FFFFFFFFFFFFE 13510798882111486 |
对应的二进制数值如下:
1 2 3 | 0X30000000000000 : 11 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0X2FFFFFFFFFFFFF : 10 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0X2FFFFFFFFFFFFE : 10 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1110 |
发现awk的数值处理范围超过0X2FFFFFFFFFFFFE(13510798882111486)就不不准确了(为了找这个临界值,费了一番功夫),他会把0X2FFFFFFFFFFFFF当成0X30000000000000,如果在awk中对0X2FFFFFFFFFFFFF进行减一计算,值没有任何变化,对0X2FFFFFFFFFFFFE进行加法运算,加1和加2的结果都是0X30000000000000,但是awk又可以显示/处理更大的数值,从二进制结果中我也没看出有什么规律可循。有兴趣的可以深入源码层面研究下。
接下来,毅然放弃awk自身的计算功能,选择awk与bc的结合。于是,把代码修改成下面的样子:
1 2 3 4 | awk' / remove alive file / { start = $ 3 printf "%6s: %s\n" , "START" , start
|
这篇关于awk计算到纳秒级的bug的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!