--- projects/libstatgrab/src/statgrab/statgrab.c 2004/04/07 15:50:26 1.26 +++ projects/libstatgrab/src/statgrab/statgrab.c 2005/07/13 13:01:24 1.35 @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - * $Id: statgrab.c,v 1.26 2004/04/07 15:50:26 tdb Exp $ + * $Id: statgrab.c,v 1.35 2005/07/13 13:01:24 tdb Exp $ */ #ifdef HAVE_CONFIG_H @@ -33,6 +33,7 @@ typedef enum { LONG_LONG = 0, + BYTES, TIME_T, FLOAT, DOUBLE, @@ -71,6 +72,8 @@ repeat_mode_type repeat_mode = REPEAT_NONE; int repeat_time = 1; int use_cpu_percent = 0; int use_diffs = 0; +long float_scale_factor = 0; +long long bytes_scale_factor = 0; /* Exit with an error message. */ void die(const char *s) { @@ -214,10 +217,10 @@ void populate_mem() { sg_mem_stats *mem = sg_get_mem_stats(); if (mem != NULL) { - add_stat(LONG_LONG, &mem->total, "mem", "total", NULL); - add_stat(LONG_LONG, &mem->free, "mem", "free", NULL); - add_stat(LONG_LONG, &mem->used, "mem", "used", NULL); - add_stat(LONG_LONG, &mem->cache, "mem", "cache", NULL); + add_stat(BYTES, &mem->total, "mem", "total", NULL); + add_stat(BYTES, &mem->free, "mem", "free", NULL); + add_stat(BYTES, &mem->used, "mem", "used", NULL); + add_stat(BYTES, &mem->cache, "mem", "cache", NULL); } } @@ -244,9 +247,9 @@ void populate_swap() { sg_swap_stats *swap = sg_get_swap_stats(); if (swap != NULL) { - add_stat(LONG_LONG, &swap->total, "swap", "total", NULL); - add_stat(LONG_LONG, &swap->used, "swap", "used", NULL); - add_stat(LONG_LONG, &swap->free, "swap", "free", NULL); + add_stat(BYTES, &swap->total, "swap", "total", NULL); + add_stat(BYTES, &swap->used, "swap", "used", NULL); + add_stat(BYTES, &swap->free, "swap", "free", NULL); } } @@ -298,11 +301,11 @@ void populate_fs() { "fs", name, "fs_type", NULL); add_stat(STRING, &disk[i].mnt_point, "fs", name, "mnt_point", NULL); - add_stat(LONG_LONG, &disk[i].size, + add_stat(BYTES, &disk[i].size, "fs", name, "size", NULL); - add_stat(LONG_LONG, &disk[i].used, + add_stat(BYTES, &disk[i].used, "fs", name, "used", NULL); - add_stat(LONG_LONG, &disk[i].avail, + add_stat(BYTES, &disk[i].avail, "fs", name, "avail", NULL); add_stat(LONG_LONG, &disk[i].total_inodes, "fs", name, "total_inodes", NULL); @@ -310,6 +313,20 @@ void populate_fs() { "fs", name, "used_inodes", NULL); add_stat(LONG_LONG, &disk[i].free_inodes, "fs", name, "free_inodes", NULL); + add_stat(LONG_LONG, &disk[i].avail_inodes, + "fs", name, "avail_inodes", NULL); + add_stat(LONG_LONG, &disk[i].io_size, + "fs", name, "io_size", NULL); + add_stat(LONG_LONG, &disk[i].block_size, + "fs", name, "block_size", NULL); + add_stat(LONG_LONG, &disk[i].total_blocks, + "fs", name, "total_blocks", NULL); + add_stat(LONG_LONG, &disk[i].free_blocks, + "fs", name, "free_blocks", NULL); + add_stat(LONG_LONG, &disk[i].avail_blocks, + "fs", name, "avail_blocks", NULL); + add_stat(LONG_LONG, &disk[i].used_blocks, + "fs", name, "used_blocks", NULL); free(buf); } @@ -328,9 +345,9 @@ void populate_disk() { add_stat(STRING, &diskio[i].disk_name, "disk", name, "disk_name", NULL); - add_stat(LONG_LONG, &diskio[i].read_bytes, + add_stat(BYTES, &diskio[i].read_bytes, "disk", name, "read_bytes", NULL); - add_stat(LONG_LONG, &diskio[i].write_bytes, + add_stat(BYTES, &diskio[i].write_bytes, "disk", name, "write_bytes", NULL); add_stat(TIME_T, &diskio[i].systime, "disk", name, "systime", NULL); @@ -352,21 +369,21 @@ void populate_proc() { } void populate_net() { - int n, i; + int num_io, num_iface, i; sg_network_io_stats *io; sg_network_iface_stats *iface; - io = use_diffs ? sg_get_network_io_stats_diff(&n) - : sg_get_network_io_stats(&n); + io = use_diffs ? sg_get_network_io_stats_diff(&num_io) + : sg_get_network_io_stats(&num_io); if (io != NULL) { - for (i = 0; i < n; i++) { + for (i = 0; i < num_io; i++) { const char *name = io[i].interface_name; add_stat(STRING, &io[i].interface_name, "net", name, "interface_name", NULL); - add_stat(LONG_LONG, &io[i].tx, + add_stat(BYTES, &io[i].tx, "net", name, "tx", NULL); - add_stat(LONG_LONG, &io[i].rx, + add_stat(BYTES, &io[i].rx, "net", name, "rx", NULL); add_stat(LONG_LONG, &io[i].ipackets, "net", name, "ipackets", NULL); @@ -383,16 +400,33 @@ void populate_net() { } } - iface = sg_get_network_iface_stats(&n); + iface = sg_get_network_iface_stats(&num_iface); if (iface != NULL) { - for (i = 0; i < n; i++) { + for (i = 0; i < num_iface; i++) { const char *name = iface[i].interface_name; + int had_io = 0, j; + /* If there wasn't a corresponding io stat, + add interface_name from here. */ + if (io != NULL) { + for (j = 0; j < num_io; j++) { + if (strcmp(io[j].interface_name, + name) == 0) { + had_io = 1; + break; + } + } + } + if (!had_io) { + add_stat(STRING, &iface[i].interface_name, + "net", name, "interface_name", NULL); + } + add_stat(INT, &iface[i].speed, "net", name, "speed", NULL); add_stat(BOOL, &iface[i].up, "net", name, "up", NULL); - add_stat(DUPLEX, &iface[i].dup, + add_stat(DUPLEX, &iface[i].duplex, "net", name, "duplex", NULL); } } @@ -471,22 +505,38 @@ void get_stats() { /* Print the value of a stat. */ void print_stat_value(const stat *s) { void *v = s->stat; - long l; + double fv; + long lv; + long long llv; switch (s->type) { case LONG_LONG: printf("%lld", *(long long *)v); break; + case BYTES: + llv = *(long long *)v; + if (bytes_scale_factor != 0) { + llv /= bytes_scale_factor; + } + printf("%lld", llv); + break; case TIME_T: /* FIXME option for formatted time? */ - l = *(time_t *)v; - printf("%ld", l); + lv = *(time_t *)v; + printf("%ld", lv); break; case FLOAT: - printf("%f", *(float *)v); - break; case DOUBLE: - printf("%f", *(double *)v); + if (s->type == FLOAT) { + fv = *(float *)v; + } else { + fv = *(double *)v; + } + if (float_scale_factor != 0) { + printf("%ld", (long)(float_scale_factor * fv)); + } else { + printf("%f", fv); + } break; case STRING: /* FIXME escaping? */ @@ -593,16 +643,20 @@ void usage() { "If no STATs are given, all will be displayed. Specify 'STAT.' to display all\n" "statistics starting with that prefix.\n" "\n"); - printf(" -l Linux sysctl-style output (default)\n" - " -b BSD sysctl-style output\n" - " -m MRTG-compatible output\n" - " -u Plain output (only show values)\n" - " -n Display cumulative stats once (default)\n" - " -s Display stat differences repeatedly\n" - " -o Display stat differences once\n" + printf(" -l Linux sysctl-style output (default)\n" + " -b BSD sysctl-style output\n" + " -m MRTG-compatible output\n" + " -u Plain output (only show values)\n" + " -n Display cumulative stats once (default)\n" + " -s Display stat differences repeatedly\n" + " -o Display stat differences once\n" " -t DELAY When repeating, wait DELAY seconds between updates (default 1)\n" - " -p Display CPU usage differences as percentages rather than\n" - " absolute values\n" + " -p Display CPU usage differences as percentages rather than\n" + " absolute values\n" + " -f FACTOR Display floating-point values as integers scaled by FACTOR\n" + " -K Display byte counts in kibibytes\n" + " -M Display byte counts in mebibytes\n" + " -G Display byte counts in gibibytes\n" "\n"); printf("Version %s - report bugs to <%s>.\n", PACKAGE_VERSION, PACKAGE_BUGREPORT); @@ -612,7 +666,7 @@ void usage() { int main(int argc, char **argv) { opterr = 0; while (1) { - int c = getopt(argc, argv, "lbmunsot:p"); + int c = getopt(argc, argv, "lbmunsot:pf:KMG"); if (c == -1) break; switch (c) { @@ -643,6 +697,18 @@ int main(int argc, char **argv) { case 'p': use_cpu_percent = 1; break; + case 'f': + float_scale_factor = atol(optarg); + break; + case 'K': + bytes_scale_factor = 1024; + break; + case 'M': + bytes_scale_factor = 1024 * 1024; + break; + case 'G': + bytes_scale_factor = 1024 * 1024 * 1024; + break; default: usage(); } @@ -665,7 +731,7 @@ int main(int argc, char **argv) { select_interesting(argc - optind, &argv[optind]); - /* We don't care if statgrab_init fails, because we can just display + /* We don't care if sg_init fails, because we can just display the statistics that can be read as non-root. */ sg_init(); if (sg_drop_privileges() != 0)