Linux - 从系统调用分析应用问题

Posted 王万林 Ben

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux - 从系统调用分析应用问题相关的知识,希望对你有一定的参考价值。

Linux - 从系统调用分析应用问题

背景

Linux下应用的执行,遇到性能问题时,可参考下图对应的工具进行收集分析,

其中System Call Interface层,可以使用strace命令进行日志收集。

strace收集System Call Interface日志

$ strace -ttTffy -o /path/to/strace.log <command>
$ #或追踪已运行的进程,如下
$ strace -ttTffy -o /path/to/strace.log -p <PID>

分析代码

# Discription: strace log analyzer
# Author: WanlinWang Ben
# Date:   09/19/2021
# Usage:
#       步骤1:获取strace日志,使用命令:strace -ttTffy -o /path/to/strace.log <command>
#                                或:strace -ttTffy -o /path/to/strace.log -p <PID>
#
#       步骤2:分析strace输出日志,使用命令:strace_analyzer.py /path/to/strace.log*


import re
import pandas as pd
import argparse

parser = argparse.ArgumentParser(description='strace日志分析脚本')
parser.add_argument('log_file', type=str, nargs='+',
                    help='log file\\'s name.')

args = parser.parse_args()
print(args.log_file)
print()


pd.set_option('display.max_colwidth', 256)
pd.set_option('display.max_columns', 10)
pd.set_option('display.expand_frame_repr', False)

log_file_list = args.log_file
regexp_pattern = re.compile(r"\\d{2}:\\d{2}:\\d{2}.\\d{6} ([^(]*).* <([\\d\\.]*)>")
df = pd.DataFrame(columns=["file", "line_num", "sys call", "time"])

for log_file in log_file_list:
    with open(log_file) as log:
        for num, line in enumerate(log, 1):
            # print(line)
            match = regexp_pattern.match(line)
            if match:
                syscall, time = match.groups()
                pd_line = {"file": log_file, "line_num": num, "sys call": syscall, "time": float(time)}
                df = df.append(pd_line, ignore_index=True)

# print(df)
print("Top 10 by sys call times".center(80, '-'))
print(df.sort_values(by="time", ascending=False)[:10].to_string(index=False))

print()
df_mean = df.groupby("sys call", as_index=False)["time"].mean().sort_values(by="time", ascending=False).rename(columns={"time": "Mean time"})
df_sum = df.groupby("sys call", as_index=False)["time"].sum()
df_sum = df_sum.rename(columns={"time": "Total time"})
df_count = df.groupby("sys call", as_index=False)["time"].count()
df_count = df_count.rename(columns={"time": "Count"})

print("Summary".center(80, '-'))
print(df_mean.join(df_count.set_index('sys call'), on='sys call').join(df_sum.set_index('sys call'), on='sys call').to_string(index=False))

效果

小结

本文对Linux的系统调用日志进行简单分析,看是否能够从耗时较长的系统调用入手,进一步分析与发现性能问题的根因。

以上是关于Linux - 从系统调用分析应用问题的主要内容,如果未能解决你的问题,请参考以下文章

实验总结分析报告:从系统的角度分析影响程序执行性能的因素

从系统的角度分析影响程序执行性能的因素

从片段调用 Google Play 游戏服务

linux内核系统调用和标准C库函数的关系分析

Linux内核分析第四周作业

Socket与系统调用深度分析