Linux IO tool iotop Alternatives Iopp

Source: Internet
Author: User
Tags readable

Iotop is undoubtedly a good tool for Linux IO detection, but in the kernel version and Python version, many friends give up, and so am I. Accidentally found Iopp, written in C, this with iotop is a role, nice! For everyone to share the next


The installation method is simple, first copy the following source code to save as iopp.c file

#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] = ' + '; v = Atoll (value); #define BTOKB (b) B >> 10#define Btomb (b) b >> #define Bufferlen 255#define commandlen 1024#define Valuelen #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 intindex = 0;register char *ret;register char t AG = ' B '; ret = Retarray[index];index = (index + 1)% Num_strings; if (AMT >= 10000) {Amt = (Amt +)/1024;tag = ' K '; if (AMT >= 10000) {Amt = (AMT +/)/1024;tag = ' B '; if (amt >= 10000) {Amt = (Amt +)/1024;tag = ' G ';}}} snprintf (ret, sizeof (RETARRAY[INDEX))-1, "%lld%c", AMT, TAG); return (ret);} Intget_cmdline (struct Io_node *ion) {int fd;int Length;char Filename[bufferlen + 1];char Buffer[commandlen + 1];char *p;ch  AR *q; length = snprintf (filename, Bufferlen, "%s/%d/cmdline", PROC, Ion->pid); if (length = = Bufferlen) printf ("Warning-file Name length May is too big for buffer:%d\n ", __line__); fd = open (filename, o_rdonly); if (fd = =-1) return 1;length = Read (f d, buffer, sizeof (buffer)-1);Close (FD); Buffer[length] = ' + '; if (length = = 0) return 2;if (Command_flag = = 0) {/* * The command is near the beginning; we Don ' t need to is able to * the entire stat file. */p = STRCHR (buffer, ' ('); ++p;q = STRCHR (P, ') '); length = q-p;} Elsep = Buffer;length = length < Commandlen? length:commandlen;strncpy (Ion->command, p, length); Ion->command[length] = ' n '; 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;} Intget_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-filenam E length is 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 being 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] = ' n '; 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 SP Ecial case. */if (Ion->pid < head->pid) {Ion->next = Head;head = Ion;return head;} c = Head->next;p = Head;while (c! = N ULL) {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;} Voidget_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", "writ Es "," 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", "C WMB "," command "); elseprintf ("%5s%8s%8s%8s%8s%8s%8s%8s%s\n "," pid "," Rchar "," WCHAR "," Syscr "," SYSCW "," Rbytes "," W Bytes "," 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 Rchar;long long Wchar;long long Syscr;long long Syscw;long long Read_bytes;long long Write_bytes;long long cance Lled_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 was 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-file Name length May is 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] = ' + '; /* Parsing the IO file data. */p = buffer; Get_value (Ion->rchar); Get_value (Ion->wchar); Get_value (ION-&GT;SYSCR); Get_value (ION-&GT;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-&GT;WCHAR-OLD_ION-&GT;WCHAR;SYSCR = Ion-&gt ; SYSCR-OLD_ION-&GT;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 (sys CW); 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 = Btom B (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 &AMP;&AMP;SYSCW = 0 && read_byte s = = 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) elseprintf ("%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 Pro Cesses. */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;}  Voidupsert_data (struct Io_node *ion) {struct Io_node *n;/* List is empty. */if (head = = NULL) {head = Ion;return;}/* Check If we have the seen this PID before. */n = Head;while (n! = NULL) {if (n->pid = = ion->pid) {N->rchar = Ion->rchar;n->wchar = Ion->wchar;n->s YSCR = ION-&GT;SYSCR;N-&GT;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 is 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;} Voidusage () {printf ("usage:iopp-h|--help\n");p rintf ("Usage:iopp [-ci] [-k|-m] [delay [count]]\n];p rintf ("-C ,--command Display full command line\n ");p rintf ("-H,--help display help\n ");p rintf ("-I,--idle h Ides Idle processes\n ");p rintf ("-K,--kilobytes display data in kilobytes\n ");p rintf ("-M,--megaby TES display data in megabytes\n ");p rintf ("-U,--human-readable display data in kilo-, mega-, or giga-bytes\n ") ;} Intmain (int argc, char *argv[]) {int c; int delay = 0;int Count = 0;int Max_count = 1; while (1) {int option_index = 0;stati c struct option long_options[] = {"Command", no_argument, 0, ' C '},{"help", no_argument, 0, ' h '},{"human-readable", n O_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;bre Ak;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;}


And then put it on the server,gcc-o Iopp iopp.c compile a bit

Run./iopp-i-k-c 1 > Io.log This command will print out the real-time IO information.

Print out the meanings of each:

  • PID Process ID
  • Rchar number of bytes to be read from disk
  • The number of bytes WChar has written to or should be written to disk
  • SYSCR read I/O number
  • SYSCW write I/o number
  • Rbytes number of bytes actually read from disk
  • Wbytes number of bytes actually written to disk
  • Cwbytes number of bytes that did not occur because the page cache was emptied
  • Commands executed by command


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.