diff --git a/sysmonitor/Makefile b/sysmonitor/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..a7b9ac05a3194ae5946fe70064f8bb5f72b1b3b6 --- /dev/null +++ b/sysmonitor/Makefile @@ -0,0 +1,5 @@ +all: sysmonitor +sysmonitor: src/sysmonitor.c + gcc -o sysmonitor src/sysmonitor.c -pthread +clean: + rm -rf sysmonitor diff --git a/sysmonitor/Readme.md b/sysmonitor/Readme.md new file mode 100644 index 0000000000000000000000000000000000000000..1a031bf4c3c3725c47d5fc091fee187c848b42e3 --- /dev/null +++ b/sysmonitor/Readme.md @@ -0,0 +1,18 @@ +# compiler +gcc +# perf configuration +``` +su root +echo -1 > /proc/sys/kernel/perf_event_paranoid +echo 0 > /proc/sys/kernel/kptr_restrict +exit +``` +# usage +``` +sysmonitor [-m maxsys] [-c cpu] [-i interval] [-f outfile] [-l lasttime] + -m, 设置要监控的sys值,大于这个值运行perf进行数据采集,默认20. + -c, 设置要监控的cpu,默认是监控整体cpu的sys util. + -i, 监控sys时,每次扫描的间隔时长,单位秒. + -f,输出信息的存放文件,默认是./perf.data. + -l, perf数据采集时长\n" ,cmd); +``` diff --git a/sysmonitor/src/sysmonitor.c b/sysmonitor/src/sysmonitor.c new file mode 100644 index 0000000000000000000000000000000000000000..3126e271434e979a7021dfeb46965d689a10296b --- /dev/null +++ b/sysmonitor/src/sysmonitor.c @@ -0,0 +1,189 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define FILE_NAME_LEN 100 +#define MAXLINE 256 +#define die(...) { fprintf(stderr, __VA_ARGS__); exit(EXIT_FAILURE); } + +struct cpu_info { + long unsigned utime, ntime, stime, itime; + long unsigned iowtime, irqtime, sirqtime; +}; +struct cpu_info new_cpu,old_cpu; + //default setting +int sysCpuMax=20; //20% +int cpuNum=0; //all cpu +int flushTime=1; //1s +char filePath[FILE_NAME_LEN]="./perf.data"; //./perf.data +int lastTime=10; //10s + +double usrCpu,sysCpu,iowCpu,irqCpu; +pthread_t tid; + +void handler(int sig){ + if(tid)pthread_cancel(tid); + exit(0); +} + +void usage(char *cmd) { + fprintf(stderr,"Usage: %s [-m maxsys] [-c cpu] [-i interval] [-f outfile] [-l lasttime]\n \ + -m, 设置要监控的sys值,大于这个值运行perf进行数据采集,默认20.\n \ + -c, 设置要监控的cpu,默认是监控整体cpu的sys util.\n \ + -i, 监控sys时,每次扫描的间隔时长,单位秒.\n \ + -f,输出信息的存放文件,默认是./perf.data.\n \ + -l, perf数据采集时长\n" ,cmd); +} + +void read_cpu(void){ + memcpy(&old_cpu, &new_cpu, sizeof(struct cpu_info)); + int tmp=cpuNum; + + FILE*file; + file = fopen("/proc/stat", "r"); + if (!file) die("Could not open /proc/stat.\n"); + + + char line[MAXLINE]; + memset(line,0,sizeof(MAXLINE)); + while(tmp>=0){ + fgets(line,MAXLINE,file); + tmp--; + } + sscanf(&line[5],"%ld %ld %ld %ld %ld %ld %ld", &new_cpu.utime, &new_cpu.ntime, &new_cpu.stime, + &new_cpu.itime, &new_cpu.iowtime, &new_cpu.irqtime, &new_cpu.sirqtime); + fclose(file); + + /* + printf("%lu %lu %lu %lu %lu %lu %lu\n",new_cpu.utime, new_cpu.ntime, new_cpu.stime, + new_cpu.itime, new_cpu.iowtime, new_cpu.irqtime, new_cpu.sirqtime); + */ +} + +void cal_cpu(void){ + double total_delta_time; + total_delta_time = (new_cpu.utime + new_cpu.ntime + new_cpu.stime + new_cpu.itime + + new_cpu.iowtime + new_cpu.irqtime + new_cpu.sirqtime) + - (old_cpu.utime + old_cpu.ntime + old_cpu.stime + old_cpu.itime + + old_cpu.iowtime + old_cpu.irqtime + old_cpu.sirqtime); + usrCpu=(double)(((new_cpu.utime + new_cpu.ntime) - (old_cpu.utime + old_cpu.ntime)) * 100 / total_delta_time); + sysCpu=(double)(((new_cpu.stime ) - (old_cpu.stime)) * 100 / total_delta_time); + iowCpu=(double)(((new_cpu.iowtime) - (old_cpu.iowtime)) * 100 / total_delta_time); + irqCpu=(double)(((new_cpu.irqtime + new_cpu.sirqtime) - (old_cpu.irqtime + old_cpu.sirqtime)) * 100 / total_delta_time); +} + +/* +su root +echo -1 > /proc/sys/kernel/perf_event_paranoid +echo 0 > /proc/sys/kernel/kptr_restrict +exit +*/ +void*exceptHandle(void*){ + char line[MAXLINE]; + memset(line,0,sizeof(MAXLINE)); + sprintf(line,"perf record -agq -o %20s -- sleep %d\n",filePath,lastTime); + //printf("%s\n",line); + system(line); + pthread_exit(NULL); +} + +int main(int argc,char*argv[]){ + int cpu=get_nprocs_conf(); + + for(int i=1;i= argc) { + fprintf(stderr, "Option -m expects an argument.\n"); + usage(argv[0]); + exit(EXIT_FAILURE); + } + sysCpuMax = atoi(argv[++i]); + continue; + } + if (!strcmp(argv[i], "-c")) { + if (i + 1 >= argc) { + fprintf(stderr, "Option -d expects an argument.\n"); + usage(argv[0]); + exit(EXIT_FAILURE); + } + + cpuNum = atoi(argv[++i]); + if(cpuNum>cpu){ + fprintf(stderr, "cpu number excess %d.\n",cpu); + usage(argv[0]); + exit(EXIT_FAILURE); + } + continue; + } + if (!strcmp(argv[i], "-i")) { + if (i + 1 >= argc) { + fprintf(stderr, "Option -s expects an argument.\n"); + usage(argv[0]); + exit(EXIT_FAILURE); + } + flushTime = atoi(argv[++i]); + continue; + } + if (!strcmp(argv[i], "-f")) { + if (i + 1 >= argc) { + fprintf(stderr, "Option -f expects an argument.\n"); + usage(argv[0]); + exit(EXIT_FAILURE); + } + i++; + memset(filePath,0,FILE_NAME_LEN); + strncpy(filePath,argv[i],strlen(argv[i])); + printf("%s\n",filePath); + FILE*file; + if((file=fopen(filePath,"w+"))==NULL){ + fprintf(stderr, "filepath wrong!.\n"); + usage(argv[0]); + exit(EXIT_FAILURE); + } + fclose(file); + continue; + } + if (!strcmp(argv[i],"-l")) { + if (i + 1 >= argc) { + fprintf(stderr, "Option -l expects an argument.\n"); + usage(argv[0]); + exit(EXIT_FAILURE); + } + lastTime=atoi(argv[++i]); + continue; + } + if (!strcmp(argv[i], "-h")) { + usage(argv[0]); + exit(EXIT_SUCCESS); + } + fprintf(stderr, "Invalid argument \"%s\".\n", argv[i]); + usage(argv[0]); + exit(EXIT_FAILURE); + } + + signal(SIGINT,handler); + + read_cpu(); + while(1){ + sleep(flushTime); + read_cpu(); + cal_cpu(); + printf("usrCpu %.2f%% sysCpu %.2f%% iowCpu %.2f%% irqCpu %.2f%%\n",usrCpu,sysCpu,iowCpu,irqCpu); + if(sysCpu>=sysCpuMax){ + pthread_create(&tid,NULL,exceptHandle,NULL); + sleep(lastTime+1); + break; + } + } + +} + diff --git a/sysmonitor/src/sysmonitor.py b/sysmonitor/src/sysmonitor.py new file mode 100755 index 0000000000000000000000000000000000000000..f92db80fa3d042eb4a86d1e7a72178598765b28d --- /dev/null +++ b/sysmonitor/src/sysmonitor.py @@ -0,0 +1,165 @@ +#! /usr/bin/python3 + +import sys +import os +import signal +from time import sleep + +class cpu_info: + def __init__(self): + self.utime=0; + self.ntime=0; + self.stime=0; + self.itime=0; + self.iowtime=0; + self.irqtime=0; + self.sirqtime=0; + def clone(self,cpu): + self.utime=cpu.utime; + self.ntime=cpu.ntime; + self.stime=cpu.stime; + self.itime=cpu.itime; + self.iowtime=cpu.iowtime; + self.irqtime=cpu.irqtime; + self.sirqtime=cpu.sirqtime; + + +sysCpuMax=20.0; #20% +cpuNum=0; #all cpu +flushTime=1; #1s +filePath="./perf.data"; #./perf.data +lastTime=10; #10s + +old_cpu=cpu_info() +new_cpu=cpu_info() +usrCpu=0.0 +sysCpu=0.0 +iowCpu=0.0 +irqCpu=0.0 + +def usage(cmd): + print(f"Usage: {cmd} [-m maxsys] [-c cpu] [-i interval] [-f outfile] [-l lasttime]\n \ + -m, 设置要监控的sys值,大于这个值运行perf进行数据采集,默认20.\n \ + -c, 设置要监控的cpu,默认是监控整体cpu的sys util.\n \ + -i, 监控sys时,每次扫描的间隔时长,单位秒.\n \ + -f,输出信息的存放文件,默认是./perf.data.\n \ + -l, perf数据采集时长\n") + +def handler(signum, frame): + exit(0) + +def read_cpu(cpuNum): + global old_cpu,new_cpu + old_cpu.clone(new_cpu) + with open("/proc/stat", "r",encoding="utf-8") as file: + for i in range (0,cpuNum+1): + line=file.readline() + file.close() + res=line.replace(' ',' ').split(' ') + new_cpu.utime=int(res[1],10) + new_cpu.ntime=int(res[2],10) + new_cpu.stime=int(res[3],10) + new_cpu.itime=int(res[4],10) + new_cpu.iowtime=int(res[5],10) + new_cpu.irqtime=int(res[6],10) + new_cpu.sirqtime=int(res[7],10) + +def cal_cpu(): + total_delta_time = (new_cpu.utime + new_cpu.ntime + new_cpu.stime + new_cpu.itime \ + + new_cpu.iowtime + new_cpu.irqtime + new_cpu.sirqtime) \ + - (old_cpu.utime + old_cpu.ntime + old_cpu.stime + old_cpu.itime \ + + old_cpu.iowtime + old_cpu.irqtime + old_cpu.sirqtime) + global usrCpu,sysCpu,iowCpu,irqCpu + usrCpu=(((new_cpu.utime + new_cpu.ntime) - (old_cpu.utime + old_cpu.ntime)) * 100 / total_delta_time) + sysCpu=(((new_cpu.stime ) - (old_cpu.stime)) * 100 / total_delta_time); + iowCpu=(((new_cpu.iowtime) - (old_cpu.iowtime)) * 100 / total_delta_time) + irqCpu=(((new_cpu.irqtime + new_cpu.sirqtime) - (old_cpu.irqtime + old_cpu.sirqtime)) * 100 / total_delta_time) + + +if __name__=="__main__": + + argc=len(sys.argv) + cpu=os.cpu_count() + signal.signal(signal.SIGINT, handler) + + i=1 + while(i= argc): + print("Option -m expects an argument.") + usage(sys.argv[0]) + exit(-1) + i=i+1 + sysCpuMax = float(sys.argv[i]) + i=i+1 + continue + if (sys.argv[i]=="-c"): + if (i + 1 >= argc): + print("Option -d expects an argument.") + usage(sys.argv[0]) + exit(-1) + i=i+1 + cpuNum = int(sys.argv[i],10) + if(cpuNum>cpu): + print("cpu number excess {cpu}.") + usage(sys.argv[0]) + exit(-1) + i=i+1 + continue + if (sys.argv[i]=="-i"): + if (i + 1 >= argc): + print("Option -s expects an argument.") + usage(sys.argv[0]) + exit(-1) + i=i+1 + flushTime = int(sys.argv[i],10) + i=i+1 + continue + if (sys.argv[i]=="-f"): + if (i + 1 >= argc): + print("Option -f expects an argument.") + usage(sys.argv[0]) + exit(-1) + + i+=1 + filePath=sys.argv[i] + if not os.access(os.path.dirname(filePath),os.W_OK): + print(f"wrong filePath {filepath}.") + usage(sys.argv[0]) + exit(-1) + i=i+1 + continue + if (sys.argv[i]=="-l"): + if (i + 1 >= argc): + print("Option -l expects an argument.") + usage(sys.argv[0]) + exit(-1) + i=i+1 + lastTime=int(sys.argv[i],10) + i=i+1 + continue; + if (sys.argv[i]=="-h"): + usage(sys.argv[0]) + exit(-1) + print(f"Invalid argument {sys.argv[i]}.") + usage(sys.argv[0]) + exit(-1) + + read_cpu(cpuNum) + while(True): + sleep(flushTime) + read_cpu(cpuNum) + cal_cpu() + print("usrCpu {:.2f}% sysCpu {:.2f}% iowCpu {:.2f}% irqCpu {:.2f}%".format(usrCpu,sysCpu,iowCpu,irqCpu)) + if(sysCpu>=sysCpuMax): + line=f"perf record -agq -o {filePath} -- sleep {lastTime}" + os.system(line) + break + + + + + + + +