iotop无疑在linux IO检测上是个不错的工具,但苦于要求内核版本和Python版本,不少朋友放弃了,我也是。偶然间找到了iopp,用c写的,这个跟iotop是一个作用,nice!给大家分享下
安装方法很简单,首先复制下面源代码保存为iopp.c文件
if (length >= BUFFERLEN) \ printf("ERROR - value is larger than the buffer: %d\n", __LINE__); \ strncpy(value, p, length); \ long long cancelled_write_bytes; char command[COMMANDLEN + 1]; struct io_node *head = NULL; char *format_b(long long); struct io_node *get_ion(int); struct io_node *new_ion(char *); void upsert_data(struct io_node *); static char retarray[NUM_STRINGS][16]; index = (index + 1) % NUM_STRINGS; amt = (amt + 512) / 1024; amt = (amt + 512) / 1024; amt = (amt + 512) / 1024; snprintf(ret, sizeof(retarray[index]) - 1, "%lld%c", amt, tag); get_cmdline(struct io_node *ion) char filename[BUFFERLEN + 1]; char buffer[COMMANDLEN + 1]; length = snprintf(filename, BUFFERLEN, "%s/%d/cmdline", PROC, ion->pid); printf("WARNING - filename length may be too big for buffer: %d\n", fd = open(filename, O_RDONLY); length = read(fd, buffer, sizeof(buffer) - 1); * The command is near the beginning; we don't need to be able to length = length < COMMANDLEN ? length : COMMANDLEN; strncpy(ion->command, p, length); ion->command[length] = '\0'; struct io_node *c = head; get_tcomm(struct io_node *ion) char filename[BUFFERLEN + 1]; char buffer[BUFFERLEN + 1]; length = snprintf(filename, BUFFERLEN, "%s/%d/stat", PROC, ion->pid); printf("WARNING - filename length may be too big for buffer: %d\n", fd = open(filename, O_RDONLY); length = read(fd, buffer, sizeof(buffer) - 1); * The command is near the beginning; we don't need to be able to length = length < BUFFERLEN ? length : BUFFERLEN; strncpy(ion->command, p, length); ion->command[length] = '\0'; insert_ion(struct io_node *ion) /* Check the head of the list as a special case. */ if (ion->pid < head->pid) /* Append to the end of the list. */ DIR *dir = opendir(PROC); char filename[BUFFERLEN + 1]; char buffer[BUFFERLEN + 1]; char value[BUFFERLEN + 1]; /* Display column headers. */ printf("%5s %5s %5s %8s %8s %5s %6s %7s %s\n", "pid", "rchar", "wchar", "syscr", "syscw", "reads", "writes", "cwrites", "command"); printf("%5s %8s %8s %8s %8s %8s %8s %8s %s\n", "pid", "rchar", "wchar", "syscr", "syscw", "rkb", "wkb", "cwkb", "command"); printf("%5s %8s %8s %8s %8s %8s %8s %8s %s\n", "pid", "rchar", "wchar", "syscr", "syscw", "rmb", "wmb", "cwmb", "command"); printf("%5s %8s %8s %8s %8s %8s %8s %8s %s\n", "pid", "rchar", "wchar", "syscr", "syscw", "rbytes", "wbytes", "cwbytes", "command"); /* Loop through the process table and display a line per pid. */ while ((ent = readdir(dir)) != NULL) long long cancelled_write_bytes; if (!isdigit(ent->d_name[0])) ion = new_ion(ent->d_name); if (command_flag == 0 || rc != 0) /* If the full command line is not asked for or is empty... */ length = snprintf(filename, BUFFERLEN, "%s/%s/io", PROC, ent->d_name); printf("WARNING - filename length may be too big for buffer: %d\n", fd = open(filename, O_RDONLY); length = read(fd, buffer, sizeof(buffer) - 1); /* Parsing the io file data. */ GET_VALUE(ion->read_bytes); GET_VALUE(ion->write_bytes); GET_VALUE(ion->cancelled_write_bytes); old_ion = get_ion(ion->pid); /* Display the pid's io data. */ rchar = ion->rchar - old_ion->rchar; wchar = ion->wchar - old_ion->wchar; syscr = ion->syscr - old_ion->syscr; syscw = ion->syscw - old_ion->syscw; read_bytes = ion->read_bytes - old_ion->read_bytes; write_bytes = ion->write_bytes - old_ion->write_bytes; cancelled_write_bytes = ion->cancelled_write_bytes - old_ion->cancelled_write_bytes; if (kb_flag == 1 && hr_flag == 0) read_bytes = BTOKB(read_bytes); write_bytes = BTOKB(write_bytes); cancelled_write_bytes = BTOKB(cancelled_write_bytes); else if (mb_flag == 1 && hr_flag == 0) read_bytes = BTOMB(read_bytes); write_bytes = BTOMB(write_bytes); cancelled_write_bytes = BTOMB(cancelled_write_bytes); if (!(idle_flag == 1 && rchar == 0 && wchar == 0 && syscr == 0 && syscw == 0 && read_bytes == 0 && write_bytes == 0 && cancelled_write_bytes == 0)) { printf("%5d %8lld %8lld %8lld %8lld %8lld %8lld %8lld %s\n", printf("%5d %5s %5s %8lld %8lld %5s %6s %7s %s\n", format_b(cancelled_write_bytes), * No previous data, show 0's instead of calculating negatives * only if we are shoring idle processes. printf("%5d %8d %8d %8d %8d %8d %8d %8d %s\n", ion->pid, 0, 0, 0, 0, 0, 0, 0, ion->command); ion = (struct io_node *) malloc(sizeof(struct io_node)); bzero(ion, sizeof(struct io_node)); upsert_data(struct io_node *ion) /* Check if we have seen this pid before. */ n->read_bytes = ion->read_bytes; n->write_bytes = ion->write_bytes; n->cancelled_write_bytes = ion->cancelled_write_bytes; * If the pids wrap, then the command may be different then before. strcpy(n->command, ion->command); /* Add this pid to the list. */ printf("usage: iopp -h|--help\n"); printf("usage: iopp [-ci] [-k|-m] [delay [count]]\n"); printf(" -c, --command display full command line\n"); printf(" -h, --help display help\n"); printf(" -i, --idle hides idle processes\n"); printf(" -k, --kilobytes display data in kilobytes\n"); printf(" -m, --megabytes display data in megabytes\n"); printf(" -u, --human-readable display data in kilo-, mega-, or giga-bytes\n"); main(int argc, char *argv[]) static struct option long_options[] = { { "command", no_argument, 0, 'c' }, { "help", no_argument, 0, 'h' }, { "human-readable", no_argument, 0, 'u' }, { "idle", no_argument, 0, 'i' }, { "kilobytes", no_argument, 0, 'k' }, { "megabytes", no_argument, 0, 'm' }, c = getopt_long(argc, argv, "chikmu", long_options, &option_index); /* Handle delay and count arguments. */ break; /* No additional arguments. */ else if ((argc - optind) == 1) delay = atoi(argv[optind]); else if ((argc - optind) == 2) delay = atoi(argv[optind]); max_count = atoi(argv[optind + 1]); /* Too many additional arguments. */ while (max_count == -1 || count++ < max_count)
然后放到服务器上,gcc -o iopp iopp.c 编译一下
运行 ./iopp -i -k -c 1 > io.log 这个命令就可以把实时的io信息打印出来啦
打印出来的各项含义:
-
pid 进程ID
-
rchar 将要从磁盘读取的字节数
-
wchar 已经写入或应该要写入磁盘的字节数
-
syscr 读I/O数
-
syscw 写I/O数
-
rbytes 真正从磁盘读取的字节数
-
wbytes 真正写入到磁盘的字节数
-
cwbytes 因为清空页面缓存而导致没有发生操作的字节数
-
command 执行的命令
|