ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libstatgrab/src/saidar/saidar.c
Revision: 1.33
Committed: Mon Jan 17 16:34:26 2005 UTC (19 years, 10 months ago) by tdb
Content type: text/plain
Branch: MAIN
CVS Tags: LIBSTATGRAB_0_12, LIBSTATGRAB_0_11_1
Changes since 1.32: +10 -2 lines
Log Message:
Make size_conv deal with negative numbers too (it does happen :-).

File Contents

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