ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libstatgrab/src/statgrab/statgrab.c
(Generate patch)

Comparing projects/libstatgrab/src/statgrab/statgrab.c (file contents):
Revision 1.12 by ats, Mon Oct 20 22:18:21 2003 UTC vs.
Revision 1.29 by ats, Tue Aug 10 18:50:37 2004 UTC

# Line 1 | Line 1
1   /*
2 < * i-scream central monitoring system
2 > * i-scream libstatgrab
3   * http://www.i-scream.org
4 < * Copyright (C) 2000-2003 i-scream
4 > * Copyright (C) 2000-2004 i-scream
5   *
6   * This program is free software; you can redistribute it and/or
7   * modify it under the terms of the GNU General Public License
# Line 16 | Line 16
16   * You should have received a copy of the GNU General Public License
17   * along with this program; if not, write to the Free Software
18   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19 + *
20 + * $Id$
21   */
22  
23   #ifdef HAVE_CONFIG_H
# Line 35 | Line 37 | typedef enum {
37          FLOAT,
38          DOUBLE,
39          STRING,
40 <        INT
40 >        INT,
41 >        BOOL,
42 >        DUPLEX
43   } stat_type;
44  
45   typedef enum {
# Line 67 | Line 71 | repeat_mode_type repeat_mode = REPEAT_NONE;
71   int repeat_time = 1;
72   int use_cpu_percent = 0;
73   int use_diffs = 0;
74 + long float_scale_factor = 0;
75  
76   /* Exit with an error message. */
77   void die(const char *s) {
# Line 162 | Line 167 | void populate_const() {
167  
168   void populate_cpu() {
169          if (use_cpu_percent) {
170 <                cpu_percent_t *cpu_p = cpu_percent_usage();
170 >                sg_cpu_percents *cpu_p = sg_get_cpu_percents();
171  
172                  if (cpu_p != NULL) {
173                          add_stat(FLOAT, &cpu_p->user,
174 <                                 "cpu", "user", NULL);
174 >                                 "cpu", "user", NULL);
175                          add_stat(FLOAT, &cpu_p->kernel,
176 <                                 "cpu", "kernel", NULL);
176 >                                 "cpu", "kernel", NULL);
177                          add_stat(FLOAT, &cpu_p->idle,
178 <                                 "cpu", "idle", NULL);
178 >                                 "cpu", "idle", NULL);
179                          add_stat(FLOAT, &cpu_p->iowait,
180 <                                 "cpu", "iowait", NULL);
180 >                                 "cpu", "iowait", NULL);
181                          add_stat(FLOAT, &cpu_p->swap,
182 <                                 "cpu", "swap", NULL);
182 >                                 "cpu", "swap", NULL);
183                          add_stat(FLOAT, &cpu_p->nice,
184 <                                 "cpu", "nice", NULL);
184 >                                 "cpu", "nice", NULL);
185                          add_stat(TIME_T, &cpu_p->time_taken,
186 <                                 "cpu", "time_taken", NULL);
186 >                                 "cpu", "time_taken", NULL);
187                  }
188          } else {
189 <                cpu_states_t *cpu_s;
189 >                sg_cpu_stats *cpu_s;
190  
191 <                cpu_s = use_diffs ? get_cpu_diff() : get_cpu_totals();
191 >                cpu_s = use_diffs ? sg_get_cpu_stats_diff()
192 >                                  : sg_get_cpu_stats();
193                  if (cpu_s != NULL) {
194                          add_stat(LONG_LONG, &cpu_s->user,
195 <                                 "cpu", "user", NULL);
195 >                                 "cpu", "user", NULL);
196                          add_stat(LONG_LONG, &cpu_s->kernel,
197 <                                 "cpu", "kernel", NULL);
197 >                                 "cpu", "kernel", NULL);
198                          add_stat(LONG_LONG, &cpu_s->idle,
199 <                                 "cpu", "idle", NULL);
199 >                                 "cpu", "idle", NULL);
200                          add_stat(LONG_LONG, &cpu_s->iowait,
201 <                                 "cpu", "iowait", NULL);
201 >                                 "cpu", "iowait", NULL);
202                          add_stat(LONG_LONG, &cpu_s->swap,
203 <                                 "cpu", "swap", NULL);
203 >                                 "cpu", "swap", NULL);
204                          add_stat(LONG_LONG, &cpu_s->nice,
205 <                                 "cpu", "nice", NULL);
205 >                                 "cpu", "nice", NULL);
206                          add_stat(LONG_LONG, &cpu_s->total,
207 <                                 "cpu", "total", NULL);
207 >                                 "cpu", "total", NULL);
208                          add_stat(TIME_T, &cpu_s->systime,
209 <                                 "cpu", "systime", NULL);
209 >                                 "cpu", "systime", NULL);
210                  }
211          }
212   }
213  
214   void populate_mem() {
215 <        mem_stat_t *mem = get_memory_stats();
215 >        sg_mem_stats *mem = sg_get_mem_stats();
216  
217          if (mem != NULL) {
218                  add_stat(LONG_LONG, &mem->total, "mem", "total", NULL);
# Line 217 | Line 223 | void populate_mem() {
223   }
224  
225   void populate_load() {
226 <        load_stat_t *load = get_load_stats();
226 >        sg_load_stats *load = sg_get_load_stats();
227  
228          if (load != NULL) {
229                  add_stat(DOUBLE, &load->min1, "load", "min1", NULL);
# Line 227 | Line 233 | void populate_load() {
233   }
234  
235   void populate_user() {
236 <        user_stat_t *user = get_user_stats();
236 >        sg_user_stats *user = sg_get_user_stats();
237  
238          if (user != NULL) {
239                  add_stat(INT, &user->num_entries, "user", "num", NULL);
# Line 236 | Line 242 | void populate_user() {
242   }
243  
244   void populate_swap() {
245 <        swap_stat_t *swap = get_swap_stats();
245 >        sg_swap_stats *swap = sg_get_swap_stats();
246  
247          if (swap != NULL) {
248                  add_stat(LONG_LONG, &swap->total, "swap", "total", NULL);
# Line 246 | Line 252 | void populate_swap() {
252   }
253  
254   void populate_general() {
255 <        general_stat_t *gen = get_general_stats();
255 >        /* FIXME this should be renamed to host. */
256 >        sg_host_info *host = sg_get_host_info();
257  
258 <        if (gen != NULL) {
259 <                add_stat(STRING, &gen->os_name,
260 <                         "general", "os_name", NULL);
261 <                add_stat(STRING, &gen->os_release,
262 <                         "general", "os_release", NULL);
263 <                add_stat(STRING, &gen->os_version,
264 <                         "general", "os_version", NULL);
265 <                add_stat(STRING, &gen->platform, "general", "platform", NULL);
266 <                add_stat(STRING, &gen->hostname, "general", "hostname", NULL);
267 <                add_stat(TIME_T, &gen->uptime, "general", "uptime", NULL);
258 >        if (host != NULL) {
259 >                add_stat(STRING, &host->os_name,
260 >                         "general", "os_name", NULL);
261 >                add_stat(STRING, &host->os_release,
262 >                         "general", "os_release", NULL);
263 >                add_stat(STRING, &host->os_version,
264 >                         "general", "os_version", NULL);
265 >                add_stat(STRING, &host->platform, "general", "platform", NULL);
266 >                add_stat(STRING, &host->hostname, "general", "hostname", NULL);
267 >                add_stat(TIME_T, &host->uptime, "general", "uptime", NULL);
268          }
269   }
270  
271   void populate_fs() {
272          int n, i;
273 <        disk_stat_t *disk = get_disk_stats(&n);
273 >        sg_fs_stats *disk = sg_get_fs_stats(&n);
274  
275          if (disk != NULL) {
276                  for (i = 0; i < n; i++) {
# Line 279 | Line 286 | void populate_fs() {
286                                  die("out of memory");
287  
288                          name = buf;
289 +                        if (strlen(name) == 2 && name[1] == ':')
290 +                                name[1] = '\0';
291                          if (strncmp(name, "/dev/", 5) == 0)
292                                  name += 5;
293                          while ((p = strchr(name, '/')) != NULL)
294                                  *p = '_';
295  
296                          add_stat(STRING, &disk[i].device_name,
297 <                                 "fs", name, "device_name", NULL);
297 >                                 "fs", name, "device_name", NULL);
298                          add_stat(STRING, &disk[i].fs_type,
299 <                                 "fs", name, "fs_type", NULL);
299 >                                 "fs", name, "fs_type", NULL);
300                          add_stat(STRING, &disk[i].mnt_point,
301 <                                 "fs", name, "mnt_point", NULL);
301 >                                 "fs", name, "mnt_point", NULL);
302                          add_stat(LONG_LONG, &disk[i].size,
303 <                                 "fs", name, "size", NULL);
303 >                                 "fs", name, "size", NULL);
304                          add_stat(LONG_LONG, &disk[i].used,
305 <                                 "fs", name, "used", NULL);
305 >                                 "fs", name, "used", NULL);
306                          add_stat(LONG_LONG, &disk[i].avail,
307 <                                 "fs", name, "avail", NULL);
307 >                                 "fs", name, "avail", NULL);
308                          add_stat(LONG_LONG, &disk[i].total_inodes,
309 <                                 "fs", name, "total_inodes", NULL);
309 >                                 "fs", name, "total_inodes", NULL);
310                          add_stat(LONG_LONG, &disk[i].used_inodes,
311 <                                 "fs", name, "used_inodes", NULL);
311 >                                 "fs", name, "used_inodes", NULL);
312                          add_stat(LONG_LONG, &disk[i].free_inodes,
313 <                                 "fs", name, "free_inodes", NULL);
313 >                                 "fs", name, "free_inodes", NULL);
314  
315                          free(buf);
316                  }
# Line 310 | Line 319 | void populate_fs() {
319  
320   void populate_disk() {
321          int n, i;
322 <        diskio_stat_t *diskio;
322 >        sg_disk_io_stats *diskio;
323  
324 <        diskio = use_diffs ? get_diskio_stats_diff(&n) : get_diskio_stats(&n);
324 >        diskio = use_diffs ? sg_get_disk_io_stats_diff(&n)
325 >                           : sg_get_disk_io_stats(&n);
326          if (diskio != NULL) {
327                  for (i = 0; i < n; i++) {
328                          const char *name = diskio[i].disk_name;
329          
330                          add_stat(STRING, &diskio[i].disk_name,
331 <                                 "disk", name, "disk_name", NULL);
331 >                                 "disk", name, "disk_name", NULL);
332                          add_stat(LONG_LONG, &diskio[i].read_bytes,
333 <                                 "disk", name, "read_bytes", NULL);
333 >                                 "disk", name, "read_bytes", NULL);
334                          add_stat(LONG_LONG, &diskio[i].write_bytes,
335 <                                 "disk", name, "write_bytes", NULL);
335 >                                 "disk", name, "write_bytes", NULL);
336                          add_stat(TIME_T, &diskio[i].systime,
337 <                                 "disk", name, "systime", NULL);
337 >                                 "disk", name, "systime", NULL);
338                  }
339          }
340   }
341  
342   void populate_proc() {
343 <        process_stat_t *proc = get_process_stats();
343 >        /* FIXME expose individual process info too */
344 >        sg_process_count *proc = sg_get_process_count();
345  
346          if (proc != NULL) {
347                  add_stat(INT, &proc->total, "proc", "total", NULL);
# Line 342 | Line 353 | void populate_proc() {
353   }
354  
355   void populate_net() {
356 <        int n, i;
357 <        network_stat_t *net;
356 >        int num_io, num_iface, i;
357 >        sg_network_io_stats *io;
358 >        sg_network_iface_stats *iface;
359  
360 <        net = use_diffs ? get_network_stats_diff(&n) : get_network_stats(&n);
361 <        if (net != NULL) {
362 <                for (i = 0; i < n; i++) {
363 <                        const char *name = net[i].interface_name;
360 >        io = use_diffs ? sg_get_network_io_stats_diff(&num_io)
361 >                       : sg_get_network_io_stats(&num_io);
362 >        if (io != NULL) {
363 >                for (i = 0; i < num_io; i++) {
364 >                        const char *name = io[i].interface_name;
365          
366 <                        add_stat(STRING, &net[i].interface_name,
367 <                                 "net", name, "interface_name", NULL);
368 <                        add_stat(LONG_LONG, &net[i].tx,
369 <                                 "net", name, "tx", NULL);
370 <                        add_stat(LONG_LONG, &net[i].rx,
371 <                                 "net", name, "rx", NULL);
372 <                        add_stat(TIME_T, &net[i].systime,
373 <                                 "net", name, "systime", NULL);
366 >                        add_stat(STRING, &io[i].interface_name,
367 >                                 "net", name, "interface_name", NULL);
368 >                        add_stat(LONG_LONG, &io[i].tx,
369 >                                 "net", name, "tx", NULL);
370 >                        add_stat(LONG_LONG, &io[i].rx,
371 >                                 "net", name, "rx", NULL);
372 >                        add_stat(LONG_LONG, &io[i].ipackets,
373 >                                 "net", name, "ipackets", NULL);
374 >                        add_stat(LONG_LONG, &io[i].opackets,
375 >                                 "net", name, "opackets", NULL);
376 >                        add_stat(LONG_LONG, &io[i].ierrors,
377 >                                 "net", name, "ierrors", NULL);
378 >                        add_stat(LONG_LONG, &io[i].oerrors,
379 >                                 "net", name, "oerrors", NULL);
380 >                        add_stat(LONG_LONG, &io[i].collisions,
381 >                                 "net", name, "collisions", NULL);
382 >                        add_stat(TIME_T, &io[i].systime,
383 >                                 "net", name, "systime", NULL);
384                  }
385          }
386 +
387 +        iface = sg_get_network_iface_stats(&num_iface);
388 +        if (iface != NULL) {
389 +                for (i = 0; i < num_iface; i++) {
390 +                        const char *name = iface[i].interface_name;
391 +                        int had_io = 0, j;
392 +
393 +                        /* If there wasn't a corresponding io stat,
394 +                           add interface_name from here. */
395 +                        if (io != NULL) {
396 +                                for (j = 0; j < num_io; j++) {
397 +                                        if (strcmp(io[j].interface_name,
398 +                                                   name) == 0) {
399 +                                                had_io = 1;
400 +                                                break;
401 +                                        }
402 +                                }
403 +                        }
404 +                        if (!had_io) {
405 +                                add_stat(STRING, &iface[i].interface_name,
406 +                                        "net", name, "interface_name", NULL);
407 +                        }
408 +
409 +                        add_stat(INT, &iface[i].speed,
410 +                                 "net", name, "speed", NULL);
411 +                        add_stat(BOOL, &iface[i].up,
412 +                                 "net", name, "up", NULL);
413 +                        add_stat(DUPLEX, &iface[i].dup,
414 +                                 "net", name, "duplex", NULL);
415 +                }
416 +        }
417   }
418  
419   void populate_page() {
420 <        page_stat_t *page;
420 >        sg_page_stats *page;
421  
422 <        page = use_diffs ? get_page_stats_diff() : get_page_stats();
422 >        page = use_diffs ? sg_get_page_stats_diff() : sg_get_page_stats();
423          if (page != NULL) {
424                  add_stat(LONG_LONG, &page->pages_pagein, "page", "in", NULL);
425                  add_stat(LONG_LONG, &page->pages_pageout, "page", "out", NULL);
# Line 408 | Line 462 | void select_interesting(int argc, char **argv) {
462                  for (i = 0; i < argc; i++) {
463                          for (t = &toplevels[0]; t->name != NULL; t++) {
464                                  if (strncmp(argv[i], t->name,
465 <                                            strlen(t->name)) == 0) {
465 >                                            strlen(t->name)) == 0) {
466                                          t->interesting = 1;
467                                          break;
468                                  }
# Line 428 | Line 482 | void get_stats() {
482                          t->populate();
483          }
484  
485 <        qsort(stats, num_stats, sizeof *stats, stats_compare);
485 >        if (stats != NULL)
486 >                qsort(stats, num_stats, sizeof *stats, stats_compare);
487   }
488  
489   /* Print the value of a stat. */
490   void print_stat_value(const stat *s) {
491          void *v = s->stat;
492 +        double fv;
493 +        long l;
494  
495          switch (s->type) {
496          case LONG_LONG:
# Line 441 | Line 498 | void print_stat_value(const stat *s) {
498                  break;
499          case TIME_T:
500                  /* FIXME option for formatted time? */
501 <                printf("%ld", *(time_t *)v);
501 >                l = *(time_t *)v;
502 >                printf("%ld", l);
503                  break;
504          case FLOAT:
447                printf("%f", *(float *)v);
448                break;
505          case DOUBLE:
506 <                printf("%f", *(double *)v);
506 >                if (s->type == FLOAT) {
507 >                        fv = *(float *)v;
508 >                } else {
509 >                        fv = *(double *)v;
510 >                }
511 >                if (float_scale_factor != 0) {
512 >                        printf("%ld", (long)(float_scale_factor * fv));
513 >                } else {
514 >                        printf("%f", fv);
515 >                }
516                  break;
517          case STRING:
518                  /* FIXME escaping? */
# Line 456 | Line 521 | void print_stat_value(const stat *s) {
521          case INT:
522                  printf("%d", *(int *)v);
523                  break;
524 +        case BOOL:
525 +                printf("%s", *(int *)v ? "true" : "false");
526 +                break;
527 +        case DUPLEX:
528 +                switch (*(sg_iface_duplex *) v) {
529 +                case SG_IFACE_DUPLEX_FULL:
530 +                        printf("full");
531 +                        break;
532 +                case SG_IFACE_DUPLEX_HALF:
533 +                        printf("half");
534 +                        break;
535 +                default:
536 +                        printf("unknown");
537 +                        break;
538 +                }
539 +                break;
540          }
541   }
542  
# Line 498 | Line 579 | void print_stats(int argc, char **argv) {
579                          else
580                                  compare = stats_compare;
581  
582 <                        s = (const stat *)bsearch(&key, stats, num_stats,
583 <                                                  sizeof *stats, compare);
582 >                        if (stats == NULL) {
583 >                                s = NULL;
584 >                        } else {
585 >                                s = (const stat *)bsearch(&key, stats,
586 >                                                          num_stats,
587 >                                                          sizeof *stats,
588 >                                                          compare);
589 >                        }
590 >
591                          if (s == NULL) {
592                                  printf("Unknown stat %s\n", name);
593                                  continue;
# Line 531 | Line 619 | void usage() {
619                 "If no STATs are given, all will be displayed. Specify 'STAT.' to display all\n"
620                 "statistics starting with that prefix.\n"
621                 "\n");
622 <        printf("  -l         Linux sysctl-style output (default)\n"
623 <               "  -b         BSD sysctl-style output\n"
624 <               "  -m         MRTG-compatible output\n"
625 <               "  -u         Plain output (only show values)\n"
626 <               "  -n         Display cumulative stats once (default)\n"
627 <               "  -s         Display stat differences repeatedly\n"
628 <               "  -o         Display stat differences once\n"
622 >        printf("  -l     Linux sysctl-style output (default)\n"
623 >               "  -b     BSD sysctl-style output\n"
624 >               "  -m     MRTG-compatible output\n"
625 >               "  -u     Plain output (only show values)\n"
626 >               "  -n     Display cumulative stats once (default)\n"
627 >               "  -s     Display stat differences repeatedly\n"
628 >               "  -o     Display stat differences once\n"
629                 "  -t DELAY   When repeating, wait DELAY seconds between updates (default 1)\n"
630 <               "  -p         Display CPU usage differences as percentages rather than\n"
631 <               "             absolute values\n"
630 >               "  -p     Display CPU usage differences as percentages rather than\n"
631 >               "             absolute values\n"
632 >               "  -f SCALE   Display floating-point values as integers scaled by FACTOR\n"
633                 "\n");
634          printf("Version %s - report bugs to <%s>.\n",
635                 PACKAGE_VERSION, PACKAGE_BUGREPORT);
# Line 550 | Line 639 | void usage() {
639   int main(int argc, char **argv) {
640          opterr = 0;
641          while (1) {
642 <                int c = getopt(argc, argv, "lbmunsot:p");
642 >                int c = getopt(argc, argv, "lbmunsot:pf:");
643                  if (c == -1)
644                          break;
645                  switch (c) {
# Line 581 | Line 670 | int main(int argc, char **argv) {
670                  case 'p':
671                          use_cpu_percent = 1;
672                          break;
673 +                case 'f':
674 +                        float_scale_factor = atol(optarg);
675 +                        break;
676                  default:
677                          usage();
678                  }
# Line 603 | Line 695 | int main(int argc, char **argv) {
695  
696          select_interesting(argc - optind, &argv[optind]);
697  
698 <        /* We don't care if statgrab_init fails, because we can just display
698 >        /* We don't care if sg_init fails, because we can just display
699             the statistics that can be read as non-root. */
700 <        statgrab_init();
701 < #ifdef ALLBSD
702 <        if (setegid(getgid()) != 0)
611 <                die("Failed to lose effective group");
612 < #endif
700 >        sg_init();
701 >        if (sg_drop_privileges() != 0)
702 >                die("Failed to drop setuid/setgid privileges");
703  
704          switch (repeat_mode) {
705          case REPEAT_NONE:

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines