ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libstatgrab/src/saidar/saidar.c
Revision: 1.25
Committed: Wed Jan 21 10:27:46 2004 UTC (20 years, 4 months ago) by tdb
Content type: text/plain
Branch: MAIN
CVS Tags: LIBSTATGRAB_0_9, LIBSTATGRAB_0_8_2, LIBSTATGRAB_0_8_1
Changes since 1.24: +2 -2 lines
Log Message:
Very minor fix to saidar. It happily accepted a negative number for
it's delay flag - which wasn't overly useful :-)

File Contents

# Content
1 /*
2 * i-scream central monitoring system
3 * http://www.i-scream.org
4 * Copyright (C) 2000-2004 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 * $Id: saidar.c,v 1.24 2004/01/19 16:49:23 tdb Exp $
21 */
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #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
40 #ifdef HAVE_NCURSES_H
41 #include <ncurses.h>
42 #else
43 #include <curses.h>
44 #endif
45
46 typedef struct{
47 cpu_percent_t *cpu_percents;
48 mem_stat_t *mem_stats;
49 swap_stat_t *swap_stats;
50 load_stat_t *load_stats;
51 process_stat_t *process_stats;
52 page_stat_t *page_stats;
53
54 network_stat_t *network_stats;
55 int network_entries;
56
57 diskio_stat_t *diskio_stats;
58 int diskio_entries;
59
60 disk_stat_t *disk_stats;
61 int disk_entries;
62
63 general_stat_t *general_stats;
64 user_stat_t *user_stats;
65 }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 int line;
108
109 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 line = 10;
185 if (stats.network_stats != NULL) {
186 /* 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 line += 2 + stats.network_entries;
194 }
195
196 move(line, 42);
197 printw("Mount Point");
198 move(line, 65);
199 printw("Free");
200 move(line, 75);
201 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 int counter, line;
211 long long r,w;
212 long long rt, wt;
213 diskio_stat_t *diskio_stat_ptr;
214 network_stat_t *network_stat_ptr;
215 disk_stat_t *disk_stat_ptr;
216 /* Size before it will start overwriting "uptime" */
217 char hostname[15];
218 char *ptr;
219
220 if (stats.general_stats != NULL) {
221 move(0,12);
222 strncpy(hostname, stats.general_stats->hostname, (sizeof(hostname) - 1));
223 /* 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 printw("%s", hr_uptime(stats.general_stats->uptime));
235 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
242 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
252 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
262 if (stats.process_stats != NULL) {
263 /* Process */
264 move(2, 54);
265 printw("%5d", stats.process_stats->running);
266 move(2,74);
267 printw("%5d", stats.process_stats->zombie);
268 move(3, 54);
269 printw("%5d", stats.process_stats->sleeping);
270 move(3, 74);
271 printw("%5d", stats.process_stats->total);
272 move(4, 54);
273 printw("%5d", stats.process_stats->stopped);
274 }
275 if (stats.user_stats != NULL) {
276 move(4,74);
277 printw("%5d", stats.user_stats->num_entries);
278 }
279
280 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
290 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 /* VM */
301 if (stats.mem_stats != NULL && stats.mem_stats->total != 0) {
302 move(6, 54);
303 printw("%5.2f%%", (100.00 * (float)(stats.mem_stats->used)/stats.mem_stats->total));
304 }
305 if (stats.swap_stats != NULL && stats.swap_stats->total != 0) {
306 move(7, 54);
307 printw("%5.2f%%", (100.00 * (float)(stats.swap_stats->used)/stats.swap_stats->total));
308 }
309 if (stats.mem_stats != NULL && stats.swap_stats != NULL &&
310 stats.mem_stats->total != 0 && stats.swap_stats->total != 0) {
311 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
323 line = 11;
324 if (stats.diskio_stats != NULL) {
325 /* Disk IO */
326 diskio_stat_ptr = stats.diskio_stats;
327 r=0;
328 w=0;
329 for(counter=0;counter<stats.diskio_entries;counter++){
330 move(line, 0);
331 printw("%s", diskio_stat_ptr->disk_name);
332 move(line, 12);
333 rt = (diskio_stat_ptr->systime)? (diskio_stat_ptr->read_bytes/diskio_stat_ptr->systime): diskio_stat_ptr->read_bytes;
334 printw("%7s", size_conv(rt));
335 r+=rt;
336 move(line, 26);
337 wt = (diskio_stat_ptr->systime)? (diskio_stat_ptr->write_bytes/diskio_stat_ptr->systime): diskio_stat_ptr->write_bytes;
338 printw("%7s", size_conv(wt));
339 w+=wt;
340 diskio_stat_ptr++;
341 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
352 line = 11;
353 if (stats.network_stats != NULL) {
354 /* Network */
355 network_stat_ptr = stats.network_stats;
356 for(counter=0;counter<stats.network_entries;counter++){
357 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
371 if (stats.disk_stats != NULL) {
372 /* Disk */
373 disk_stat_ptr = stats.disk_stats;
374 for(counter=0;counter<stats.disk_entries;counter++){
375 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 }
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 stats.cpu_percents = cpu_percent_usage();
398 stats.mem_stats = get_memory_stats();
399 stats.swap_stats = get_swap_stats();
400 stats.load_stats = get_load_stats();
401 stats.process_stats = get_process_stats();
402 stats.page_stats = get_page_stats_diff();
403 stats.network_stats = get_network_stats_diff(&(stats.network_entries));
404 stats.diskio_stats = get_diskio_stats_diff(&(stats.diskio_entries));
405 stats.disk_stats = get_disk_stats(&(stats.disk_entries));
406 stats.general_stats = get_general_stats();
407 stats.user_stats = get_user_stats();
408
409 return 1;
410 }
411
412 void version_num(char *progname){
413 fprintf(stderr, "%s version %s\n", progname, PACKAGE_VERSION);
414 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 fprintf(stderr, " -v Prints version number\n");
422 fprintf(stderr, " -h Displays this help information.\n");
423 fprintf(stderr, "\nReport bugs to <%s>.\n", PACKAGE_BUGREPORT);
424 exit(1);
425 }
426
427 int main(int argc, char **argv){
428
429 extern char *optarg;
430 extern int optind;
431 int c;
432
433 time_t last_update = 0;
434
435 WINDOW *window;
436
437 extern int errno;
438
439 int delay=2;
440
441 statgrab_init();
442 if(statgrab_drop_privileges() != 0){
443 fprintf(stderr, "Failed to drop setuid/setgid privileges\n");
444 return 1;
445 }
446
447 while ((c = getopt(argc, argv, "vhd:")) != -1){
448 switch (c){
449 case 'd':
450 delay = atoi(optarg);
451 if (delay < 1){
452 fprintf(stderr, "Time must be 1 second or greater\n");
453 exit(1);
454 }
455 break;
456 case 'v':
457 version_num(argv[0]);
458 break;
459 case 'h':
460 default:
461 usage(argv[0]);
462 return 1;
463 break;
464 }
465 }
466
467 signal(SIGWINCH, sig_winch_handler);
468 initscr();
469 nonl();
470 cbreak();
471 noecho();
472 timeout(delay * 1000);
473 window=newwin(0, 0, 0, 0);
474 clear();
475
476 if(!get_stats()){
477 fprintf(stderr, "Failed to get all the stats. Please check correct permissions\n");
478 endwin();
479 return 1;
480 }
481
482 display_headings();
483
484 for(;;){
485 time_t now;
486 int ch = getch();
487
488 if (ch == 'q'){
489 break;
490 }
491
492 /* To keep the numbers slightly accurate we do not want them
493 * updating more frequently than once a second.
494 */
495 now = time(NULL);
496 if ((now - last_update) >= 1) {
497 get_stats();
498 }
499 last_update = now;
500
501 display_data();
502 }
503
504 endwin();
505 return 0;
506 }