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

# Content
1 /*
2 * i-scream libstatgrab
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.33 2005/01/17 16:34:26 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 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
57 sg_disk_io_stats *disk_io_stats;
58 int disk_io_entries;
59
60 sg_fs_stats *fs_stats;
61 int fs_entries;
62
63 sg_host_info *host_info;
64 sg_user_stats *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 int sign=1;
73 static char string[10];
74
75 if(number < 0){
76 sign=-1;
77 number=-number;
78 }
79
80 for(;x<5;x++){
81 if( (number/1024) < (100)) {
82 break;
83 }
84 number = (number/1024);
85 }
86
87 number = number*sign;
88
89 snprintf(string, 10, "%lld%c", number, type[x]);
90 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 int line;
116
117 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 move(6, 21);
164 printw("Swap Total:");
165 move(7, 21);
166 printw("Swap Used :");
167 move(8, 21);
168 printw("Swap Free :");
169
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 line = 10;
193 if (stats.network_io_stats != NULL) {
194 /* 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 line += 2 + stats.network_io_entries;
202 }
203
204 move(line, 42);
205 printw("Mount Point");
206 move(line, 65);
207 printw("Free");
208 move(line, 75);
209 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 int counter, line;
219 long long r,w;
220 long long rt, wt;
221 sg_disk_io_stats *disk_io_stat_ptr;
222 sg_network_io_stats *network_stat_ptr;
223 sg_fs_stats *disk_stat_ptr;
224 /* Size before it will start overwriting "uptime" */
225 char hostname[15];
226 char *ptr;
227
228 if (stats.host_info != NULL) {
229 move(0,12);
230 strncpy(hostname, stats.host_info->hostname, (sizeof(hostname) - 1));
231 /* 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 printw("%s", hr_uptime(stats.host_info->uptime));
243 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
250 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
260 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
270 if (stats.process_count != NULL) {
271 /* Process */
272 move(2, 54);
273 printw("%5d", stats.process_count->running);
274 move(2,74);
275 printw("%5d", stats.process_count->zombie);
276 move(3, 54);
277 printw("%5d", stats.process_count->sleeping);
278 move(3, 74);
279 printw("%5d", stats.process_count->total);
280 move(4, 54);
281 printw("%5d", stats.process_count->stopped);
282 }
283 if (stats.user_stats != NULL) {
284 move(4,74);
285 printw("%5d", stats.user_stats->num_entries);
286 }
287
288 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
298 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 /* VM */
309 if (stats.mem_stats != NULL && stats.mem_stats->total != 0) {
310 move(6, 54);
311 printw("%5.2f%%", (100.00 * (float)(stats.mem_stats->used)/stats.mem_stats->total));
312 }
313 if (stats.swap_stats != NULL && stats.swap_stats->total != 0) {
314 move(7, 54);
315 printw("%5.2f%%", (100.00 * (float)(stats.swap_stats->used)/stats.swap_stats->total));
316 }
317 if (stats.mem_stats != NULL && stats.swap_stats != NULL &&
318 stats.mem_stats->total != 0 && stats.swap_stats->total != 0) {
319 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
331 line = 11;
332 if (stats.disk_io_stats != NULL) {
333 /* Disk IO */
334 disk_io_stat_ptr = stats.disk_io_stats;
335 r=0;
336 w=0;
337 for(counter=0;counter<stats.disk_io_entries;counter++){
338 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 move(line, 0);
342 printw("%s", name);
343 move(line, 12);
344 rt = (disk_io_stat_ptr->systime)? (disk_io_stat_ptr->read_bytes/disk_io_stat_ptr->systime): disk_io_stat_ptr->read_bytes;
345 printw("%7s", size_conv(rt));
346 r+=rt;
347 move(line, 26);
348 wt = (disk_io_stat_ptr->systime)? (disk_io_stat_ptr->write_bytes/disk_io_stat_ptr->systime): disk_io_stat_ptr->write_bytes;
349 printw("%7s", size_conv(wt));
350 w+=wt;
351 disk_io_stat_ptr++;
352 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
363 line = 11;
364 if (stats.network_io_stats != NULL) {
365 /* Network */
366 network_stat_ptr = stats.network_io_stats;
367 for(counter=0;counter<stats.network_io_entries;counter++){
368 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 move(line, 42);
372 printw("%s", name);
373 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
385 if (stats.fs_stats != NULL) {
386 /* Disk */
387 disk_stat_ptr = stats.fs_stats;
388 for(counter=0;counter<stats.fs_entries;counter++){
389 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 move(line, 42);
393 printw("%s", name);
394 move(line, 62);
395 printw("%7s", size_conv(disk_stat_ptr->avail));
396 move(line, 73);
397 printw("%6.2f%%", 100.00 * ((float) disk_stat_ptr->used / (float) (disk_stat_ptr->used + disk_stat_ptr->avail)));
398 disk_stat_ptr++;
399 line++;
400 }
401 }
402
403 refresh();
404 }
405
406 void sig_winch_handler(int dummy){
407 clear();
408 display_headings();
409 display_data();
410 signal(SIGWINCH, sig_winch_handler);
411 }
412
413 int get_stats(){
414 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
426 return 1;
427 }
428
429 void version_num(char *progname){
430 fprintf(stderr, "%s version %s\n", progname, PACKAGE_VERSION);
431 fprintf(stderr, "\nReport bugs to <%s>.\n", PACKAGE_BUGREPORT);
432 exit(1);
433 }
434
435 void usage(char *progname){
436 fprintf(stderr, "Usage: %s [-d delay] [-v] [-h]\n\n", progname);
437 fprintf(stderr, " -d Sets the update time in seconds\n");
438 fprintf(stderr, " -v Prints version number\n");
439 fprintf(stderr, " -h Displays this help information.\n");
440 fprintf(stderr, "\nReport bugs to <%s>.\n", PACKAGE_BUGREPORT);
441 exit(1);
442 }
443
444 int main(int argc, char **argv){
445
446 extern char *optarg;
447 int c;
448
449 time_t last_update = 0;
450
451 WINDOW *window;
452
453 extern int errno;
454
455 int delay=2;
456
457 sg_init();
458 if(sg_drop_privileges() != 0){
459 fprintf(stderr, "Failed to drop setuid/setgid privileges\n");
460 return 1;
461 }
462
463 while ((c = getopt(argc, argv, "vhd:")) != -1){
464 switch (c){
465 case 'd':
466 delay = atoi(optarg);
467 if (delay < 1){
468 fprintf(stderr, "Time must be 1 second or greater\n");
469 exit(1);
470 }
471 break;
472 case 'v':
473 version_num(argv[0]);
474 break;
475 case 'h':
476 default:
477 usage(argv[0]);
478 return 1;
479 break;
480 }
481 }
482
483 signal(SIGWINCH, sig_winch_handler);
484 initscr();
485 nonl();
486 cbreak();
487 noecho();
488 timeout(delay * 1000);
489 window=newwin(0, 0, 0, 0);
490 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 time_t now;
502 int ch = getch();
503
504 if (ch == 'q'){
505 break;
506 }
507
508 /* 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
517 display_data();
518 }
519
520 endwin();
521 return 0;
522 }