winlin

refine the cpu stat, use fgets and sscanf.

@@ -194,7 +194,6 @@ SrsProcSystemStat::SrsProcSystemStat() @@ -194,7 +194,6 @@ SrsProcSystemStat::SrsProcSystemStat()
194 sample_time = 0; 194 sample_time = 0;
195 percent = 0; 195 percent = 0;
196 total_delta = 0; 196 total_delta = 0;
197 - memset(label, 0, sizeof(label));  
198 user = 0; 197 user = 0;
199 nice = 0; 198 nice = 0;
200 sys = 0; 199 sys = 0;
@@ -229,22 +228,30 @@ bool get_proc_system_stat(SrsProcSystemStat& r) @@ -229,22 +228,30 @@ bool get_proc_system_stat(SrsProcSystemStat& r)
229 return false; 228 return false;
230 } 229 }
231 230
232 - for (;;) {  
233 - int ret = fscanf(f, "%4s %lu %lu %lu %lu %lu "  
234 - "%lu %lu %lu %lu\n",  
235 - r.label, &r.user, &r.nice, &r.sys, &r.idle, &r.iowait,  
236 - &r.irq, &r.softirq, &r.steal, &r.guest);  
237 r.ok = false; 231 r.ok = false;
238 232
239 - if (ret == EOF) {  
240 - break; 233 + static char buf[1024];
  234 + while (fgets(buf, sizeof(buf), f)) {
  235 + if (strncmp(buf, "cpu ", 4) != 0) {
  236 + continue;
241 } 237 }
242 238
243 - if (strcmp("cpu", r.label) == 0) { 239 + int ret = sscanf(buf, "cpu %llu %llu %llu %llu %llu "
  240 + "%llu %llu %llu %llu\n",
  241 + &r.user, &r.nice, &r.sys, &r.idle, &r.iowait,
  242 + &r.irq, &r.softirq, &r.steal, &r.guest);
  243 + srs_assert(ret == 9);
  244 +
  245 + // matched ok.
244 r.ok = true; 246 r.ok = true;
  247 +
  248 + // @see: http://tester-higkoo.googlecode.com/svn-history/r14/trunk/Tools/iostat/iostat.c
  249 + // add the interrupts to sys.
  250 + // TODO: FIXME: check out it.
  251 + r.sys += r.irq + r.softirq;
  252 +
245 break; 253 break;
246 } 254 }
247 - }  
248 255
249 fclose(f); 256 fclose(f);
250 257
@@ -358,6 +365,14 @@ SrsDiskStat::SrsDiskStat() @@ -358,6 +365,14 @@ SrsDiskStat::SrsDiskStat()
358 365
359 pgpgin = 0; 366 pgpgin = 0;
360 pgpgout = 0; 367 pgpgout = 0;
  368 +
  369 + rd_ios = rd_merges = 0;
  370 + rd_sectors = 0;
  371 + rd_ticks = 0;
  372 +
  373 + wr_ios = wr_merges = 0;
  374 + wr_sectors = 0;
  375 + wr_ticks = nb_current = ticks = aveq = 0;
361 } 376 }
362 377
363 static SrsDiskStat _srs_disk_stat; 378 static SrsDiskStat _srs_disk_stat;
@@ -403,6 +418,64 @@ bool srs_get_disk_vmstat_stat(SrsDiskStat& r) @@ -403,6 +418,64 @@ bool srs_get_disk_vmstat_stat(SrsDiskStat& r)
403 418
404 bool srs_get_disk_diskstats_stat(SrsDiskStat& r) 419 bool srs_get_disk_diskstats_stat(SrsDiskStat& r)
405 { 420 {
  421 + // %4d %4d %31s %u
  422 + //
  423 + FILE* f = fopen("/proc/diskstats", "r");
  424 + if (f == NULL) {
  425 + srs_warn("open vmstat failed, ignore");
  426 + return false;
  427 + }
  428 +
  429 + r.ok = false;
  430 + r.sample_time = srs_get_system_time_ms();
  431 +
  432 + static char buf[1024];
  433 +
  434 + while (fgets(buf, sizeof(buf), f)) {
  435 + unsigned int major = 0;
  436 + unsigned int minor = 0;
  437 + static char name[32];
  438 + unsigned int rd_ios = 0;
  439 + unsigned int rd_merges = 0;
  440 + unsigned long long rd_sectors = 0;
  441 + unsigned int rd_ticks = 0;
  442 + unsigned int wr_ios = 0;
  443 + unsigned int wr_merges = 0;
  444 + unsigned long long wr_sectors = 0;
  445 + unsigned int wr_ticks = 0;
  446 + unsigned int nb_current = 0;
  447 + unsigned int ticks = 0;
  448 + unsigned int aveq = 0;
  449 + memset(name, sizeof(name), 0);
  450 + int ret = sscanf(buf,
  451 + "%4d %4d %31s %u %u %llu %u %u %u %llu %u %u %u %u",
  452 + &major, &minor, name, &rd_ios, &rd_merges,
  453 + &rd_sectors, &rd_ticks, &wr_ios, &wr_merges,
  454 + &wr_sectors, &wr_ticks, &nb_current, &ticks, &aveq);
  455 +
  456 + if (ret == EOF) {
  457 + break;
  458 + }
  459 +
  460 + if (strcmp("sda", name) == 0) {
  461 + r.rd_ios += rd_ios;
  462 + r.rd_merges += rd_merges;
  463 + r.rd_sectors += rd_sectors;
  464 + r.rd_ticks += rd_ticks;
  465 + r.wr_ios += wr_ios;
  466 + r.wr_merges += wr_merges;
  467 + r.wr_sectors += wr_sectors;
  468 + r.wr_ticks += wr_ticks;
  469 + r.nb_current += nb_current;
  470 + r.ticks += ticks;
  471 + r.aveq += aveq;
  472 + }
  473 + }
  474 +
  475 + fclose(f);
  476 +
  477 + r.ok = true;
  478 +
406 return true; 479 return true;
407 } 480 }
408 481
@@ -273,9 +273,6 @@ public: @@ -273,9 +273,6 @@ public:
273 // previous cpu total = this->total() - total_delta 273 // previous cpu total = this->total() - total_delta
274 int64_t total_delta; 274 int64_t total_delta;
275 275
276 - // always be cpu  
277 - char label[32];  
278 -  
279 // data of /proc/stat 276 // data of /proc/stat
280 public: 277 public:
281 // The amount of time, measured in units of USER_HZ 278 // The amount of time, measured in units of USER_HZ
@@ -283,32 +280,32 @@ public: @@ -283,32 +280,32 @@ public:
283 // sysconf(_SC_CLK_TCK) to obtain the right value) 280 // sysconf(_SC_CLK_TCK) to obtain the right value)
284 // 281 //
285 // the system spent in user mode, 282 // the system spent in user mode,
286 - unsigned long user; 283 + unsigned long long user;
287 // user mode with low priority (nice), 284 // user mode with low priority (nice),
288 - unsigned long nice; 285 + unsigned long long nice;
289 // system mode, 286 // system mode,
290 - unsigned long sys; 287 + unsigned long long sys;
291 // and the idle task, respectively. 288 // and the idle task, respectively.
292 - unsigned long idle; 289 + unsigned long long idle;
293 290
294 // In Linux 2.6 this line includes three additional columns: 291 // In Linux 2.6 this line includes three additional columns:
295 // 292 //
296 // iowait - time waiting for I/O to complete (since 2.5.41); 293 // iowait - time waiting for I/O to complete (since 2.5.41);
297 - unsigned long iowait; 294 + unsigned long long iowait;
298 // irq - time servicing interrupts (since 2.6.0-test4); 295 // irq - time servicing interrupts (since 2.6.0-test4);
299 - unsigned long irq; 296 + unsigned long long irq;
300 // softirq - time servicing softirqs (since 2.6.0-test4). 297 // softirq - time servicing softirqs (since 2.6.0-test4).
301 - unsigned long softirq; 298 + unsigned long long softirq;
302 299
303 // Since Linux 2.6.11, there is an eighth column, 300 // Since Linux 2.6.11, there is an eighth column,
304 // steal - stolen time, which is the time spent in other oper- 301 // steal - stolen time, which is the time spent in other oper-
305 // ating systems when running in a virtualized environment 302 // ating systems when running in a virtualized environment
306 - unsigned long steal; 303 + unsigned long long steal;
307 304
308 // Since Linux 2.6.24, there is a ninth column, 305 // Since Linux 2.6.24, there is a ninth column,
309 // guest, which is the time spent running a virtual CPU for guest 306 // guest, which is the time spent running a virtual CPU for guest
310 // operating systems under the control of the Linux kernel. 307 // operating systems under the control of the Linux kernel.
311 - unsigned long guest; 308 + unsigned long long guest;
312 309
313 public: 310 public:
314 SrsProcSystemStat(); 311 SrsProcSystemStat();
@@ -350,46 +347,56 @@ public: @@ -350,46 +347,56 @@ public:
350 unsigned long pgpgout; 347 unsigned long pgpgout;
351 348
352 // @see: https://www.kernel.org/doc/Documentation/iostats.txt 349 // @see: https://www.kernel.org/doc/Documentation/iostats.txt
  350 + // @see: http://tester-higkoo.googlecode.com/svn-history/r14/trunk/Tools/iostat/iostat.c
353 // @see: cat /proc/diskstats 351 // @see: cat /proc/diskstats
354 // 352 //
355 // Number of issued reads. 353 // Number of issued reads.
356 // This is the total number of reads completed successfully. 354 // This is the total number of reads completed successfully.
357 - unsigned long long nb_read; 355 + // Read I/O operations
  356 + unsigned int rd_ios;
358 // Number of reads merged 357 // Number of reads merged
359 - unsigned long long nb_mread; 358 + // Reads merged
  359 + unsigned int rd_merges;
360 // Number of sectors read. 360 // Number of sectors read.
361 // This is the total number of sectors read successfully. 361 // This is the total number of sectors read successfully.
362 - unsigned long long nb_sread; 362 + // Sectors read
  363 + unsigned long long rd_sectors;
363 // Number of milliseconds spent reading. 364 // Number of milliseconds spent reading.
364 // This is the total number of milliseconds spent by all reads 365 // This is the total number of milliseconds spent by all reads
365 // (as measured from __make_request() to end_that_request_last()). 366 // (as measured from __make_request() to end_that_request_last()).
366 - unsigned long long ms_read; 367 + // Time in queue + service for read
  368 + unsigned int rd_ticks;
367 // 369 //
368 // Number of writes completed. 370 // Number of writes completed.
369 // This is the total number of writes completed successfully 371 // This is the total number of writes completed successfully
370 - unsigned long long nb_write; 372 + // Write I/O operations
  373 + unsigned int wr_ios;
371 // Number of writes merged Reads and writes which are adjacent 374 // Number of writes merged Reads and writes which are adjacent
372 // to each other may be merged for efficiency. Thus two 4K 375 // to each other may be merged for efficiency. Thus two 4K
373 // reads may become one 8K read before it is ultimately 376 // reads may become one 8K read before it is ultimately
374 // handed to the disk, and so it will be counted (and queued) 377 // handed to the disk, and so it will be counted (and queued)
375 // as only one I/O. This field lets you know how often this was done. 378 // as only one I/O. This field lets you know how often this was done.
376 - unsigned long long nb_mwrite; 379 + // Writes merged
  380 + unsigned int wr_merges;
377 // Number of sectors written. 381 // Number of sectors written.
378 // This is the total number of sectors written successfully. 382 // This is the total number of sectors written successfully.
379 - unsigned long long nb_swrite; 383 + // Sectors written
  384 + unsigned long long wr_sectors;
380 // Number of milliseconds spent writing . 385 // Number of milliseconds spent writing .
381 // This is the total number of milliseconds spent by all writes 386 // This is the total number of milliseconds spent by all writes
382 // (as measured from __make_request() to end_that_request_last()). 387 // (as measured from __make_request() to end_that_request_last()).
383 - unsigned long long ms_write; 388 + // Time in queue + service for write
  389 + unsigned int wr_ticks;
384 // 390 //
385 // Number of I/Os currently in progress. 391 // Number of I/Os currently in progress.
386 // The only field that should go to zero. 392 // The only field that should go to zero.
387 // Incremented as requests are given to appropriate request_queue_t 393 // Incremented as requests are given to appropriate request_queue_t
388 // and decremented as they finish. 394 // and decremented as they finish.
389 - unsigned long long nb_current; 395 + unsigned int nb_current;
390 // Number of milliseconds spent doing I/Os. 396 // Number of milliseconds spent doing I/Os.
391 // This field is increased so long as field 9 is nonzero. 397 // This field is increased so long as field 9 is nonzero.
392 - unsigned long long ms_total; 398 + // Time of requests in queue
  399 + unsigned int ticks;
393 // Number of milliseconds spent doing I/Os. 400 // Number of milliseconds spent doing I/Os.
394 // This field is incremented at each I/O start, I/O completion, 401 // This field is incremented at each I/O start, I/O completion,
395 // I/O merge, or read of these stats by the number of I/Os in 402 // I/O merge, or read of these stats by the number of I/Os in
@@ -397,8 +404,8 @@ public: @@ -397,8 +404,8 @@ public:
397 // doing I/O since the last update of this field. This can 404 // doing I/O since the last update of this field. This can
398 // provide an easy measure of both I/O completion time and 405 // provide an easy measure of both I/O completion time and
399 // the backlog that may be accumulating. 406 // the backlog that may be accumulating.
400 - // weighting total.  
401 - unsigned long long ms_wtotal; 407 + // Average queue length
  408 + unsigned int aveq;
402 409
403 public: 410 public:
404 SrsDiskStat(); 411 SrsDiskStat();