Skip to content

Commit bbd9856

Browse files
committed
Introduce DiskIORateMeter and DiskIOTimeMeter
The two meters are split from DiskIOMeter and they allow separate display of disk read & write rates and the busy time percentage, including drawing the data as separate bars and graphs. The old DiskIOMeter is kept for backward compatibility. It will be reworked in the next commit. Note that DiskIORateMeter and DiskIOTimeMeter have different 'isPercentChart' values. Signed-off-by: Kang-Che Sung <explorer09@gmail.com>
1 parent 78086b5 commit bbd9856

8 files changed

Lines changed: 174 additions & 0 deletions

File tree

DiskIOMeter.c

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,27 @@ in the source distribution for its full text.
2121
#include "XUtils.h"
2222

2323

24+
static const int DiskIORateMeter_attributes[] = {
25+
METER_VALUE_IOREAD,
26+
METER_VALUE_IOWRITE,
27+
};
28+
29+
static const int DiskIOTimeMeter_attributes[] = {
30+
METER_VALUE_NOTICE,
31+
};
32+
2433
static const int DiskIOMeter_attributes[] = {
2534
METER_VALUE_NOTICE,
2635
METER_VALUE_IOREAD,
2736
METER_VALUE_IOWRITE,
2837
};
2938

3039
static MeterRateStatus status = RATESTATUS_INIT;
40+
static double cached_read_diff;
3141
static char cached_read_diff_str[6];
42+
static double cached_write_diff;
3243
static char cached_write_diff_str[6];
44+
static uint64_t cached_num_disks;
3345
static double cached_utilisation_diff;
3446
static double cached_utilisation_norm;
3547

@@ -73,6 +85,7 @@ static void DiskIOUpdateCache(const Machine* host) {
7385
} else {
7486
diff = 0;
7587
}
88+
cached_read_diff = diff;
7689
Meter_humanUnit(cached_read_diff_str, diff, sizeof(cached_read_diff_str));
7790

7891
if (data.totalBytesWritten > cached_write_total) {
@@ -82,8 +95,10 @@ static void DiskIOUpdateCache(const Machine* host) {
8295
} else {
8396
diff = 0;
8497
}
98+
cached_write_diff = diff;
8599
Meter_humanUnit(cached_write_diff_str, diff, sizeof(cached_write_diff_str));
86100

101+
cached_num_disks = data.numDisks;
87102
cached_utilisation_diff = 0.0;
88103
cached_utilisation_norm = 0.0;
89104
if (data.totalMsTimeSpend > cached_msTimeSpend_total) {
@@ -101,6 +116,111 @@ static void DiskIOUpdateCache(const Machine* host) {
101116
cached_msTimeSpend_total = data.totalMsTimeSpend;
102117
}
103118

119+
static void DiskIORateMeter_updateValues(Meter* this) {
120+
DiskIOUpdateCache(this->host);
121+
122+
this->values[0] = cached_read_diff * ONE_K;
123+
this->values[1] = cached_write_diff * ONE_K;
124+
125+
switch (status) {
126+
case RATESTATUS_NODATA:
127+
xSnprintf(this->txtBuffer, sizeof(this->txtBuffer), "no data");
128+
return;
129+
case RATESTATUS_INIT:
130+
xSnprintf(this->txtBuffer, sizeof(this->txtBuffer), "init");
131+
return;
132+
case RATESTATUS_STALE:
133+
xSnprintf(this->txtBuffer, sizeof(this->txtBuffer), "stale");
134+
return;
135+
case RATESTATUS_DATA:
136+
break;
137+
}
138+
139+
xSnprintf(this->txtBuffer, sizeof(this->txtBuffer), "r:%siB/s w:%siB/s", cached_read_diff_str, cached_write_diff_str);
140+
}
141+
142+
static void DiskIORateMeter_display(ATTR_UNUSED const Object* cast, RichString* out) {
143+
switch (status) {
144+
case RATESTATUS_NODATA:
145+
RichString_writeAscii(out, CRT_colors[METER_VALUE_ERROR], "no data");
146+
return;
147+
case RATESTATUS_INIT:
148+
RichString_writeAscii(out, CRT_colors[METER_VALUE], "initializing...");
149+
return;
150+
case RATESTATUS_STALE:
151+
RichString_writeAscii(out, CRT_colors[METER_VALUE_WARN], "stale data");
152+
return;
153+
case RATESTATUS_DATA:
154+
break;
155+
}
156+
157+
RichString_appendAscii(out, CRT_colors[METER_TEXT], "read: ");
158+
RichString_appendAscii(out, CRT_colors[METER_VALUE_IOREAD], cached_read_diff_str);
159+
RichString_appendAscii(out, CRT_colors[METER_VALUE_IOREAD], "iB/s");
160+
161+
RichString_appendAscii(out, CRT_colors[METER_TEXT], " write: ");
162+
RichString_appendAscii(out, CRT_colors[METER_VALUE_IOWRITE], cached_write_diff_str);
163+
RichString_appendAscii(out, CRT_colors[METER_VALUE_IOWRITE], "iB/s");
164+
}
165+
166+
static void DiskIOTimeMeter_updateValues(Meter* this) {
167+
DiskIOUpdateCache(this->host);
168+
169+
this->values[0] = cached_utilisation_norm;
170+
171+
switch (status) {
172+
case RATESTATUS_NODATA:
173+
xSnprintf(this->txtBuffer, sizeof(this->txtBuffer), "no data");
174+
return;
175+
case RATESTATUS_INIT:
176+
xSnprintf(this->txtBuffer, sizeof(this->txtBuffer), "init");
177+
return;
178+
case RATESTATUS_STALE:
179+
xSnprintf(this->txtBuffer, sizeof(this->txtBuffer), "stale");
180+
return;
181+
case RATESTATUS_DATA:
182+
break;
183+
}
184+
185+
char numDisksStr[12];
186+
numDisksStr[0] = '\0';
187+
if (cached_num_disks > 1 && cached_num_disks < 1000) {
188+
xSnprintf(numDisksStr, sizeof(numDisksStr), " (%udisks)", (unsigned int)cached_num_disks);
189+
}
190+
191+
xSnprintf(this->txtBuffer, sizeof(this->txtBuffer), "%.1f%%%s", cached_utilisation_diff, numDisksStr);
192+
}
193+
194+
static void DiskIOTimeMeter_display(ATTR_UNUSED const Object* cast, RichString* out) {
195+
switch (status) {
196+
case RATESTATUS_NODATA:
197+
RichString_writeAscii(out, CRT_colors[METER_VALUE_ERROR], "no data");
198+
return;
199+
case RATESTATUS_INIT:
200+
RichString_writeAscii(out, CRT_colors[METER_VALUE], "initializing...");
201+
return;
202+
case RATESTATUS_STALE:
203+
RichString_writeAscii(out, CRT_colors[METER_VALUE_WARN], "stale data");
204+
return;
205+
case RATESTATUS_DATA:
206+
break;
207+
}
208+
209+
char buffer[16];
210+
211+
int color = cached_utilisation_diff > 40.0 ? METER_VALUE_NOTICE : METER_VALUE;
212+
int len = xSnprintf(buffer, sizeof(buffer), "%.1f%%", cached_utilisation_diff);
213+
RichString_appendnAscii(out, CRT_colors[color], buffer, len);
214+
RichString_appendAscii(out, CRT_colors[METER_TEXT], " busy");
215+
216+
if (cached_num_disks > 1 && cached_num_disks < 1000) {
217+
RichString_appendAscii(out, CRT_colors[METER_TEXT], " (");
218+
len = xSnprintf(buffer, sizeof(buffer), "%u", (unsigned int)cached_num_disks);
219+
RichString_appendnAscii(out, CRT_colors[METER_VALUE], buffer, len);
220+
RichString_appendAscii(out, CRT_colors[METER_TEXT], " disks)");
221+
}
222+
}
223+
104224
static void DiskIOMeter_updateValues(Meter* this) {
105225
DiskIOUpdateCache(this->host);
106226

@@ -153,6 +273,44 @@ static void DiskIOMeter_display(ATTR_UNUSED const Object* cast, RichString* out)
153273
RichString_appendAscii(out, CRT_colors[METER_VALUE_IOWRITE], "iB/s");
154274
}
155275

276+
const MeterClass DiskIORateMeter_class = {
277+
.super = {
278+
.extends = Class(Meter),
279+
.delete = Meter_delete,
280+
.display = DiskIORateMeter_display
281+
},
282+
.updateValues = DiskIORateMeter_updateValues,
283+
.defaultMode = TEXT_METERMODE,
284+
.supportedModes = METERMODE_DEFAULT_SUPPORTED,
285+
.maxItems = 2,
286+
.isPercentChart = false,
287+
.total = 1.0,
288+
.attributes = DiskIORateMeter_attributes,
289+
.name = "DiskIORate",
290+
.uiName = "Disk IO Rate",
291+
.description = "Disk IO read & write bytes per second",
292+
.caption = "Dsk: "
293+
};
294+
295+
const MeterClass DiskIOTimeMeter_class = {
296+
.super = {
297+
.extends = Class(Meter),
298+
.delete = Meter_delete,
299+
.display = DiskIOTimeMeter_display
300+
},
301+
.updateValues = DiskIOTimeMeter_updateValues,
302+
.defaultMode = TEXT_METERMODE,
303+
.supportedModes = METERMODE_DEFAULT_SUPPORTED,
304+
.maxItems = 1,
305+
.isPercentChart = true,
306+
.total = 1.0,
307+
.attributes = DiskIOTimeMeter_attributes,
308+
.name = "DiskIOTime",
309+
.uiName = "Disk IO Time",
310+
.description = "Disk percent time busy",
311+
.caption = "Dsk: "
312+
};
313+
156314
const MeterClass DiskIOMeter_class = {
157315
.super = {
158316
.extends = Class(Meter),

DiskIOMeter.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ typedef struct DiskIOData_ {
1919
uint64_t numDisks;
2020
} DiskIOData;
2121

22+
extern const MeterClass DiskIORateMeter_class;
23+
24+
extern const MeterClass DiskIOTimeMeter_class;
25+
2226
extern const MeterClass DiskIOMeter_class;
2327

2428
#endif /* HEADER_DiskIOMeter */

darwin/Platform.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,8 @@ const MeterClass* const Platform_meterTypes[] = {
143143
&RightCPUs8Meter_class,
144144
&ZfsArcMeter_class,
145145
&ZfsCompressedArcMeter_class,
146+
&DiskIORateMeter_class,
147+
&DiskIOTimeMeter_class,
146148
&DiskIOMeter_class,
147149
&NetworkIOMeter_class,
148150
&FileDescriptorMeter_class,

dragonflybsd/Platform.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ const MeterClass* const Platform_meterTypes[] = {
120120
&RightCPUs4Meter_class,
121121
&LeftCPUs8Meter_class,
122122
&RightCPUs8Meter_class,
123+
&DiskIORateMeter_class,
124+
&DiskIOTimeMeter_class,
123125
&DiskIOMeter_class,
124126
&NetworkIOMeter_class,
125127
&FileDescriptorMeter_class,

freebsd/Platform.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ const MeterClass* const Platform_meterTypes[] = {
130130
&BlankMeter_class,
131131
&ZfsArcMeter_class,
132132
&ZfsCompressedArcMeter_class,
133+
&DiskIORateMeter_class,
134+
&DiskIOTimeMeter_class,
133135
&DiskIOMeter_class,
134136
&FileDescriptorMeter_class,
135137
&NetworkIOMeter_class,

linux/Platform.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,8 @@ const MeterClass* const Platform_meterTypes[] = {
247247
&ZfsArcMeter_class,
248248
&ZfsCompressedArcMeter_class,
249249
&ZramMeter_class,
250+
&DiskIORateMeter_class,
251+
&DiskIOTimeMeter_class,
250252
&DiskIOMeter_class,
251253
&NetworkIOMeter_class,
252254
&SELinuxMeter_class,

netbsd/Platform.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,8 @@ const MeterClass* const Platform_meterTypes[] = {
180180
&LeftCPUs8Meter_class,
181181
&RightCPUs8Meter_class,
182182
&BlankMeter_class,
183+
&DiskIORateMeter_class,
184+
&DiskIOTimeMeter_class,
183185
&DiskIOMeter_class,
184186
&NetworkIOMeter_class,
185187
&FileDescriptorMeter_class,

pcp/Platform.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ const MeterClass* const Platform_meterTypes[] = {
114114
&ZfsArcMeter_class,
115115
&ZfsCompressedArcMeter_class,
116116
&ZramMeter_class,
117+
&DiskIORateMeter_class,
118+
&DiskIOTimeMeter_class,
117119
&DiskIOMeter_class,
118120
&NetworkIOMeter_class,
119121
&SysArchMeter_class,

0 commit comments

Comments
 (0)