背景:
服务A调用了服务B的rpc接口,但是rpc接口有一部分处理失败了,返回的status为-1,现在要把失败这部分的调用参数拿到,给服务B的负责人看,分析失败原因以改善接口。
线上日志打印格式为:
2022-01-19 18:42:18.473 [INFO] [Thread-64] [com.xxx.xxx.ClassA] @@@traceId=123456789ABCDEFGH@@@ rpc方法调用开始,参数{a1='balalalala', a2={url: http://www.aaa.com }},
2022-01-19 18:42:18.476 [INFO] [Thread-64] [com.xxx.xxx.ClassA] @@@traceId=123456789ABCDEFGH@@@ rpc方法调用结束,返回值:{status:-1, message:{"失败"}},
2022-01-19 18:42:18.473 [INFO] [Thread-69] [com.xxx.xxx.ClassA] @@@traceId=123456789ABCDEFG1@@@ rpc方法调用开始,参数{a1='balalalala', a2={url: http://www.bbb.com }},
2022-01-19 18:42:18.476 [INFO] [Thread-69] [com.xxx.xxx.ClassA] @@@traceId=123456789ABCDEFG1@@@ rpc方法调用结束,返回值:{status:0, message:{"成功"}},
现在要查询到日志中所有返回status=-1对应的参数中a2={url:} 的值,而问题在与参数和返回值没有在一条日志中打印,按status:-1查不到参数,按参数又不知道是否rpc方法调用成功。同时我们的数据量比较大,有几十万条,不可能一个个的去日志里找,只能通过traceId把参数和返回值串起来。
思路:
- 按status:-1查到所有失败日志的traceId
- 按traceId + ‘rpc方法调用开始’ 这两项找到打印参数的那行日志
- 拿到打印参数的日志后,截断只取‘url: http://www.aaa.com’这部分
实践:
1.按status:-1查到所有失败日志
grep "status:-1" *.log*
我拿到的是:
2022-01-19 18:42:18.476 [INFO] [Thread-64] [com.xxx.xxx.ClassA] @@@traceId=123456789ABCDEFGH@@@ rpc方法调用结束,返回值:{status:-1, message:{“失败”}},
2022-01-19 18:42:18.476 [INFO] [Thread-64] [com.xxx.xxx.ClassA] @@@traceId=123456789ABCDEFG1@@@ rpc方法调用结束,返回值:{status:-1, message:{“失败”}},
。。。。。。
2.截断日志中的traceId部分,只需要123456789ABCDEFGH,123456789ABCDEFG1等
grep "status:-1" *.log* | awk '{print $5}'
会得到
@@@traceId=123456789ABCDEFGH@@@
@@@traceId=123456789ABCDEFG1@@@
。。。
我不需要’@@@traceId=‘ 和后面的‘@@@’,在用cut截断,只取12-29的字符
grep "status:-1" *.log* | awk '{print $5}' | cut -c 12-29
会得到
123456789ABCDEFGH
123456789ABCDEFG1
。。。
3. 按traceId + ‘rpc方法调用开始’ 这两项找到打印参数的那行日志
最开始,我不知道怎么遍历文件的每一行执行grep , awk命令,只能将上面的输出到一个文件 /tmp/message.txt
再写了shell来执行第三步动作
grep "status:-1" *.log* | awk '{print $5}' | cut -c 12-29 >> /tmp/message.txt
查看/tmp/message.txt的确是我想要的traceId,每一行一个
写shell脚本:
vim /tmp/grep.sh
#!/bin/bash
cat /tmp/message.txt | while read line
do
grep $line *.log* | grep "rpc方法调用开始" | awk '{print $12}'
done`
给/tmp/grep.sh 可执行权限
chmod +x /tmp/grep.sh
然后执行/tmp/grep.sh 就能看到想要的输出了
a2={url: http://www.aaa.com }
a2={url: http://www.bbb.com }
优化:用xargs -i 接收参数
xargs(英文全拼: eXtended ARGuments)是给命令传递参数的一个过滤器,也是组合多个命令的一个工具
grep "20000" *.log* | awk '{print $6}' | cut -c 12-27 | xargs -i grep {} *.log* | awk '$9~/rpc方法调用开始/' | awk '{print $12}'
参考资料:
https://segmentfault.com/a/1190000022755738