共计 1916 个字符,预计需要花费 5 分钟才能阅读完成。
导读 | 在对日志信息进行实时监控分析时,需要对日志中纳秒级的时间进行计算,逻辑比较简单:找出开始时间、结束时间,遇到结束时间后输出时间间隔。 |
在对日志信息进行实时监控分析时,需要对日志中纳秒级的时间进行计算,逻辑比较简单:找出开始时间、结束时间,遇到结束时间后输出时间间隔。
日志中的部分数据如下:
2016-01-30 19:37:30 1454153850967748663 remove alive file
2016-01-30 19:37:34 1454153854621122459 role change to FAULT
一开始写出来是这样的:
awk '
/remove alive file/ {
start=$3
printf "%6s: %dn","START",start
}
/role change to FAULT/ {
end=$3;
printf "%6s: %dn","END",end
diff=(end-start)/1000^3
printf "%6s: %0.9f(s)n","DIFF",diff
}'
输出结果看似就是我想要的:
START: 1454153850967748608
END: 1454153854621122560
DIFF: 3.653373952(s)
有的朋友可能看到这个结果后就直接使用了,但是较真的我还是把输出结果和 bc 的结算结果比较了一下,没问题。
接下来我习惯性的到日志中把每个输出结果进行确认,略一看没什么不对的地方,仔细一对比,发现日志中纳秒级的时间被 awk 处理后竟然变了。为了进行确认,写了如下代码:
awk 'BEGIN {
printf "%20s == %-20sn","0X2FFFFFFFFFFFFF","13510798882111487"
printf "%20X %dn",0X2FFFFFFFFFFFFF,0X2FFFFFFFFFFFFF
printf "%20X %dn",13510798882111487,13510798882111487
printf "---------------------------------------------n"
printf "%20s == %-20sn","0X2FFFFFFFFFFFFE","13510798882111486"
printf "%20X %dn",0X2FFFFFFFFFFFFE,0X2FFFFFFFFFFFFE
printf "%20X %dn",13510798882111486,13510798882111486
}'
输出结果如下:
0X2FFFFFFFFFFFFF == 13510798882111487
30000000000000 13510798882111488
30000000000000 13510798882111488
---------------------------------------------
0X2FFFFFFFFFFFFE == 13510798882111486
2FFFFFFFFFFFFE 13510798882111486
2FFFFFFFFFFFFE 13510798882111486
对应的二进制数值如下:
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 的结合。于是,把代码修改成下面的样子:
awk '
/remove alive file/ {
start=$3
printf "%6s: %sn","START",start
正文完
星哥玩云-微信公众号