bash iostat - ceragon/LinuxDoc GitHub Wiki
iostat 属于 sysstat 工程
$ iostat
Linux 5.15.0-30-generic (ceragon-ThinkPad-T440p) 2022年05月17日 _x86_64_ (4 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
7.08 0.02 0.54 0.04 0.00 92.32
Device tps kB_read/s kB_wrtn/s kB_dscd/s kB_read kB_wrtn kB_dscd
loop0 0.00 0.00 0.00 0.00 17 0 0
loop1 0.00 0.01 0.00 0.00 351 0 0
loop10 0.00 0.01 0.00 0.00 188 0 0
loop11 0.00 0.01 0.00 0.00 347 0 0
loop12 0.00 0.00 0.00 0.00 14 0 0
loop2 0.04 0.74 0.00 0.00 22103 0 0
loop3 0.00 0.04 0.00 0.00 1101 0 0
loop4 0.11 1.70 0.00 0.00 51019 0 0
loop5 0.10 5.94 0.00 0.00 178375 0 0
loop6 0.10 0.27 0.00 0.00 8216 0 0
loop7 0.00 0.01 0.00 0.00 350 0 0
loop8 0.04 0.47 0.00 0.00 14133 0 0
loop9 0.00 0.05 0.00 0.00 1652 0 0
sda 0.03 0.19 2.58 0.00 5624 77396 0
sdb 13.25 250.90 343.41 0.00 7537140 10316277 0
sr0 0.00 0.00 0.00 0.00 2 0 0
只考虑IO数据的部分,下面用于显示标题行
void write_disk_stat_header(int *fctr, int *tab, int hpart) {
char *units, *spc;
units = "kB";
spc = " ";
if (!DISPLAY_PRETTY(flags)) {
printf("Device ");
}
if (DISPLAY_EXTENDED(flags)) {
} else {
if (DISPLAY_SHORT_OUTPUT(flags)) {
} else {
printf(" tps %s%s_read/s %s%s_wrtn/s %s%s_dscd/s %s%s_read %s%s_wrtn %s%s_dscd",
spc, units, spc, units, spc, units, spc, units, spc, units, spc, units);
}
}
}
int flags = 0;
struct io_device *dev_list = NULL;
void write_stats(int curr, struct tm *rectime, int skip) {
int h, hl = 0, hh = 0, fctr = 1, tab = 4, next = FALSE;
unsigned long long itv;
/* Calculate time interval in 1/100th of a second */
itv = get_interval(uptime_cs[!curr], uptime_cs[curr]);
if (DISPLAY_DISK(flags)) {
struct io_stats *ioi, *ioj, iozero;
for (h = hl; h <= hh; h++) {
for (d = dev_list; ; d = dnext) {
dnext = d->next;
ioi = d->dev_stats[curr];
ioj = d->dev_stats[!curr];
dev_name = get_device_name(d->major, d->minor, NULL, 0,
DISPLAY_DEVMAP_NAME(flags),
DISPLAY_PERSIST_NAME_I(flags),
FALSE, d->name);
if (!skip) {
if (DISPLAY_EXTENDED(flags)) {
} else {
// itv 是时间差值
// fctr 默认值是1
write_basic_stat(itv, fctr, d, ioi, ioj, tab, dev_name);
}
}
}
}
}
}
void write_basic_stat(unsigned long long itv, int fctr,
struct io_device *d, struct io_stats *ioi,
struct io_stats *ioj, int tab, char *dname) {
unsigned long long rd_sec, wr_sec, dc_sec;
rd_sec = ioi->rd_sectors - ioj->rd_sectors;
wr_sec = ioi->wr_sectors - ioj->wr_sectors;
dc_sec = ioi->dc_sectors - ioj->dc_sectors;
if (DISPLAY_JSON_OUTPUT(flags)) {
} else {
write_plain_basic_stat(itv, fctr, ioi, ioj, dname,
rd_sec, wr_sec, dc_sec);
}
}
void write_plain_basic_stat(unsigned long long itv, int fctr,
struct io_stats *ioi, struct io_stats *ioj,
char *devname, unsigned long long rd_sec,
unsigned long long wr_sec, unsigned long long dc_sec) {
double rsectors, wsectors, dsectors;
// ((ioi - ioj) / itv) * 100
rsectors = S_VALUE(ioj->rd_sectors, ioi->rd_sectors, itv);
wsectors = S_VALUE(ioj->wr_sectors, ioi->wr_sectors, itv);
dsectors = S_VALUE(ioj->dc_sectors, ioi->dc_sectors, itv);
if (!DISPLAY_UNIT(flags)) {
rsectors /= fctr;
wsectors /= fctr;
dsectors /= fctr;
}
if (!DISPLAY_PRETTY(flags)) {
cprintf_in(IS_STR, "%-13s", devname, 0);
}
/* tps */
cprintf_f(NO_UNIT, 1, 8, 2,
/* Origin (unmerged) flush operations are counted as writes */
S_VALUE(ioj->rd_ios + ioj->wr_ios + ioj->dc_ios,
ioi->rd_ios + ioi->wr_ios + ioi->dc_ios, itv));
if (DISPLAY_SHORT_OUTPUT(flags)) {
} else {
/* kB_read/s kB_wrtn/s kB_dscd/s */
cprintf_f(DISPLAY_UNIT(flags) ? UNIT_SECTOR : NO_UNIT, 3, 12, 2,
rsectors, wsectors, dsectors);
/* kB_read kB_wrtn kB_dscd */
cprintf_u64(DISPLAY_UNIT(flags) ? UNIT_SECTOR : NO_UNIT, 3, 10,
DISPLAY_UNIT(flags) ? (unsigned long long) rd_sec
: (unsigned long long) rd_sec / fctr,
DISPLAY_UNIT(flags) ? (unsigned long long) wr_sec
: (unsigned long long) wr_sec / fctr,
DISPLAY_UNIT(flags) ? (unsigned long long) dc_sec
: (unsigned long long) dc_sec / fctr);
}
printf("\n");
}
$ cat /proc/diskstats
7 0 loop0 14 0 34 1 0 0 0 0 0 20 1 0 0 0 0 0 0
7 1 loop1 45 0 702 46 0 0 0 0 0 72 46 0 0 0 0 0 0
7 2 loop2 1123 0 48088 263 0 0 0 0 0 2676 263 0 0 0 0 0 0
7 3 loop3 61 0 2208 45 0 0 0 0 0 64 45 0 0 0 0 0 0
7 4 loop4 3465 0 106416 634 0 0 0 0 0 6288 634 0 0 0 0 0 0
7 5 loop5 2926 0 356756 907 0 0 0 0 0 4128 907 0 0 0 0 0 0
7 6 loop6 3153 0 16442 137 0 0 0 0 0 1120 137 0 0 0 0 0 0
7 7 loop7 43 0 700 14 0 0 0 0 0 28 14 0 0 0 0 0 0
8 0 sda 795 24 11305 143450 108 15 154792 4470 0 13432 148450 0 0 0 0 30 529
8 1 sda1 370 24 8714 133638 108 15 154792 4470 0 4092 138108 0 0 0 0 0 0
8 16 sdb 321538 85929 15917616 133118 96261 489238 21298746 418453 0 568976 579014 0 0 0 0 13306 27442
8 17 sdb1 26 0 208 364 0 0 0 0 0 384 364 0 0 0 0 0 0
8 18 sdb2 147 23 10992 486 2 0 2 0 0 544 486 0 0 0 0 0 0
8 19 sdb3 320822 85906 15900258 131753 96259 489238 21298744 418453 0 568312 550207 0 0 0 0 0 0
11 0 sr0 10 0 4 7 0 0 0 0 0 28 7 0 0 0 0 0 0
7 8 loop8 1102 0 28980 216 0 0 0 0 0 1984 216 0 0 0 0 0 0
7 11 loop11 43 0 694 11 0 0 0 0 0 44 11 0 0 0 0 0 0
7 9 loop9 145 0 8316 49 0 0 0 0 0 376 49 0 0 0 0 0 0
7 10 loop10 29 0 378 7 0 0 0 0 0 60 7 0 0 0 0 0 0
7 12 loop12 73 0 2216 3 0 0 0 0 0 48 3 0 0 0 0 0 0
void read_diskstats_stat_work(int curr, char *diskstats) {
// diskstats = /proc/diskstats
FILE *fp;
char line[256];
struct io_stats sdev;
int i;
unsigned int ios_pgr, tot_ticks, rq_ticks, wr_ticks, dc_ticks, fl_ticks;
unsigned long rd_ios, rd_merges_or_rd_sec, rd_ticks_or_wr_sec, wr_ios;
unsigned long wr_merges, rd_sec_or_wr_ios, wr_sec;
unsigned long dc_ios, dc_merges, dc_sec, fl_ios;
unsigned int major, minor;
if ((fp = fopen(diskstats, "r")) == NULL)
return;
while (fgets(line, sizeof(line), fp) != NULL) {
i = sscanf(line, "%u %u %s %lu %lu %lu %lu %lu %lu %lu %u %u %u %u %lu %lu %lu %u %lu %u",
&major, &minor, dev_name,
&rd_ios, &rd_merges_or_rd_sec, &rd_sec_or_wr_ios, &rd_ticks_or_wr_sec,
&wr_ios, &wr_merges, &wr_sec, &wr_ticks, &ios_pgr, &tot_ticks, &rq_ticks,
&dc_ios, &dc_merges, &dc_sec, &dc_ticks,
&fl_ios, &fl_ticks);
if (i >= 14) {
// 第 4个参数
sdev.rd_ios = rd_ios;
// 第 8个参数
sdev.wr_ios = wr_ios;
// 第 15个参数
sdev.dc_ios = dc_ios;
// 第 6个参数
sdev.rd_sectors = rd_sec_or_wr_ios;
// 第 10个参数
sdev.wr_sectors = wr_sec;
// 第 17个参数
sdev.dc_sectors = dc_sec;
}
d = add_list_device(&dev_list, dev_name, 0, major, minor);
if (d != NULL) {
*d->dev_stats[curr] = sdev;
}
}
}
- tps : 单位时间 IO 的请求数
- read/s: 单位时间内平均每秒 读 IO 的数量
- wrtn/s: 单位时间平均每秒 写 IO 的数量
- read: 单位时间内 读 IO的数据量,单位KB
- wrtn: 单位时间内 读 IO的数据量, 单位KB