ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libstatgrab/src/saidar/saidar.c
Revision: 1.34
Committed: Wed Sep 7 14:15:40 2005 UTC (18 years, 8 months ago) by tdb
Content type: text/plain
Branch: MAIN
CVS Tags: LIBSTATGRAB_0_13
Changes since 1.33: +13 -4 lines
Log Message:
Simple hack to truncate disk/interface/mount names to fit in to the
field. Before this they just overwrote stuff and it got messy.

Hardly an elegant fix, btw ;)

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.34 * $Id: saidar.c,v 1.33 2005/01/17 16:34:26 tdb 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 tdb 1.34 char name[12];
339     strncpy(name, disk_io_stat_ptr->disk_name, sizeof(name));
340     name[sizeof(name)-1] = '\0'; /* strncpy doesn't terminate longer strings */
341 ats 1.11 move(line, 0);
342 tdb 1.34 printw("%s", name);
343 ats 1.11 move(line, 12);
344 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;
345 ats 1.11 printw("%7s", size_conv(rt));
346     r+=rt;
347     move(line, 26);
348 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;
349 ats 1.11 printw("%7s", size_conv(wt));
350     w+=wt;
351 ats 1.27 disk_io_stat_ptr++;
352 ats 1.11 line++;
353     }
354     line++;
355     move(line, 0);
356     printw("Total");
357     move(line, 12);
358     printw("%7s", size_conv(r));
359     move(line, 26);
360     printw("%7s", size_conv(w));
361     }
362 pajs 1.1
363 ats 1.11 line = 11;
364 ats 1.27 if (stats.network_io_stats != NULL) {
365 ats 1.11 /* Network */
366 ats 1.27 network_stat_ptr = stats.network_io_stats;
367     for(counter=0;counter<stats.network_io_entries;counter++){
368 tdb 1.34 char name[20];
369     strncpy(name, network_stat_ptr->interface_name, sizeof(name));
370     name[sizeof(name)-1] = '\0'; /* strncpy doesn't terminate longer strings */
371 tdb 1.29 move(line, 42);
372 tdb 1.34 printw("%s", name);
373 ats 1.11 move(line, 62);
374     rt = (network_stat_ptr->systime)? (network_stat_ptr->rx / network_stat_ptr->systime): network_stat_ptr->rx;
375     printw("%7s", size_conv(rt));
376     move(line, 72);
377     wt = (network_stat_ptr->systime)? (network_stat_ptr->tx / network_stat_ptr->systime): network_stat_ptr->tx;
378     printw("%7s", size_conv(wt));
379     network_stat_ptr++;
380     line++;
381     }
382     line += 2;
383     }
384 pajs 1.1
385 ats 1.27 if (stats.fs_stats != NULL) {
386 ats 1.11 /* Disk */
387 ats 1.27 disk_stat_ptr = stats.fs_stats;
388     for(counter=0;counter<stats.fs_entries;counter++){
389 tdb 1.34 char name[20];
390     strncpy(name, disk_stat_ptr->mnt_point, sizeof(name));
391     name[sizeof(name)-1] = '\0'; /* strncpy doesn't terminate longer strings */
392 ats 1.11 move(line, 42);
393 tdb 1.34 printw("%s", name);
394 ats 1.11 move(line, 62);
395     printw("%7s", size_conv(disk_stat_ptr->avail));
396     move(line, 73);
397 tdb 1.30 printw("%6.2f%%", 100.00 * ((float) disk_stat_ptr->used / (float) (disk_stat_ptr->used + disk_stat_ptr->avail)));
398 ats 1.11 disk_stat_ptr++;
399     line++;
400     }
401 pajs 1.1 }
402    
403     refresh();
404     }
405    
406 ats 1.32 void sig_winch_handler(int dummy){
407 pajs 1.1 clear();
408     display_headings();
409     display_data();
410 tdb 1.29 signal(SIGWINCH, sig_winch_handler);
411 pajs 1.1 }
412    
413     int get_stats(){
414 ats 1.27 stats.cpu_percents = sg_get_cpu_percents();
415     stats.mem_stats = sg_get_mem_stats();
416     stats.swap_stats = sg_get_swap_stats();
417     stats.load_stats = sg_get_load_stats();
418     stats.process_count = sg_get_process_count();
419     stats.page_stats = sg_get_page_stats_diff();
420     stats.network_io_stats = sg_get_network_io_stats_diff(&(stats.network_io_entries));
421     stats.disk_io_stats = sg_get_disk_io_stats_diff(&(stats.disk_io_entries));
422     stats.fs_stats = sg_get_fs_stats(&(stats.fs_entries));
423     stats.host_info = sg_get_host_info();
424     stats.user_stats = sg_get_user_stats();
425 pajs 1.1
426 ats 1.11 return 1;
427 pajs 1.1 }
428    
429 pajs 1.3 void version_num(char *progname){
430 pajs 1.5 fprintf(stderr, "%s version %s\n", progname, PACKAGE_VERSION);
431 pajs 1.3 fprintf(stderr, "\nReport bugs to <%s>.\n", PACKAGE_BUGREPORT);
432     exit(1);
433     }
434    
435     void usage(char *progname){
436 tdb 1.29 fprintf(stderr, "Usage: %s [-d delay] [-v] [-h]\n\n", progname);
437     fprintf(stderr, " -d Sets the update time in seconds\n");
438 pajs 1.4 fprintf(stderr, " -v Prints version number\n");
439 tdb 1.29 fprintf(stderr, " -h Displays this help information.\n");
440     fprintf(stderr, "\nReport bugs to <%s>.\n", PACKAGE_BUGREPORT);
441     exit(1);
442 pajs 1.3 }
443    
444 pajs 1.1 int main(int argc, char **argv){
445    
446 tdb 1.29 extern char *optarg;
447     int c;
448 pajs 1.1
449 ats 1.17 time_t last_update = 0;
450    
451 pajs 1.1 WINDOW *window;
452    
453     extern int errno;
454    
455     int delay=2;
456 ats 1.21
457 ats 1.27 sg_init();
458     if(sg_drop_privileges() != 0){
459 ats 1.22 fprintf(stderr, "Failed to drop setuid/setgid privileges\n");
460 pajs 1.10 return 1;
461     }
462    
463 tdb 1.29 while ((c = getopt(argc, argv, "vhd:")) != -1){
464     switch (c){
465     case 'd':
466     delay = atoi(optarg);
467 tdb 1.25 if (delay < 1){
468 pajs 1.1 fprintf(stderr, "Time must be 1 second or greater\n");
469     exit(1);
470     }
471 tdb 1.29 break;
472 pajs 1.3 case 'v':
473     version_num(argv[0]);
474     break;
475     case 'h':
476     default:
477     usage(argv[0]);
478     return 1;
479     break;
480 tdb 1.29 }
481     }
482 pajs 1.1
483     signal(SIGWINCH, sig_winch_handler);
484 tdb 1.29 initscr();
485     nonl();
486     cbreak();
487     noecho();
488 ats 1.14 timeout(delay * 1000);
489 tdb 1.29 window=newwin(0, 0, 0, 0);
490 pajs 1.1 clear();
491    
492     if(!get_stats()){
493     fprintf(stderr, "Failed to get all the stats. Please check correct permissions\n");
494     endwin();
495     return 1;
496     }
497    
498     display_headings();
499    
500     for(;;){
501 ats 1.17 time_t now;
502 ats 1.15 int ch = getch();
503 ats 1.17
504 ats 1.14 if (ch == 'q'){
505 ats 1.18 break;
506 pajs 1.1 }
507    
508 ats 1.17 /* To keep the numbers slightly accurate we do not want them
509     * updating more frequently than once a second.
510     */
511     now = time(NULL);
512     if ((now - last_update) >= 1) {
513     get_stats();
514     }
515     last_update = now;
516 pajs 1.1
517     display_data();
518     }
519    
520     endwin();
521     return 0;
522     }