ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libstatgrab/src/saidar/saidar.c
Revision: 1.17
Committed: Fri Nov 7 18:38:48 2003 UTC (20 years, 11 months ago) by ats
Content type: text/plain
Branch: MAIN
Changes since 1.16: +12 -6 lines
Log Message:
Do the "don't update more than once a second" thing slightly
differently; this avoids having it be unresponsive for 20 seconds if
you type 20 spaces.

File Contents

# User Rev Content
1 tdb 1.2 /*
2     * i-scream central monitoring system
3     * http://www.i-scream.org
4     * Copyright (C) 2000-2002 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
8     * as published by the Free Software Foundation; either version 2
9     * of the License, or (at your option) any later version.
10     *
11     * This program is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15     *
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    
21     #ifdef HAVE_CONFIG_H
22     #include "config.h"
23     #endif
24    
25 pajs 1.1 #include <stdio.h>
26     #include <string.h>
27     #include <sys/ioctl.h>
28     #include <unistd.h>
29     #include <stdlib.h>
30     #include <sys/termios.h>
31     #include <signal.h>
32     #include <errno.h>
33     #include <statgrab.h>
34     #include <sys/times.h>
35     #include <limits.h>
36     #include <time.h>
37 tdb 1.2
38     #ifdef HAVE_NCURSES_H
39     #include <ncurses.h>
40     #else
41 pajs 1.1 #include <curses.h>
42 tdb 1.2 #endif
43 pajs 1.1
44     typedef struct{
45     cpu_percent_t *cpu_percents;
46     mem_stat_t *mem_stats;
47     swap_stat_t *swap_stats;
48     load_stat_t *load_stats;
49     process_stat_t *process_stats;
50     page_stat_t *page_stats;
51    
52     network_stat_t *network_stats;
53     int network_entries;
54    
55     diskio_stat_t *diskio_stats;
56     int diskio_entries;
57    
58     disk_stat_t *disk_stats;
59     int disk_entries;
60    
61     general_stat_t *general_stats;
62     user_stat_t *user_stats;
63     }stats_t;
64    
65     stats_t stats;
66    
67     char *size_conv(long long number){
68     char type[] = {'B', 'K', 'M', 'G', 'T'};
69     int x=0;
70     static char string[10];
71    
72     for(;x<5;x++){
73     if( (number/1024) < (100)) {
74     break;
75     }
76     number = (number/1024);
77     }
78    
79     snprintf(string, 10, "%lld%c", number, type[x]);
80     return string;
81    
82     }
83    
84     char *hr_uptime(time_t time){
85     int day = 0, hour = 0, min = 0;
86     static char uptime_str[25];
87     int sec = (int) time;
88    
89     day = sec / (24*60*60);
90     sec = sec % (24*60*60);
91     hour = sec / (60*60);
92     sec = sec % (60*60);
93     min = sec / 60;
94     sec = sec % 60;
95    
96     if(day){
97     snprintf(uptime_str, 25, "%dd %02d:%02d:%02d", day, hour, min, sec);
98     }else{
99     snprintf(uptime_str, 25, "%02d:%02d:%02d", hour, min, sec);
100     }
101     return uptime_str;
102     }
103    
104     void display_headings(){
105 ats 1.11 int line;
106    
107 pajs 1.1 move(0,0);
108     printw("Hostname :");
109     move(0,27);
110     printw("Uptime : ");
111     move(0,54);
112     printw("Date : ");
113    
114     /* Load */
115     move(2,0);
116     printw("Load 1 :");
117     move(3,0);
118     printw("Load 5 :");
119     move(4,0);
120     printw("Load 15 :");
121    
122     /* CPU */
123     move(2,21);
124     printw("CPU Idle :");
125     move(3,21);
126     printw("CPU System:");
127     move(4,21);
128     printw("CPU User :");
129    
130     /* Process */
131     move(2, 42);
132     printw("Running :");
133     move(3, 42);
134     printw("Sleeping :");
135     move(4, 42);
136     printw("Stopped :");
137     move(2, 62);
138     printw("Zombie :");
139     move(3, 62);
140     printw("Total :");
141     move(4, 62);
142     printw("No. Users :");
143    
144     /* Mem */
145     move(6, 0);
146     printw("Mem Total :");
147     move(7, 0);
148     printw("Mem Used :");
149     move(8, 0);
150     printw("Mem Free :");
151    
152     /* Swap */
153     move(6, 21);
154     printw("Swap Total:");
155     move(7, 21);
156     printw("Swap Used :");
157     move(8, 21);
158     printw("Swap Free :");
159    
160     /* VM */
161     move(6, 42);
162     printw("Mem Used :");
163     move(7, 42);
164     printw("Swap Used :");
165     move(8, 42);
166     printw("Total Used:");
167    
168     /* Paging */
169     move(6, 62);
170     printw("Paging in :");
171     move(7, 62);
172     printw("Paging out:");
173    
174     /* Disk IO */
175     move(10,0);
176     printw("Disk Name");
177     move(10,15);
178     printw("Read");
179     move(10,28);
180     printw("Write");
181    
182 ats 1.11 line = 10;
183     if (stats.network_stats != NULL) {
184     /* Network IO */
185     move(line, 42);
186     printw("Network Interface");
187     move(line, 67);
188     printw("rx");
189     move(line, 77);
190     printw("tx");
191     line += 2 + stats.network_entries;
192     }
193 pajs 1.1
194 ats 1.11 move(line, 42);
195 pajs 1.1 printw("Mount Point");
196 ats 1.11 move(line, 65);
197 pajs 1.1 printw("Free");
198 ats 1.11 move(line, 75);
199 pajs 1.1 printw("Used");
200    
201     refresh();
202     }
203    
204     void display_data(){
205     char cur_time[20];
206     struct tm *tm_time;
207     time_t epoc_time;
208 ats 1.11 int counter, line;
209 pajs 1.1 long long r,w;
210     long long rt, wt;
211     diskio_stat_t *diskio_stat_ptr;
212     network_stat_t *network_stat_ptr;
213     disk_stat_t *disk_stat_ptr;
214 pajs 1.7 /* Size before it will start overwriting "uptime" */
215     char hostname[15];
216     char *ptr;
217 pajs 1.1
218 ats 1.11 if (stats.general_stats != NULL) {
219     move(0,12);
220     strncpy(hostname, stats.general_stats->hostname, (sizeof(hostname) - 1));
221     /* strncpy does not NULL terminate.. If only strlcpy was on all platforms :) */
222     hostname[14] = '\0';
223     ptr=strchr(hostname, '.');
224     /* Some hosts give back a FQDN for hostname. To avoid this, we'll
225     * just blank out everything after the first "."
226     */
227     if (ptr != NULL){
228     *ptr = '\0';
229     }
230     printw("%s", hostname);
231     move(0,36);
232     printw("%s", hr_uptime(stats.general_stats->uptime));
233     epoc_time=time(NULL);
234     tm_time = localtime(&epoc_time);
235     strftime(cur_time, 20, "%Y-%m-%d %T", tm_time);
236     move(0,61);
237     printw("%s", cur_time);
238     }
239 pajs 1.1
240 ats 1.11 if (stats.load_stats != NULL) {
241     /* Load */
242     move(2,12);
243     printw("%6.2f", stats.load_stats->min1);
244     move(3,12);
245     printw("%6.2f", stats.load_stats->min5);
246     move(4,12);
247     printw("%6.2f", stats.load_stats->min15);
248     }
249 pajs 1.1
250 ats 1.11 if (stats.cpu_percents != NULL) {
251     /* CPU */
252     move(2,33);
253     printw("%6.2f%%", stats.cpu_percents->idle);
254     move(3,33);
255     printw("%6.2f%%", (stats.cpu_percents->kernel + stats.cpu_percents->iowait + stats.cpu_percents->swap));
256     move(4,33);
257     printw("%6.2f%%", (stats.cpu_percents->user + stats.cpu_percents->nice));
258     }
259 pajs 1.1
260 ats 1.11 if (stats.process_stats != NULL) {
261     /* Process */
262     move(2, 54);
263     printw("%5d", stats.process_stats->running);
264     move(2,74);
265     printw("%5d", stats.process_stats->zombie);
266     move(3, 54);
267     printw("%5d", stats.process_stats->sleeping);
268     move(3, 74);
269     printw("%5d", stats.process_stats->total);
270     move(4, 54);
271     printw("%5d", stats.process_stats->stopped);
272     }
273     if (stats.user_stats != NULL) {
274     move(4,74);
275     printw("%5d", stats.user_stats->num_entries);
276     }
277 pajs 1.1
278 ats 1.11 if (stats.mem_stats != NULL) {
279     /* Mem */
280     move(6, 12);
281     printw("%7s", size_conv(stats.mem_stats->total));
282     move(7, 12);
283     printw("%7s", size_conv(stats.mem_stats->used));
284     move(8, 12);
285     printw("%7s", size_conv(stats.mem_stats->free));
286     }
287 pajs 1.1
288 ats 1.11 if (stats.swap_stats != NULL) {
289     /* Swap */
290     move(6, 32);
291     printw("%8s", size_conv(stats.swap_stats->total));
292     move(7, 32);
293     printw("%8s", size_conv(stats.swap_stats->used));
294     move(8, 32);
295     printw("%8s", size_conv(stats.swap_stats->free));
296     }
297    
298 tdb 1.12 /* VM */
299 tdb 1.13 if (stats.mem_stats != NULL && stats.mem_stats->total != 0) {
300 ats 1.11 move(6, 54);
301     printw("%5.2f%%", (100.00 * (float)(stats.mem_stats->used)/stats.mem_stats->total));
302 tdb 1.12 }
303 tdb 1.13 if (stats.swap_stats != NULL && stats.swap_stats->total != 0) {
304 ats 1.11 move(7, 54);
305     printw("%5.2f%%", (100.00 * (float)(stats.swap_stats->used)/stats.swap_stats->total));
306 tdb 1.12 }
307 tdb 1.13 if (stats.mem_stats != NULL && stats.swap_stats != NULL &&
308     stats.mem_stats->total != 0 && stats.swap_stats->total != 0) {
309 ats 1.11 move(8, 54);
310     printw("%5.2f%%", (100.00 * (float)(stats.mem_stats->used+stats.swap_stats->used)/(stats.mem_stats->total+stats.swap_stats->total)));
311     }
312    
313     if (stats.page_stats != NULL) {
314     /* Paging */
315     move(6, 74);
316     printw("%5d", (stats.page_stats->systime)? (stats.page_stats->pages_pagein / stats.page_stats->systime): stats.page_stats->pages_pagein);
317     move(7, 74);
318     printw("%5d", (stats.page_stats->systime)? (stats.page_stats->pages_pageout / stats.page_stats->systime) : stats.page_stats->pages_pageout);
319     }
320 pajs 1.1
321 ats 1.11 line = 11;
322     if (stats.diskio_stats != NULL) {
323     /* Disk IO */
324     diskio_stat_ptr = stats.diskio_stats;
325     r=0;
326     w=0;
327     for(counter=0;counter<stats.diskio_entries;counter++){
328     move(line, 0);
329     printw("%s", diskio_stat_ptr->disk_name);
330     move(line, 12);
331     rt = (diskio_stat_ptr->systime)? (diskio_stat_ptr->read_bytes/diskio_stat_ptr->systime): diskio_stat_ptr->read_bytes;
332     printw("%7s", size_conv(rt));
333     r+=rt;
334     move(line, 26);
335     wt = (diskio_stat_ptr->systime)? (diskio_stat_ptr->write_bytes/diskio_stat_ptr->systime): diskio_stat_ptr->write_bytes;
336     printw("%7s", size_conv(wt));
337     w+=wt;
338     diskio_stat_ptr++;
339     line++;
340     }
341     line++;
342     move(line, 0);
343     printw("Total");
344     move(line, 12);
345     printw("%7s", size_conv(r));
346     move(line, 26);
347     printw("%7s", size_conv(w));
348     }
349 pajs 1.1
350 ats 1.11 line = 11;
351     if (stats.network_stats != NULL) {
352     /* Network */
353     network_stat_ptr = stats.network_stats;
354     for(counter=0;counter<stats.network_entries;counter++){
355     move(line, 42);
356     printw("%s", network_stat_ptr->interface_name);
357     move(line, 62);
358     rt = (network_stat_ptr->systime)? (network_stat_ptr->rx / network_stat_ptr->systime): network_stat_ptr->rx;
359     printw("%7s", size_conv(rt));
360     move(line, 72);
361     wt = (network_stat_ptr->systime)? (network_stat_ptr->tx / network_stat_ptr->systime): network_stat_ptr->tx;
362     printw("%7s", size_conv(wt));
363     network_stat_ptr++;
364     line++;
365     }
366     line += 2;
367     }
368 pajs 1.1
369 ats 1.11 if (stats.disk_stats != NULL) {
370     /* Disk */
371     disk_stat_ptr = stats.disk_stats;
372     for(counter=0;counter<stats.disk_entries;counter++){
373     move(line, 42);
374     printw("%s", disk_stat_ptr->mnt_point);
375     move(line, 62);
376     printw("%7s", size_conv(disk_stat_ptr->avail));
377     move(line, 73);
378     printw("%5.2f%%", 100.00 * ((float) disk_stat_ptr->used / (float) (disk_stat_ptr->used + disk_stat_ptr->avail)));
379     disk_stat_ptr++;
380     line++;
381     }
382 pajs 1.1 }
383    
384     refresh();
385     }
386    
387     void sig_winch_handler(int sig){
388     clear();
389     display_headings();
390     display_data();
391     signal(SIGWINCH, sig_winch_handler);
392     }
393    
394     int get_stats(){
395 ats 1.11 stats.cpu_percents = cpu_percent_usage();
396     stats.mem_stats = get_memory_stats();
397     stats.swap_stats = get_swap_stats();
398     stats.load_stats = get_load_stats();
399     stats.process_stats = get_process_stats();
400     stats.page_stats = get_page_stats_diff();
401     stats.network_stats = get_network_stats_diff(&(stats.network_entries));
402     stats.diskio_stats = get_diskio_stats_diff(&(stats.diskio_entries));
403     stats.disk_stats = get_disk_stats(&(stats.disk_entries));
404     stats.general_stats = get_general_stats();
405     stats.user_stats = get_user_stats();
406 pajs 1.1
407 ats 1.11 return 1;
408 pajs 1.1 }
409    
410 pajs 1.3 void version_num(char *progname){
411 pajs 1.5 fprintf(stderr, "%s version %s\n", progname, PACKAGE_VERSION);
412 pajs 1.3 fprintf(stderr, "\nReport bugs to <%s>.\n", PACKAGE_BUGREPORT);
413     exit(1);
414     }
415    
416     void usage(char *progname){
417     fprintf(stderr, "Usage: %s [-d delay] [-v] [-h]\n\n", progname);
418     fprintf(stderr, " -d Sets the update time in seconds\n");
419 pajs 1.4 fprintf(stderr, " -v Prints version number\n");
420 pajs 1.3 fprintf(stderr, " -h Displays this help information.\n");
421     fprintf(stderr, "\nReport bugs to <%s>.\n", PACKAGE_BUGREPORT);
422     exit(1);
423     }
424    
425 pajs 1.1 int main(int argc, char **argv){
426    
427     extern char *optarg;
428     extern int optind;
429     int c;
430    
431 ats 1.17 time_t last_update = 0;
432    
433 pajs 1.1 WINDOW *window;
434    
435     extern int errno;
436    
437     int delay=2;
438 pajs 1.10 #ifdef ALLBSD
439     gid_t gid;
440     #endif
441 ats 1.11 statgrab_init();
442 pajs 1.10 #ifdef ALLBSD
443     if((setegid(getgid())) != 0){
444     fprintf(stderr, "Failed to lose setgid'ness\n");
445     return 1;
446     }
447     #endif
448    
449 ats 1.16 while ((c = getopt(argc, argv, "vhd:")) != -1){
450 pajs 1.1 switch (c){
451     case 'd':
452     delay = atoi(optarg);
453     if (delay == 0){
454     fprintf(stderr, "Time must be 1 second or greater\n");
455     exit(1);
456     }
457     delay--;
458     break;
459 pajs 1.3 case 'v':
460     version_num(argv[0]);
461     break;
462     case 'h':
463     default:
464     usage(argv[0]);
465     return 1;
466     break;
467    
468 pajs 1.1 }
469     }
470    
471     signal(SIGWINCH, sig_winch_handler);
472     initscr();
473     nonl();
474     cbreak();
475     noecho();
476 ats 1.14 timeout(delay * 1000);
477 pajs 1.1 window=newwin(0, 0, 0, 0);
478     clear();
479    
480     if(!get_stats()){
481     fprintf(stderr, "Failed to get all the stats. Please check correct permissions\n");
482     endwin();
483     return 1;
484     }
485    
486     display_headings();
487    
488     for(;;){
489 ats 1.17 time_t now;
490 ats 1.15 int ch = getch();
491 ats 1.17
492 ats 1.14 if (ch == 'q'){
493     endwin();
494     return 0;
495 pajs 1.1 }
496    
497 ats 1.17 /* To keep the numbers slightly accurate we do not want them
498     * updating more frequently than once a second.
499     */
500     now = time(NULL);
501     if ((now - last_update) >= 1) {
502     get_stats();
503     }
504     last_update = now;
505 pajs 1.1
506     display_data();
507     }
508    
509     endwin();
510     return 0;
511     }