iotop毫无疑问linux IO检测上是一个很好的工具,但苦于要求和内核版本Python版本号。我的很多朋友放弃了。我也是。无意中发现iopp,使用c书面,与此iotop它是一个作用。nice!

一起分享

安装方法非常easy。首先复制以下源码保存为iopp.c文件

  1. #include <stdio.h>
  2. #include <sys/types.h>
  3. #include <dirent.h>
  4. #include <ctype.h>
  5. #include <sys/stat.h>
  6. #include <fcntl.h>
  7. #include <unistd.h>
  8. #include <string.h>
  9. #include <stdlib.h>
  10. #include <getopt.h>
  11.  
  12. #define PROC "/proc"
  13.  
  14. #define GET_VALUE(v) \
  15. p = strchr(p, ':'); \
  16. ++p; \
  17. ++p; \
  18. q = strchr(p, '\n'); \
  19. length = q - p; \
  20. if (length >= BUFFERLEN) \
  21. { \
  22. printf("ERROR - value is larger than the buffer: %d\n", __LINE__); \
  23. exit(1); \
  24. } \
  25. strncpy(value, p, length); \
  26. value[length] = '\0'; \
  27. v = atoll(value);
  28.  
  29. #define BTOKB(b) b >> 10
  30. #define BTOMB(b) b >> 20
  31.  
  32. #define BUFFERLEN 255
  33. #define COMMANDLEN 1024
  34. #define VALUELEN 63
  35.  
  36. #define NUM_STRINGS 8
  37.  
  38. struct io_node
  39. {
  40. int pid;
  41. long long rchar;
  42. long long wchar;
  43. long long syscr;
  44. long long syscw;
  45. long long read_bytes;
  46. long long write_bytes;
  47. long long cancelled_write_bytes;
  48. char command[COMMANDLEN + 1];
  49. struct io_node *next;
  50. };
  51.  
  52. struct io_node *head = NULL;
  53. int command_flag = 0;
  54. int idle_flag = 0;
  55. int mb_flag = 0;
  56. int kb_flag = 0;
  57. int hr_flag = 0;
  58.  
  59. /* Prototypes */
  60. char *format_b(long long);
  61. struct io_node *get_ion(int);
  62. struct io_node *new_ion(char *);
  63. void upsert_data(struct io_node *);
  64.  
  65. char *
  66. format_b(long long amt)
  67. {
  68. static char retarray[NUM_STRINGS][16];
  69. static int index = 0;
  70. register char *ret;
  71. register char tag = 'B';
  72.  
  73. ret = retarray[index];
  74. index = (index + 1) % NUM_STRINGS;
  75.  
  76. if (amt >= 10000) {
  77. amt = (amt + 512) / 1024;
  78. tag = 'K';
  79. if (amt >= 10000) {
  80. amt = (amt + 512) / 1024;
  81. tag = 'B';
  82. if (amt >= 10000) {
  83. amt = (amt + 512) / 1024;
  84. tag = 'G';
  85. }
  86. }
  87. }
  88.  
  89. snprintf(ret, sizeof(retarray[index]) - 1, "%lld%c", amt, tag);
  90.  
  91. return (ret);
  92. }
  93.  
  94. int
  95. get_cmdline(struct io_node *ion)
  96. {
  97. int fd;
  98. int length;
  99. char filename[BUFFERLEN + 1];
  100. char buffer[COMMANDLEN + 1];
  101. char *p;
  102. char *q;
  103.  
  104. length = snprintf(filename, BUFFERLEN, "%s/%d/cmdline", PROC, ion->pid);
  105. if (length == BUFFERLEN)
  106. printf("WARNING - filename length may be too big for buffer: %d\n",
  107. __LINE__);
  108. fd = open(filename, O_RDONLY);
  109. if (fd == -1)
  110. return 1;
  111. length = read(fd, buffer, sizeof(buffer) - 1);
  112. close(fd);
  113. buffer[length] = '\0';
  114. if (length == 0)
  115. return 2;
  116. if (command_flag == 0)
  117. {
  118. /*
  119. * The command is near the beginning; we don't need to be able to
  120. * the entire stat file.
  121. */
  122. p = strchr(buffer, '(');
  123. ++p;
  124. q = strchr(p, ')');
  125. length = q - p;
  126. }
  127. else
  128. p = buffer;
  129. length = length < COMMANDLEN ? length : COMMANDLEN;
  130. strncpy(ion->command, p, length);
  131. ion->command[length] = '\0';
  132. return 0;
  133. }
  134.  
  135. struct io_node *
  136. get_ion(int pid)
  137. {
  138. struct io_node *c = head;
  139.  
  140. while (c != NULL)
  141. {
  142. if (c->pid == pid)
  143. break;
  144. c = c->next;
  145. }
  146. return c;
  147. }
  148.  
  149. int
  150. get_tcomm(struct io_node *ion)
  151. {
  152. int fd;
  153. int length;
  154. char filename[BUFFERLEN + 1];
  155. char buffer[BUFFERLEN + 1];
  156. char *p;
  157. char *q;
  158.  
  159. length = snprintf(filename, BUFFERLEN, "%s/%d/stat", PROC, ion->pid);
  160. if (length == BUFFERLEN)
  161. printf("WARNING - filename length may be too big for buffer: %d\n",
  162. __LINE__);
  163. fd = open(filename, O_RDONLY);
  164. if (fd == -1)
  165. return 1;
  166. length = read(fd, buffer, sizeof(buffer) - 1);
  167. close(fd);
  168. /*
  169. * The command is near the beginning; we don't need to be able to
  170. * the entire stat file.
  171. */
  172. p = strchr(buffer, '(');
  173. ++p;
  174. q = strchr(p, ')');
  175. length = q - p;
  176. length = length < BUFFERLEN ?
  177.  
  178. length : BUFFERLEN;
  179.  
  180. strncpy(ion->command, p, length);
  181. ion->command[length] = '\0';
  182. return 0;
  183. }
  184.  
  185. struct io_node *
  186. insert_ion(struct io_node *ion)
  187. {
  188. struct io_node *c;
  189. struct io_node *p;
  190.  
  191. /* Check the head of the list as a special case. */
  192. if (ion->pid < head->pid)
  193. {
  194. ion->next = head;
  195. head = ion;
  196. return head;
  197. }
  198.  
  199. c = head->next;
  200. p = head;
  201. while (c != NULL)
  202. {
  203. if (ion->pid < c->pid)
  204. {
  205. ion->next = c;
  206. p->next = ion;
  207. return head;
  208. }
  209. p = c;
  210. c = c->next;
  211. }
  212.  
  213. /* Append to the end of the list. */
  214. if (c == NULL)
  215. p->next = ion;
  216.  
  217. return head;
  218. }
  219.  
  220. void
  221. get_stats()
  222. {
  223. DIR *dir = opendir(PROC);
  224. struct dirent *ent;
  225. char filename[BUFFERLEN + 1];
  226. char buffer[BUFFERLEN + 1];
  227.  
  228. char value[BUFFERLEN + 1];
  229.  
  230. /* Display column headers. */
  231. if (hr_flag == 1)
  232. printf("%5s %5s %5s %8s %8s %5s %6s %7s %s\n", "pid", "rchar", "wchar",
  233. "syscr", "syscw", "reads", "writes", "cwrites", "command");
  234. else if (kb_flag == 1)
  235. printf("%5s %8s %8s %8s %8s %8s %8s %8s %s\n", "pid", "rchar", "wchar",
  236. "syscr", "syscw", "rkb", "wkb", "cwkb", "command");
  237. else if (mb_flag == 1)
  238. printf("%5s %8s %8s %8s %8s %8s %8s %8s %s\n", "pid", "rchar", "wchar",
  239. "syscr", "syscw", "rmb", "wmb", "cwmb", "command");
  240. else
  241. printf("%5s %8s %8s %8s %8s %8s %8s %8s %s\n", "pid", "rchar", "wchar",
  242. "syscr", "syscw", "rbytes", "wbytes", "cwbytes", "command");
  243.  
  244. /* Loop through the process table and display a line per pid. */
  245. while ((ent = readdir(dir)) != NULL)
  246. {
  247. int rc;
  248. int fd;
  249. int length;
  250.  
  251. char *p;
  252. char *q;
  253.  
  254. struct io_node *ion;
  255. struct io_node *old_ion;
  256.  
  257. long long rchar;
  258. long long wchar;
  259. long long syscr;
  260. long long syscw;
  261. long long read_bytes;
  262. long long write_bytes;
  263. long long cancelled_write_bytes;
  264.  
  265. if (!isdigit(ent->d_name[0]))
  266. continue;
  267.  
  268. ion = new_ion(ent->d_name);
  269.  
  270. if (command_flag == 1)
  271. rc = get_cmdline(ion);
  272. if (command_flag == 0 || rc != 0)
  273. /* If the full command line is not asked for or is empty... */
  274. rc = get_tcomm(ion);
  275.  
  276. if (rc != 0)
  277. {
  278. free(ion);
  279. continue;
  280. }
  281.  
  282. /* Read 'io' file. */
  283. length = snprintf(filename, BUFFERLEN, "%s/%s/io", PROC, ent->d_name);
  284. if (length == BUFFERLEN)
  285. printf("WARNING - filename length may be too big for buffer: %d\n",
  286. __LINE__);
  287. fd = open(filename, O_RDONLY);
  288. if (fd == -1)
  289. {
  290. free(ion);
  291. continue;
  292. }
  293. length = read(fd, buffer, sizeof(buffer) - 1);
  294. close(fd);
  295. buffer[length] = '\0';
  296.  
  297. /* Parsing the io file data. */
  298. p = buffer;
  299. GET_VALUE(ion->rchar);
  300. GET_VALUE(ion->wchar);
  301. GET_VALUE(ion->syscr);
  302. GET_VALUE(ion->syscw);
  303. GET_VALUE(ion->read_bytes);
  304. GET_VALUE(ion->write_bytes);
  305. GET_VALUE(ion->cancelled_write_bytes);
  306.  
  307. old_ion = get_ion(ion->pid);
  308.  
  309. /* Display the pid's io data. */
  310. if (old_ion != NULL)
  311. {
  312. rchar = ion->rchar - old_ion->rchar;
  313. wchar = ion->wchar - old_ion->wchar;
  314. syscr = ion->syscr - old_ion->syscr;
  315. syscw = ion->syscw - old_ion->syscw;
  316. read_bytes = ion->read_bytes - old_ion->read_bytes;
  317. write_bytes = ion->write_bytes - old_ion->write_bytes;
  318. cancelled_write_bytes = ion->cancelled_write_bytes -
  319. old_ion->cancelled_write_bytes;
  320.  
  321. if (kb_flag == 1 && hr_flag == 0)
  322. {
  323. rchar = BTOKB(rchar);
  324. wchar = BTOKB(wchar);
  325. syscr = BTOKB(syscr);
  326. syscw = BTOKB(syscw);
  327. read_bytes = BTOKB(read_bytes);
  328. write_bytes = BTOKB(write_bytes);
  329. cancelled_write_bytes = BTOKB(cancelled_write_bytes);
  330. }
  331. else if (mb_flag == 1 && hr_flag == 0)
  332. {
  333. rchar = BTOMB(rchar);
  334. wchar = BTOMB(wchar);
  335. syscr = BTOMB(syscr);
  336. syscw = BTOMB(syscw);
  337. read_bytes = BTOMB(read_bytes);
  338. write_bytes = BTOMB(write_bytes);
  339. cancelled_write_bytes = BTOMB(cancelled_write_bytes);
  340. }
  341.  
  342. if (!(idle_flag == 1 && rchar == 0 && wchar == 0 && syscr == 0 &&
  343. syscw == 0 && read_bytes == 0 && write_bytes == 0 &&
  344. cancelled_write_bytes == 0)) {
  345. if (hr_flag == 0)
  346. printf("%5d %8lld %8lld %8lld %8lld %8lld %8lld %8lld %s\n",
  347. ion->pid,
  348. rchar,
  349. wchar,
  350. syscr,
  351. syscw,
  352. read_bytes,
  353. write_bytes,
  354. cancelled_write_bytes,
  355. ion->command);
  356. else
  357. printf("%5d %5s %5s %8lld %8lld %5s %6s %7s %s\n",
  358. ion->pid,
  359. format_b(rchar),
  360. format_b(wchar),
  361. syscr,
  362. syscw,
  363. format_b(read_bytes),
  364. format_b(write_bytes),
  365. format_b(cancelled_write_bytes),
  366. ion->command);
  367. }
  368. }
  369. else if (idle_flag != 1)
  370. /*
  371. * No previous data, show 0's instead of calculating negatives
  372. * only if we are shoring idle processes.
  373. */
  374. printf("%5d %8d %8d %8d %8d %8d %8d %8d %s\n",
  375. ion->pid, 0, 0, 0, 0, 0, 0, 0, ion->command);
  376.  
  377. upsert_data(ion);
  378. }
  379. closedir(dir);
  380. return;
  381. }
  382.  
  383. struct io_node *
  384. new_ion(char *pid)
  385. {
  386. struct io_node *ion;
  387.  
  388. ion = (struct io_node *) malloc(sizeof(struct io_node));
  389. bzero(ion, sizeof(struct io_node));
  390. ion->pid = atoi(pid);
  391.  
  392. return ion;
  393. }
  394.  
  395. void
  396. upsert_data(struct io_node *ion)
  397. {
  398. struct io_node *n;
  399.  
  400. /* List is empty. */
  401. if (head == NULL)
  402. {
  403. head = ion;
  404. return;
  405. }
  406.  
  407. /* Check if we have seen this pid before. */
  408. n = head;
  409. while (n != NULL)
  410. {
  411. if (n->pid == ion->pid)
  412. {
  413. n->rchar = ion->rchar;
  414. n->wchar = ion->wchar;
  415. n->syscr = ion->syscr;
  416. n->syscw = ion->syscw;
  417. n->read_bytes = ion->read_bytes;
  418. n->write_bytes = ion->write_bytes;
  419. n->cancelled_write_bytes = ion->cancelled_write_bytes;
  420. /*
  421. * If the pids wrap, then the command may be different then before.
  422. */
  423. strcpy(n->command, ion->command);
  424. free(ion);
  425. return;
  426. }
  427. n = n->next;
  428. }
  429.  
  430. /* Add this pid to the list. */
  431. head = insert_ion(ion);
  432. return;
  433. }
  434.  
  435. void
  436. usage()
  437. {
  438. printf("usage: iopp -h|--help\n");
  439. printf("usage: iopp [-ci] [-k|-m] [delay [count]]\n");
  440. printf(" -c, --command display full command line\n");
  441. printf(" -h, --help display help\n");
  442. printf(" -i, --idle hides idle processes\n");
  443. printf(" -k, --kilobytes display data in kilobytes\n");
  444. printf(" -m, --megabytes display data in megabytes\n");
  445. printf(" -u, --human-readable display data in kilo-, mega-, or giga-bytes\n");
  446. }
  447.  
  448. int
  449. main(int argc, char *argv[])
  450. {
  451. int c;
  452.  
  453. int delay = 0;
  454. int count = 0;
  455. int max_count = 1;
  456.  
  457. while (1)
  458. {
  459. int option_index = 0;
  460. static struct option long_options[] = {
  461. { "command", no_argument, 0, 'c' },
  462. { "help", no_argument, 0, 'h' },
  463. { "human-readable", no_argument, 0, 'u' },
  464. { "idle", no_argument, 0, 'i' },
  465. { "kilobytes", no_argument, 0, 'k' },
  466. { "megabytes", no_argument, 0, 'm' },
  467. { 0, 0, 0, 0 }
  468. };
  469.  
  470. c = getopt_long(argc, argv, "chikmu", long_options, &option_index);
  471. if (c == -1)
  472. {
  473. /* Handle delay and count arguments. */
  474.  
  475. if (argc == optind)
  476. break; /* No additional arguments. */
  477. else if ((argc - optind) == 1)
  478. {
  479. delay = atoi(argv[optind]);
  480. max_count = -1;
  481. }
  482. else if ((argc - optind) == 2)
  483. {
  484. delay = atoi(argv[optind]);
  485. max_count = atoi(argv[optind + 1]);
  486. }
  487. else
  488. {
  489. /* Too many additional arguments. */
  490. usage();
  491. return 3;
  492. }
  493. break;
  494. }
  495.  
  496. switch (c)
  497. {
  498. case 'c':
  499. command_flag = 1;
  500. break;
  501. case 'h':
  502. usage();
  503. return 0;
  504. case 'i':
  505. idle_flag = 1;
  506. break;
  507. case 'k':
  508. kb_flag = 1;
  509. break;
  510. case 'm':
  511. mb_flag = 1;
  512. break;
  513. case 'u':
  514. hr_flag = 1;
  515. break;
  516. default:
  517. usage();
  518. return 2;
  519. }
  520. }
  521.  
  522. while (max_count == -1 || count++ < max_count)
  523. {
  524. get_stats();
  525. if (count != max_count)
  526. sleep(delay);
  527. }
  528. return 0;
  529. }

然后放到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的更多相关文章

  1. Linux进程实时IO监控iotop命令详解

    介绍 Linux下的IO统计工具如iostat, nmon等大多数是只能统计到per设备的读写情况, 如果你想知道每个进程是如何使用IO的就比较麻烦. iotop 是一个用来监视磁盘 I/O 使用状况 ...

  2. Linux IO时事检测工具iostat

    Linux IO时事检测工具iostat iostat命令用于检测linux系统io设备的负载情况,运行iostat将显示自上次运行该命令以后的统计信息.用户可以通过指定统计的次数和时间来获得所需的统 ...

  3. Linux性能工具介绍

    l  Linux性能工具介绍 p  CPU高 p  磁盘I/O p  网络 p  内存 p  应用程序跟踪 l  操作系统与应用程序的关系比喻为“唇亡齿寒”一点不为过 l  应用程序的性能问题/功能问 ...

  4. Java开发人员必须掌握的两个Linux魔法工具(四)

    子曰:"工欲善其事,必先利其器." 做一个积极的人 编码.改bug.提升自己 我有一个乐园,面向编程,春暖花开! 学习应该是快乐的,在这个乐园中我努力让自己能用简洁易懂(搞笑有趣) ...

  5. Linux IO 监控与深入分析

    https://jaminzhang.github.io/os/Linux-IO-Monitoring-and-Deep-Analysis/ Linux IO 监控与深入分析 引言 接昨天电话面试,面 ...

  6. 【知乎网】Linux IO 多路复用 是什么意思?

    提问一: Linux IO多路复用有 epoll, poll, select,知道epoll性能比其他几者要好.也在网上查了一下这几者的区别,表示没有弄明白. IO多路复用是什么意思,在实际的应用中是 ...

  7. linux IO诊断命令集

    IO.sh ##iostat是查看磁盘活动统计情况 ##显示全部设备负载情况 r/s: 每秒完毕的读 I/O 设备次数.即 rio/s:w/s: 每秒完毕的写 I/O 设备次数.即 wio/s等 io ...

  8. block_dump观察Linux IO写入的具体文件(mysqld)

      一.使用方法: 二.基本原理: 三.总结 很多情况下开发者调测程序需要在Linux下获取具体的IO的状况,目前常用的IO观察工具用vmstat和iostat,具体功能上说当然是iostat更胜一筹 ...

  9. Linux开发工具的使用

    1.   Linux开发工具的使用 Vim编译的使用 Gdb调试工具的使用 Makefile的编写 linux跟踪调试 SSH的使用 subversion的使用 1.   Linux开发工具的使用 V ...

随机推荐

  1. Java反射机制小例子

    package com.wjy.main; import java.io.Console; import java.lang.reflect.Constructor; import java.lang ...

  2. WebService之Soap头验证入门

    1.新建一个类,如"AuthHeaderUser",继承于"System.Web.Services.Protocols.SoapHeader"类 2.新建Web ...

  3. 完美攻略心得之圣魔大战3(Castle Fantisia)艾伦希亚战记(艾伦西亚战记)包含重做版(即新艾伦希亚战记)

    (城堡幻想曲3,纠正大家个错误哦,不是圣魔大战3,圣魔大战是城堡幻想曲2,圣魔大战不是个系列,艾伦西亚战记==艾伦希亚战记,一个游戏日文名:タイトル キャッスルファンタジア -エレンシア戦記-リニュー ...

  4. Android 性能优化 五 性能分析工具dumpsys的使用

    Android提供的dumpsys工具能够用于查看感兴趣的系统服务信息与状态,手机连接电脑后能够直接命令行运行adb shell dumpsys 查看全部支持的Service可是这样输出的太多,能够通 ...

  5. DirectX11 学习笔记9 - 动态顶点缓冲区 和 静态顶点缓冲区

    首先,什么是缓冲区: 缓冲区是.fx文件的影响(.ps .vs还) 一种数据结构,其定义了.为.fx和cpp数据通信文件. 例: //--------------------------------- ...

  6. 使用 DBMS_REPAIR 修复坏块

    对于Oracle数据块物理损坏的情形,在我们有备份的情况下可以直接使用备份来恢复.对于通过备份恢复,Oracel为我们提供了很多种方式,冷备,基于用户管理方式,RMAN方式等等.对于这几种方式我们需要 ...

  7. Mysql学习笔记(二)数据类型 补充

    原文:Mysql学习笔记(二)数据类型 补充 PS:简单的补充一下数据类型里的String类型以及列类型... 学习内容: 1.String类型 2.列类型存储需求 String类型: i.char与 ...

  8. 何谓集群(cluster)

    1.簇 1.1 何谓集群 简单的说.簇(cluster)是一组计算机.他们,作为一个一般的为客户提供了一套网络资源.该计算机系统是集群中的单个节点(node). 个理想的集群是,用户从来不会意识到集群 ...

  9. IP Camera 和 Web Camera 差分

    一直以来,,没太注意IP camera 和 Web Camera之间的差,这两个摄像头,昨天晚上.闲来无事Google少数,我们发现,还有两者之间的差异. 1) IP Camera IP Camera ...

  10. struts2在&lt;s:select&gt;用动态标签

    后台传过来的必要性userlist成为一个下拉菜单.因此,认为使用<s:select>.但设置了很久设置的属性,在这个下跌. JSP代码: <s:select label=" ...