ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libstatgrab/src/saidar/saidar.c
Revision: 1.27
Committed: Mon Apr 5 15:40:17 2004 UTC (20 years, 1 month ago) by ats
Content type: text/plain
Branch: MAIN
Changes since 1.26: +56 -56 lines
Log Message:
Rename all the functions, types and enums in the API to be consistent.
Types are now of the form "sg_mem_stats"; functions of the form
"sg_get_mem_stats"; enums of the form "SG_PROCESS_STATE_RUNNING".
(The old get_proc_snapshot follows the usual calling convention now.)

Make internal functions static where possible.

Rename non-static internal functions to have an sg_ prefix so they don't
collide with those from other libraries. In particular, strlcpy and
strlcat are now called sg_strlcpy and sg_strlcat and are always
included.

Fix saidar and statgrab to use the new API.

File Contents

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