Linux IO工具 iotop备择方案iopp
iotop毫无疑问linux IO检测上是一个很好的工具,但苦于要求和内核版本Python版本号。我的很多朋友放弃了。我也是。无意中发现iopp,使用c书面,与此iotop它是一个作用。nice!
一起分享
安装方法非常easy。首先复制以下源码保存为iopp.c文件
- #include <stdio.h>
- #include <sys/types.h>
- #include <dirent.h>
- #include <ctype.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <string.h>
- #include <stdlib.h>
- #include <getopt.h>
- #define PROC "/proc"
- #define GET_VALUE(v) \
- p = strchr(p, ':'); \
- ++p; \
- ++p; \
- q = strchr(p, '\n'); \
- length = q - p; \
- if (length >= BUFFERLEN) \
- { \
- printf("ERROR - value is larger than the buffer: %d\n", __LINE__); \
- exit(1); \
- } \
- strncpy(value, p, length); \
- value[length] = '\0'; \
- v = atoll(value);
- #define BTOKB(b) b >> 10
- #define BTOMB(b) b >> 20
- #define BUFFERLEN 255
- #define COMMANDLEN 1024
- #define VALUELEN 63
- #define NUM_STRINGS 8
- struct io_node
- {
- int pid;
- long long rchar;
- long long wchar;
- long long syscr;
- long long syscw;
- long long read_bytes;
- long long write_bytes;
- long long cancelled_write_bytes;
- char command[COMMANDLEN + 1];
- struct io_node *next;
- };
- struct io_node *head = NULL;
- int command_flag = 0;
- int idle_flag = 0;
- int mb_flag = 0;
- int kb_flag = 0;
- int hr_flag = 0;
- /* Prototypes */
- char *format_b(long long);
- struct io_node *get_ion(int);
- struct io_node *new_ion(char *);
- void upsert_data(struct io_node *);
- char *
- format_b(long long amt)
- {
- static char retarray[NUM_STRINGS][16];
- static int index = 0;
- register char *ret;
- register char tag = 'B';
- ret = retarray[index];
- index = (index + 1) % NUM_STRINGS;
- if (amt >= 10000) {
- amt = (amt + 512) / 1024;
- tag = 'K';
- if (amt >= 10000) {
- amt = (amt + 512) / 1024;
- tag = 'B';
- if (amt >= 10000) {
- amt = (amt + 512) / 1024;
- tag = 'G';
- }
- }
- }
- snprintf(ret, sizeof(retarray[index]) - 1, "%lld%c", amt, tag);
- return (ret);
- }
- int
- get_cmdline(struct io_node *ion)
- {
- int fd;
- int length;
- char filename[BUFFERLEN + 1];
- char buffer[COMMANDLEN + 1];
- char *p;
- char *q;
- length = snprintf(filename, BUFFERLEN, "%s/%d/cmdline", PROC, ion->pid);
- if (length == BUFFERLEN)
- printf("WARNING - filename length may be too big for buffer: %d\n",
- __LINE__);
- fd = open(filename, O_RDONLY);
- if (fd == -1)
- return 1;
- length = read(fd, buffer, sizeof(buffer) - 1);
- close(fd);
- buffer[length] = '\0';
- if (length == 0)
- return 2;
- if (command_flag == 0)
- {
- /*
- * The command is near the beginning; we don't need to be able to
- * the entire stat file.
- */
- p = strchr(buffer, '(');
- ++p;
- q = strchr(p, ')');
- length = q - p;
- }
- else
- p = buffer;
- length = length < COMMANDLEN ? length : COMMANDLEN;
- strncpy(ion->command, p, length);
- ion->command[length] = '\0';
- return 0;
- }
- struct io_node *
- get_ion(int pid)
- {
- struct io_node *c = head;
- while (c != NULL)
- {
- if (c->pid == pid)
- break;
- c = c->next;
- }
- return c;
- }
- int
- get_tcomm(struct io_node *ion)
- {
- int fd;
- int length;
- char filename[BUFFERLEN + 1];
- char buffer[BUFFERLEN + 1];
- char *p;
- char *q;
- length = snprintf(filename, BUFFERLEN, "%s/%d/stat", PROC, ion->pid);
- if (length == BUFFERLEN)
- printf("WARNING - filename length may be too big for buffer: %d\n",
- __LINE__);
- fd = open(filename, O_RDONLY);
- if (fd == -1)
- return 1;
- length = read(fd, buffer, sizeof(buffer) - 1);
- close(fd);
- /*
- * The command is near the beginning; we don't need to be able to
- * the entire stat file.
- */
- p = strchr(buffer, '(');
- ++p;
- q = strchr(p, ')');
- length = q - p;
- length = length < BUFFERLEN ?
- length : BUFFERLEN;
- strncpy(ion->command, p, length);
- ion->command[length] = '\0';
- return 0;
- }
- struct io_node *
- insert_ion(struct io_node *ion)
- {
- struct io_node *c;
- struct io_node *p;
- /* Check the head of the list as a special case. */
- if (ion->pid < head->pid)
- {
- ion->next = head;
- head = ion;
- return head;
- }
- c = head->next;
- p = head;
- while (c != NULL)
- {
- if (ion->pid < c->pid)
- {
- ion->next = c;
- p->next = ion;
- return head;
- }
- p = c;
- c = c->next;
- }
- /* Append to the end of the list. */
- if (c == NULL)
- p->next = ion;
- return head;
- }
- void
- get_stats()
- {
- DIR *dir = opendir(PROC);
- struct dirent *ent;
- char filename[BUFFERLEN + 1];
- char buffer[BUFFERLEN + 1];
- char value[BUFFERLEN + 1];
- /* Display column headers. */
- if (hr_flag == 1)
- printf("%5s %5s %5s %8s %8s %5s %6s %7s %s\n", "pid", "rchar", "wchar",
- "syscr", "syscw", "reads", "writes", "cwrites", "command");
- else if (kb_flag == 1)
- printf("%5s %8s %8s %8s %8s %8s %8s %8s %s\n", "pid", "rchar", "wchar",
- "syscr", "syscw", "rkb", "wkb", "cwkb", "command");
- else if (mb_flag == 1)
- printf("%5s %8s %8s %8s %8s %8s %8s %8s %s\n", "pid", "rchar", "wchar",
- "syscr", "syscw", "rmb", "wmb", "cwmb", "command");
- else
- 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)
- {
- int rc;
- int fd;
- int length;
- char *p;
- char *q;
- struct io_node *ion;
- struct io_node *old_ion;
- long long rchar;
- long long wchar;
- long long syscr;
- long long syscw;
- long long read_bytes;
- long long write_bytes;
- long long cancelled_write_bytes;
- if (!isdigit(ent->d_name[0]))
- continue;
- ion = new_ion(ent->d_name);
- if (command_flag == 1)
- rc = get_cmdline(ion);
- if (command_flag == 0 || rc != 0)
- /* If the full command line is not asked for or is empty... */
- rc = get_tcomm(ion);
- if (rc != 0)
- {
- free(ion);
- continue;
- }
- /* Read 'io' file. */
- length = snprintf(filename, BUFFERLEN, "%s/%s/io", PROC, ent->d_name);
- if (length == BUFFERLEN)
- printf("WARNING - filename length may be too big for buffer: %d\n",
- __LINE__);
- fd = open(filename, O_RDONLY);
- if (fd == -1)
- {
- free(ion);
- continue;
- }
- length = read(fd, buffer, sizeof(buffer) - 1);
- close(fd);
- buffer[length] = '\0';
- /* Parsing the io file data. */
- p = buffer;
- GET_VALUE(ion->rchar);
- GET_VALUE(ion->wchar);
- GET_VALUE(ion->syscr);
- GET_VALUE(ion->syscw);
- 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. */
- if (old_ion != NULL)
- {
- 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)
- {
- rchar = BTOKB(rchar);
- wchar = BTOKB(wchar);
- syscr = BTOKB(syscr);
- syscw = BTOKB(syscw);
- 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)
- {
- rchar = BTOMB(rchar);
- wchar = BTOMB(wchar);
- syscr = BTOMB(syscr);
- syscw = BTOMB(syscw);
- 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)) {
- if (hr_flag == 0)
- printf("%5d %8lld %8lld %8lld %8lld %8lld %8lld %8lld %s\n",
- ion->pid,
- rchar,
- wchar,
- syscr,
- syscw,
- read_bytes,
- write_bytes,
- cancelled_write_bytes,
- ion->command);
- else
- printf("%5d %5s %5s %8lld %8lld %5s %6s %7s %s\n",
- ion->pid,
- format_b(rchar),
- format_b(wchar),
- syscr,
- syscw,
- format_b(read_bytes),
- format_b(write_bytes),
- format_b(cancelled_write_bytes),
- ion->command);
- }
- }
- else if (idle_flag != 1)
- /*
- * 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);
- upsert_data(ion);
- }
- closedir(dir);
- return;
- }
- struct io_node *
- new_ion(char *pid)
- {
- struct io_node *ion;
- ion = (struct io_node *) malloc(sizeof(struct io_node));
- bzero(ion, sizeof(struct io_node));
- ion->pid = atoi(pid);
- return ion;
- }
- void
- upsert_data(struct io_node *ion)
- {
- struct io_node *n;
- /* List is empty. */
- if (head == NULL)
- {
- head = ion;
- return;
- }
- /* Check if we have seen this pid before. */
- n = head;
- while (n != NULL)
- {
- if (n->pid == ion->pid)
- {
- n->rchar = ion->rchar;
- n->wchar = ion->wchar;
- n->syscr = ion->syscr;
- n->syscw = ion->syscw;
- 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);
- free(ion);
- return;
- }
- n = n->next;
- }
- /* Add this pid to the list. */
- head = insert_ion(ion);
- return;
- }
- void
- usage()
- {
- 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");
- }
- int
- main(int argc, char *argv[])
- {
- int c;
- int delay = 0;
- int count = 0;
- int max_count = 1;
- while (1)
- {
- int option_index = 0;
- 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' },
- { 0, 0, 0, 0 }
- };
- c = getopt_long(argc, argv, "chikmu", long_options, &option_index);
- if (c == -1)
- {
- /* Handle delay and count arguments. */
- if (argc == optind)
- break; /* No additional arguments. */
- else if ((argc - optind) == 1)
- {
- delay = atoi(argv[optind]);
- max_count = -1;
- }
- else if ((argc - optind) == 2)
- {
- delay = atoi(argv[optind]);
- max_count = atoi(argv[optind + 1]);
- }
- else
- {
- /* Too many additional arguments. */
- usage();
- return 3;
- }
- break;
- }
- switch (c)
- {
- case 'c':
- command_flag = 1;
- break;
- case 'h':
- usage();
- return 0;
- case 'i':
- idle_flag = 1;
- break;
- case 'k':
- kb_flag = 1;
- break;
- case 'm':
- mb_flag = 1;
- break;
- case 'u':
- hr_flag = 1;
- break;
- default:
- usage();
- return 2;
- }
- }
- while (max_count == -1 || count++ < max_count)
- {
- get_stats();
- if (count != max_count)
- sleep(delay);
- }
- return 0;
- }
然后放到server上,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 运行的命令
版权声明:本文博客原创文章,博客,未经同意,不得转载。
Linux IO工具 iotop备择方案iopp的更多相关文章
- Linux进程实时IO监控iotop命令详解
介绍 Linux下的IO统计工具如iostat, nmon等大多数是只能统计到per设备的读写情况, 如果你想知道每个进程是如何使用IO的就比较麻烦. iotop 是一个用来监视磁盘 I/O 使用状况 ...
- Linux IO时事检测工具iostat
Linux IO时事检测工具iostat iostat命令用于检测linux系统io设备的负载情况,运行iostat将显示自上次运行该命令以后的统计信息.用户可以通过指定统计的次数和时间来获得所需的统 ...
- Linux性能工具介绍
l Linux性能工具介绍 p CPU高 p 磁盘I/O p 网络 p 内存 p 应用程序跟踪 l 操作系统与应用程序的关系比喻为“唇亡齿寒”一点不为过 l 应用程序的性能问题/功能问 ...
- Java开发人员必须掌握的两个Linux魔法工具(四)
子曰:"工欲善其事,必先利其器." 做一个积极的人 编码.改bug.提升自己 我有一个乐园,面向编程,春暖花开! 学习应该是快乐的,在这个乐园中我努力让自己能用简洁易懂(搞笑有趣) ...
- Linux IO 监控与深入分析
https://jaminzhang.github.io/os/Linux-IO-Monitoring-and-Deep-Analysis/ Linux IO 监控与深入分析 引言 接昨天电话面试,面 ...
- 【知乎网】Linux IO 多路复用 是什么意思?
提问一: Linux IO多路复用有 epoll, poll, select,知道epoll性能比其他几者要好.也在网上查了一下这几者的区别,表示没有弄明白. IO多路复用是什么意思,在实际的应用中是 ...
- linux IO诊断命令集
IO.sh ##iostat是查看磁盘活动统计情况 ##显示全部设备负载情况 r/s: 每秒完毕的读 I/O 设备次数.即 rio/s:w/s: 每秒完毕的写 I/O 设备次数.即 wio/s等 io ...
- block_dump观察Linux IO写入的具体文件(mysqld)
一.使用方法: 二.基本原理: 三.总结 很多情况下开发者调测程序需要在Linux下获取具体的IO的状况,目前常用的IO观察工具用vmstat和iostat,具体功能上说当然是iostat更胜一筹 ...
- Linux开发工具的使用
1. Linux开发工具的使用 Vim编译的使用 Gdb调试工具的使用 Makefile的编写 linux跟踪调试 SSH的使用 subversion的使用 1. Linux开发工具的使用 V ...
随机推荐
- Java反射机制小例子
package com.wjy.main; import java.io.Console; import java.lang.reflect.Constructor; import java.lang ...
- WebService之Soap头验证入门
1.新建一个类,如"AuthHeaderUser",继承于"System.Web.Services.Protocols.SoapHeader"类 2.新建Web ...
- 完美攻略心得之圣魔大战3(Castle Fantisia)艾伦希亚战记(艾伦西亚战记)包含重做版(即新艾伦希亚战记)
(城堡幻想曲3,纠正大家个错误哦,不是圣魔大战3,圣魔大战是城堡幻想曲2,圣魔大战不是个系列,艾伦西亚战记==艾伦希亚战记,一个游戏日文名:タイトル キャッスルファンタジア -エレンシア戦記-リニュー ...
- Android 性能优化 五 性能分析工具dumpsys的使用
Android提供的dumpsys工具能够用于查看感兴趣的系统服务信息与状态,手机连接电脑后能够直接命令行运行adb shell dumpsys 查看全部支持的Service可是这样输出的太多,能够通 ...
- DirectX11 学习笔记9 - 动态顶点缓冲区 和 静态顶点缓冲区
首先,什么是缓冲区: 缓冲区是.fx文件的影响(.ps .vs还) 一种数据结构,其定义了.为.fx和cpp数据通信文件. 例: //--------------------------------- ...
- 使用 DBMS_REPAIR 修复坏块
对于Oracle数据块物理损坏的情形,在我们有备份的情况下可以直接使用备份来恢复.对于通过备份恢复,Oracel为我们提供了很多种方式,冷备,基于用户管理方式,RMAN方式等等.对于这几种方式我们需要 ...
- Mysql学习笔记(二)数据类型 补充
原文:Mysql学习笔记(二)数据类型 补充 PS:简单的补充一下数据类型里的String类型以及列类型... 学习内容: 1.String类型 2.列类型存储需求 String类型: i.char与 ...
- 何谓集群(cluster)
1.簇 1.1 何谓集群 简单的说.簇(cluster)是一组计算机.他们,作为一个一般的为客户提供了一套网络资源.该计算机系统是集群中的单个节点(node). 个理想的集群是,用户从来不会意识到集群 ...
- IP Camera 和 Web Camera 差分
一直以来,,没太注意IP camera 和 Web Camera之间的差,这两个摄像头,昨天晚上.闲来无事Google少数,我们发现,还有两者之间的差异. 1) IP Camera IP Camera ...
- struts2在<s:select>用动态标签
后台传过来的必要性userlist成为一个下拉菜单.因此,认为使用<s:select>.但设置了很久设置的属性,在这个下跌. JSP代码: <s:select label=" ...