我想格式化使用选项" strace -s 1024 -vftT"获得的strace输出数据。并有日志类似,
... <log that is un-important>
24339 01:51:55 sendto(4, "<logging to required file>", <size>, MSG_NOSIGNAL, NULL, 0) = 114 <0.000050>
...
15016 01:51:55 sendto(594, "<some log to different file>, not included for time measure", <size>, 0, NULL, 0 <unfinished ...>
... <log from different threads>
15016 01:51:55 <... sendto resumed> ) = 5 <0.000076>
... <log that is un-important>
29192 01:51:57 sendto(4, "<logging to required file>", <size>, MSG_NOSIGNAL, NULL, 0 <unfinished ...>
...
29192 01:51:58 <... sendto resumed> ) = 109 <0.652744>
... <log that is un-important>
- &GT;我想找到所有sendto(4,)调用所花费的总时间。 - &GT;这也应该考虑在线程切换后sendto()恢复调用。 - &GT;时间计算应忽略对文件描述符4以外的其他文件描述符的sendto()调用。
所以我在这种情况下的要求是我需要一些脚本(最好使用sed)来添加sendto(4,...)调用所采用的所有时序(在本例中它是0.000050 + 0.652744 = 0.652794)。
欢迎任何类似上下文的引用(我试过找,但找不到任何相关的内容)。
答案 0 :(得分:1)
以下为我工作,感谢Shellter建议使用awk(虽然我没有考虑过“sendto”本身是其他系统调用数据的一部分的特殊情况)
cat strace.txt | awk '
function find_thread(maxInd, threads, threadStrArr, reqThr)
{
for (ind = 1; ind <= maxInd; ind++)
{
if (reqThr == threads[ind])
{
printf "...\n%s\n...\n", threadStrArr[ind]
for ( ; ind < maxInd; ind++)
{
threads[ind] = threads[ind + 1]
threadStrArr[ind]=threadStrArr[ind + 1]
}
return reqThr
}
}
return -1
}
{
thrCnt=0
totmatchCnt=0
totTimetaken=0
syscall_name="sendto"
while ((getline myline) > 0) {
found_syscall_finished=0
resumed_found=match(myline, "<... "syscall_name" resumed>")
if (resumed_found != 0)
{
# Found "<system call> resumed" string in the input line
split(myline,a," ");
thread_id=a[1]
if (thrCnt > 0)
{
# Now need to find matching thread (if any) from the unfinished calls
foundThr=find_thread(thrCnt, threads, threadStrArr, thread_id)
if (foundThr != -1)
{
# There is a matching unfinished call found in the trace
thrCnt--
found_syscall_finished=1
}
}
}
else
{
# It is not resumed system call, check if required system call found
syscall_found = match(myline, syscall_name"\\(4,") # Please note the 4, ie first parameter is 4
if (syscall_found != 0)
{
# It is required system call
unfinished_found=match(myline, "<unfinished ...>$")
if (unfinished_found != 0)
{
# It is an unfinished call, add thread number to the array for search later
split(myline,a," ");
thrCnt++
threadStrArr[thrCnt]=myline
threads[thrCnt]=a[1]
}
else
{
found_syscall_finished=1
}
}
}
if (found_syscall_finished != 0)
{
# current line contains required system call which is finished, fetch time and add to total time
printf "%s\n", myline
n=split(myline,a,"[ <>]");
time_took=a[n-1]
totmatchCnt++
totTimetaken=totTimetaken+time_took
}
}
if (totmatchCnt != 0)
{
avgTime=totTimetaken/totmatchCnt
printf "total = %s, cnt = %s, average = %s\n", totTimetaken, totmatchCnt, avgTime
}
}
'
sample output,
-------------------------------------------------------------------------------------------
24339 01:51:55 sendto(4, "<logging to required file>", <size>, MSG_NOSIGNAL, NULL, 0) = 114 <0.000050>
...
29192 01:51:57 sendto(4, "<logging to required file>", <size>, MSG_NOSIGNAL, NULL, 0 <unfinished ...>
...
29192 01:51:58 <... sendto resumed> ) = 109 <0.652744>
total = 0.652794, cnt = 2, average = 0.326397