ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libstatgrab/src/saidar/saidar.c
Revision: 1.12
Committed: Tue Oct 21 18:01:15 2003 UTC (20 years, 7 months ago) by tdb
Content type: text/plain
Branch: MAIN
CVS Tags: LIBSTATGRAB_0_7
Changes since 1.11: +6 -2 lines
Log Message:
Make saidar display the VM percentages for swap *or* memory if it can,
rather than not displaying either if it can't get one or the other.

File Contents

# Content
1 /*
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 #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
38 #ifdef HAVE_NCURSES_H
39 #include <ncurses.h>
40 #else
41 #include <curses.h>
42 #endif
43
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 int line;
106
107 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 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
194 move(line, 42);
195 printw("Mount Point");
196 move(line, 65);
197 printw("Free");
198 move(line, 75);
199 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 int counter, line;
209 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 /* Size before it will start overwriting "uptime" */
215 char hostname[15];
216 char *ptr;
217
218 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
240 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
250 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
260 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
278 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
288 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 /* VM */
299 if (stats.mem_stats != NULL) {
300 move(6, 54);
301 printw("%5.2f%%", (100.00 * (float)(stats.mem_stats->used)/stats.mem_stats->total));
302 }
303 if (stats.swap_stats != NULL) {
304 move(7, 54);
305 printw("%5.2f%%", (100.00 * (float)(stats.swap_stats->used)/stats.swap_stats->total));
306 }
307 if (stats.mem_stats != NULL && stats.swap_stats != NULL) {
308 move(8, 54);
309 printw("%5.2f%%", (100.00 * (float)(stats.mem_stats->used+stats.swap_stats->used)/(stats.mem_stats->total+stats.swap_stats->total)));
310 }
311
312 if (stats.page_stats != NULL) {
313 /* Paging */
314 move(6, 74);
315 printw("%5d", (stats.page_stats->systime)? (stats.page_stats->pages_pagein / stats.page_stats->systime): stats.page_stats->pages_pagein);
316 move(7, 74);
317 printw("%5d", (stats.page_stats->systime)? (stats.page_stats->pages_pageout / stats.page_stats->systime) : stats.page_stats->pages_pageout);
318 }
319
320 line = 11;
321 if (stats.diskio_stats != NULL) {
322 /* Disk IO */
323 diskio_stat_ptr = stats.diskio_stats;
324 r=0;
325 w=0;
326 for(counter=0;counter<stats.diskio_entries;counter++){
327 move(line, 0);
328 printw("%s", diskio_stat_ptr->disk_name);
329 move(line, 12);
330 rt = (diskio_stat_ptr->systime)? (diskio_stat_ptr->read_bytes/diskio_stat_ptr->systime): diskio_stat_ptr->read_bytes;
331 printw("%7s", size_conv(rt));
332 r+=rt;
333 move(line, 26);
334 wt = (diskio_stat_ptr->systime)? (diskio_stat_ptr->write_bytes/diskio_stat_ptr->systime): diskio_stat_ptr->write_bytes;
335 printw("%7s", size_conv(wt));
336 w+=wt;
337 diskio_stat_ptr++;
338 line++;
339 }
340 line++;
341 move(line, 0);
342 printw("Total");
343 move(line, 12);
344 printw("%7s", size_conv(r));
345 move(line, 26);
346 printw("%7s", size_conv(w));
347 }
348
349 line = 11;
350 if (stats.network_stats != NULL) {
351 /* Network */
352 network_stat_ptr = stats.network_stats;
353 for(counter=0;counter<stats.network_entries;counter++){
354 move(line, 42);
355 printw("%s", network_stat_ptr->interface_name);
356 move(line, 62);
357 rt = (network_stat_ptr->systime)? (network_stat_ptr->rx / network_stat_ptr->systime): network_stat_ptr->rx;
358 printw("%7s", size_conv(rt));
359 move(line, 72);
360 wt = (network_stat_ptr->systime)? (network_stat_ptr->tx / network_stat_ptr->systime): network_stat_ptr->tx;
361 printw("%7s", size_conv(wt));
362 network_stat_ptr++;
363 line++;
364 }
365 line += 2;
366 }
367
368 if (stats.disk_stats != NULL) {
369 /* Disk */
370 disk_stat_ptr = stats.disk_stats;
371 for(counter=0;counter<stats.disk_entries;counter++){
372 move(line, 42);
373 printw("%s", disk_stat_ptr->mnt_point);
374 move(line, 62);
375 printw("%7s", size_conv(disk_stat_ptr->avail));
376 move(line, 73);
377 printw("%5.2f%%", 100.00 * ((float) disk_stat_ptr->used / (float) (disk_stat_ptr->used + disk_stat_ptr->avail)));
378 disk_stat_ptr++;
379 line++;
380 }
381 }
382
383 refresh();
384 }
385
386 void sig_winch_handler(int sig){
387 clear();
388 display_headings();
389 display_data();
390 signal(SIGWINCH, sig_winch_handler);
391 }
392
393 int get_stats(){
394 stats.cpu_percents = cpu_percent_usage();
395 stats.mem_stats = get_memory_stats();
396 stats.swap_stats = get_swap_stats();
397 stats.load_stats = get_load_stats();
398 stats.process_stats = get_process_stats();
399 stats.page_stats = get_page_stats_diff();
400 stats.network_stats = get_network_stats_diff(&(stats.network_entries));
401 stats.diskio_stats = get_diskio_stats_diff(&(stats.diskio_entries));
402 stats.disk_stats = get_disk_stats(&(stats.disk_entries));
403 stats.general_stats = get_general_stats();
404 stats.user_stats = get_user_stats();
405
406 return 1;
407 }
408
409 void version_num(char *progname){
410 fprintf(stderr, "%s version %s\n", progname, PACKAGE_VERSION);
411 fprintf(stderr, "\nReport bugs to <%s>.\n", PACKAGE_BUGREPORT);
412 exit(1);
413 }
414
415 void usage(char *progname){
416 fprintf(stderr, "Usage: %s [-d delay] [-v] [-h]\n\n", progname);
417 fprintf(stderr, " -d Sets the update time in seconds\n");
418 fprintf(stderr, " -v Prints version number\n");
419 fprintf(stderr, " -h Displays this help information.\n");
420 fprintf(stderr, "\nReport bugs to <%s>.\n", PACKAGE_BUGREPORT);
421 exit(1);
422 }
423
424 int main(int argc, char **argv){
425
426 extern char *optarg;
427 extern int optind;
428 int c;
429
430 WINDOW *window;
431
432 int stdin_fileno;
433 fd_set infds;
434 struct timeval timeout;
435
436 extern int errno;
437 char ch;
438
439 int delay=2;
440 #ifdef ALLBSD
441 gid_t gid;
442 #endif
443 statgrab_init();
444 #ifdef ALLBSD
445 if((setegid(getgid())) != 0){
446 fprintf(stderr, "Failed to lose setgid'ness\n");
447 return 1;
448 }
449 #endif
450
451 while ((c = getopt(argc, argv, "vhd:")) != EOF){
452 switch (c){
453 case 'd':
454 delay = atoi(optarg);
455 if (delay == 0){
456 fprintf(stderr, "Time must be 1 second or greater\n");
457 exit(1);
458 }
459 delay--;
460 break;
461 case 'v':
462 version_num(argv[0]);
463 break;
464 case 'h':
465 default:
466 usage(argv[0]);
467 return 1;
468 break;
469
470 }
471 }
472
473 signal(SIGWINCH, sig_winch_handler);
474 initscr();
475 nonl();
476 cbreak();
477 noecho();
478 window=newwin(0, 0, 0, 0);
479 clear();
480
481 if(!get_stats()){
482 fprintf(stderr, "Failed to get all the stats. Please check correct permissions\n");
483 endwin();
484 return 1;
485 }
486
487 display_headings();
488 stdin_fileno=fileno(stdin);
489
490 for(;;){
491
492 FD_ZERO(&infds);
493 FD_SET(stdin_fileno, &infds);
494 timeout.tv_sec = delay;
495 timeout.tv_usec = 0;
496
497 if((select((stdin_fileno+1), &infds, NULL, NULL, &timeout)) == -1){
498 if(errno!=EINTR){
499 perror("select failed");
500 exit(1);
501 }
502 }
503
504 if(FD_ISSET(stdin_fileno, &infds)){
505 ch=getch();
506 if (ch == 'q'){
507 endwin();
508 return 0;
509 }
510 }
511
512 get_stats();
513
514 display_data();
515
516 /* To keep the numbers slightly accurate we do not want them updating more
517 * frequently than once a second.
518 */
519 sleep(1);
520 }
521
522 endwin();
523 return 0;
524 }