ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libstatgrab/src/saidar/saidar.c
Revision: 1.1
Committed: Thu Oct 9 15:57:05 2003 UTC (21 years, 1 month ago) by pajs
Content type: text/plain
Branch: MAIN
Log Message:
First release of saidar. This version works on all platforms, using ncurses
fine. Bugs exist when linked against the solaris curses. (E.g. if while
running saidar you hammer a key repeatedly, the screen no longer updates.
This only happens with the solaris curses however)

Saidar takes a single optional flag, "-d" and an argument of the delay in
seconds. e.g.

saidar -d 1

Will update the screen once a second (the fastest allowed update time). The
default update it every 3 seconds. However, if you press any other key, it
will update immidiately (unless its less than 1 second, in which case it will
update at the earlist available time)

File Contents

# Content
1 #include <stdio.h>
2 #include <string.h>
3 #include <sys/ioctl.h>
4 #include <unistd.h>
5 #include <stdlib.h>
6 #include <sys/termios.h>
7 #include <signal.h>
8 #include <errno.h>
9 #include <statgrab.h>
10 #include <sys/times.h>
11 #include <limits.h>
12 #include <time.h>
13 #include <curses.h>
14
15 typedef struct{
16 cpu_percent_t *cpu_percents;
17 mem_stat_t *mem_stats;
18 swap_stat_t *swap_stats;
19 load_stat_t *load_stats;
20 process_stat_t *process_stats;
21 page_stat_t *page_stats;
22
23 network_stat_t *network_stats;
24 int network_entries;
25
26 diskio_stat_t *diskio_stats;
27 int diskio_entries;
28
29 disk_stat_t *disk_stats;
30 int disk_entries;
31
32 general_stat_t *general_stats;
33 user_stat_t *user_stats;
34 }stats_t;
35
36 stats_t stats;
37
38 char *size_conv(long long number){
39 char type[] = {'B', 'K', 'M', 'G', 'T'};
40 int x=0;
41 static char string[10];
42
43 for(;x<5;x++){
44 if( (number/1024) < (100)) {
45 break;
46 }
47 number = (number/1024);
48 }
49
50 snprintf(string, 10, "%lld%c", number, type[x]);
51 return string;
52
53 }
54
55 char *hr_uptime(time_t time){
56 int day = 0, hour = 0, min = 0;
57 static char uptime_str[25];
58 int sec = (int) time;
59
60 day = sec / (24*60*60);
61 sec = sec % (24*60*60);
62 hour = sec / (60*60);
63 sec = sec % (60*60);
64 min = sec / 60;
65 sec = sec % 60;
66
67 if(day){
68 snprintf(uptime_str, 25, "%dd %02d:%02d:%02d", day, hour, min, sec);
69 }else{
70 snprintf(uptime_str, 25, "%02d:%02d:%02d", hour, min, sec);
71 }
72 return uptime_str;
73 }
74
75 void display_headings(){
76 move(0,0);
77 printw("Hostname :");
78 move(0,27);
79 printw("Uptime : ");
80 move(0,54);
81 printw("Date : ");
82
83 /* Load */
84 move(2,0);
85 printw("Load 1 :");
86 move(3,0);
87 printw("Load 5 :");
88 move(4,0);
89 printw("Load 15 :");
90
91 /* CPU */
92 move(2,21);
93 printw("CPU Idle :");
94 move(3,21);
95 printw("CPU System:");
96 move(4,21);
97 printw("CPU User :");
98
99 /* Process */
100 move(2, 42);
101 printw("Running :");
102 move(3, 42);
103 printw("Sleeping :");
104 move(4, 42);
105 printw("Stopped :");
106 move(2, 62);
107 printw("Zombie :");
108 move(3, 62);
109 printw("Total :");
110 move(4, 62);
111 printw("No. Users :");
112
113 /* Mem */
114 move(6, 0);
115 printw("Mem Total :");
116 move(7, 0);
117 printw("Mem Used :");
118 move(8, 0);
119 printw("Mem Free :");
120
121 /* Swap */
122 move(6, 21);
123 printw("Swap Total:");
124 move(7, 21);
125 printw("Swap Used :");
126 move(8, 21);
127 printw("Swap Free :");
128
129 /* VM */
130 move(6, 42);
131 printw("Mem Used :");
132 move(7, 42);
133 printw("Swap Used :");
134 move(8, 42);
135 printw("Total Used:");
136
137 /* Paging */
138 move(6, 62);
139 printw("Paging in :");
140 move(7, 62);
141 printw("Paging out:");
142
143 /* Disk IO */
144 move(10,0);
145 printw("Disk Name");
146 move(10,15);
147 printw("Read");
148 move(10,28);
149 printw("Write");
150
151 /* Network IO */
152 move(10, 42);
153 printw("Network Interface");
154 move(10, 67);
155 printw("rx");
156 move(10,77);
157 printw("tx");
158
159 move(12+stats.network_entries, 42);
160 printw("Mount Point");
161 move(12+stats.network_entries, 65);
162 printw("Free");
163 move(12+stats.network_entries, 75);
164 printw("Used");
165
166 refresh();
167 }
168
169 void display_data(){
170 char cur_time[20];
171 struct tm *tm_time;
172 time_t epoc_time;
173 int counter;
174 long long r,w;
175 long long rt, wt;
176 diskio_stat_t *diskio_stat_ptr;
177 network_stat_t *network_stat_ptr;
178 disk_stat_t *disk_stat_ptr;
179
180 move(0,12);
181 printw("%s", stats.general_stats->hostname);
182 move(0,36);
183 printw("%s", hr_uptime(stats.general_stats->uptime));
184 epoc_time=time(NULL);
185 tm_time = localtime(&epoc_time);
186 strftime(cur_time, 20, "%Y-%m-%d %T", tm_time);
187 move(0,61);
188 printw("%s", cur_time);
189
190 /* Load */
191 move(2,12);
192 printw("%6.2f", stats.load_stats->min1);
193 move(3,12);
194 printw("%6.2f", stats.load_stats->min5);
195 move(4,12);
196 printw("%6.2f", stats.load_stats->min15);
197
198 /* CPU */
199 move(2,33);
200 printw("%6.2f%%", stats.cpu_percents->idle);
201 move(3,33);
202 printw("%6.2f%%", (stats.cpu_percents->kernel + stats.cpu_percents->iowait + stats.cpu_percents->swap));
203 move(4,33);
204 printw("%6.2f%%", (stats.cpu_percents->user + stats.cpu_percents->nice));
205
206 /* Process */
207 move(2, 54);
208 printw("%5d", stats.process_stats->running);
209 move(2,74);
210 printw("%5d", stats.process_stats->zombie);
211 move(3, 54);
212 printw("%5d", stats.process_stats->sleeping);
213 move(3, 74);
214 printw("%5d", stats.process_stats->total);
215 move(4, 54);
216 printw("%5d", stats.process_stats->stopped);
217 move(4,74);
218 printw("%5d", stats.user_stats->num_entries);
219
220 /* Mem */
221
222 move(6, 12);
223 printw("%7s", size_conv(stats.mem_stats->total));
224 move(7, 12);
225 printw("%7s", size_conv(stats.mem_stats->used));
226 move(8, 12);
227 printw("%7s", size_conv(stats.mem_stats->free));
228
229 /* Swap */
230 move(6, 32);
231 printw("%8s", size_conv(stats.swap_stats->total));
232 move(7, 32);
233 printw("%8s", size_conv(stats.swap_stats->used));
234 move(8, 32);
235 printw("%8s", size_conv(stats.swap_stats->free));
236
237 /* VM */
238 move(6, 54);
239 printw("%5.2f%%", (100.00 * (float)(stats.mem_stats->used)/stats.mem_stats->total));
240 move(7, 54);
241 printw("%5.2f%%", (100.00 * (float)(stats.swap_stats->used)/stats.swap_stats->total));
242 move(8, 54);
243 printw("%5.2f%%", (100.00 * (float)(stats.mem_stats->used+stats.swap_stats->used)/(stats.mem_stats->total+stats.swap_stats->total)));
244
245 /* Paging */
246 move(6, 74);
247 printw("%5d", (stats.page_stats->systime)? (stats.page_stats->pages_pagein / stats.page_stats->systime): stats.page_stats->pages_pagein);
248 move(7, 74);
249 printw("%5d", (stats.page_stats->systime)? (stats.page_stats->pages_pageout / stats.page_stats->systime) : stats.page_stats->pages_pageout);
250
251 /* Disk IO */
252 diskio_stat_ptr = stats.diskio_stats;
253 r=0;
254 w=0;
255 for(counter=0;counter<stats.diskio_entries;counter++){
256 move(11+counter, 0);
257 printw("%s", diskio_stat_ptr->disk_name);
258 move(11+counter, 12);
259 rt = (diskio_stat_ptr->systime)? (diskio_stat_ptr->read_bytes/diskio_stat_ptr->systime): diskio_stat_ptr->read_bytes;
260 printw("%7s", size_conv(rt));
261 r+=rt;
262 move(11+counter, 26);
263 wt = (diskio_stat_ptr->systime)? (diskio_stat_ptr->write_bytes/diskio_stat_ptr->systime): diskio_stat_ptr->write_bytes;
264 printw("%7s", size_conv(wt));
265 w+=wt;
266 diskio_stat_ptr++;
267 }
268 move(12+counter, 0);
269 printw("Total");
270 move(12+counter, 12);
271 printw("%7s", size_conv(r));
272 move(12+counter, 26);
273 printw("%7s", size_conv(w));
274
275 /* Network */
276 network_stat_ptr = stats.network_stats;
277 for(counter=0;counter<stats.network_entries;counter++){
278 move(11+counter, 42);
279 printw("%s", network_stat_ptr->interface_name);
280 move(11+counter, 62);
281 rt = (network_stat_ptr->systime)? (network_stat_ptr->rx / network_stat_ptr->systime): network_stat_ptr->rx;
282 printw("%7s", size_conv(rt));
283 move(11+counter, 72);
284 wt = (network_stat_ptr->systime)? (network_stat_ptr->tx / network_stat_ptr->systime): network_stat_ptr->tx;
285 printw("%7s", size_conv(wt));
286 network_stat_ptr++;
287 }
288
289 disk_stat_ptr = stats.disk_stats;
290 for(counter=0;counter<stats.disk_entries;counter++){
291 move(13+stats.network_entries+counter, 42);
292 printw("%s", disk_stat_ptr->mnt_point);
293 move(13+stats.network_entries+counter, 62);
294 printw("%7s", size_conv(disk_stat_ptr->avail));
295 move(13+stats.network_entries+counter, 73);
296 printw("%5.2f%%", 100.00 * ((float)disk_stat_ptr->used / (float)disk_stat_ptr->size));
297 disk_stat_ptr++;
298 }
299
300 refresh();
301 }
302
303 void sig_winch_handler(int sig){
304 clear();
305 display_headings();
306 display_data();
307 signal(SIGWINCH, sig_winch_handler);
308 }
309
310 int get_stats(){
311 if((stats.cpu_percents = cpu_percent_usage()) == NULL) return 0;
312 if((stats.mem_stats = get_memory_stats()) == NULL) return 0;
313 if((stats.swap_stats = get_swap_stats()) == NULL) return 0;
314 if((stats.load_stats = get_load_stats()) == NULL) return 0;
315 if((stats.process_stats = get_process_stats()) == NULL) return 0;
316 if((stats.page_stats = get_page_stats_diff()) == NULL) return 0;
317 if((stats.network_stats = get_network_stats_diff(&(stats.network_entries))) == NULL) return 0;
318 if((stats.diskio_stats = get_diskio_stats_diff(&(stats.diskio_entries))) == NULL) return 0;
319 if((stats.disk_stats = get_disk_stats(&(stats.disk_entries))) == NULL) return 0;
320 if((stats.general_stats = get_general_stats()) == NULL) return 0;
321 if((stats.user_stats = get_user_stats()) == NULL) return 0;
322
323 return 1;
324 }
325
326 int main(int argc, char **argv){
327
328 extern char *optarg;
329 extern int optind;
330 int c;
331
332 WINDOW *window;
333
334 int stdin_fileno;
335 fd_set infds;
336 struct timeval timeout;
337
338 extern int errno;
339 char ch;
340
341 int delay=2;
342
343 while ((c = getopt(argc, argv, "d:")) != EOF){
344 switch (c){
345 case 'd':
346 delay = atoi(optarg);
347 if (delay == 0){
348 fprintf(stderr, "Time must be 1 second or greater\n");
349 exit(1);
350 }
351 delay--;
352 break;
353 }
354 }
355
356 signal(SIGWINCH, sig_winch_handler);
357 initscr();
358 nonl();
359 cbreak();
360 noecho();
361 window=newwin(0, 0, 0, 0);
362 clear();
363
364 if(!get_stats()){
365 fprintf(stderr, "Failed to get all the stats. Please check correct permissions\n");
366 endwin();
367 return 1;
368 }
369
370 display_headings();
371 stdin_fileno=fileno(stdin);
372
373 for(;;){
374
375 FD_ZERO(&infds);
376 FD_SET(stdin_fileno, &infds);
377 timeout.tv_sec = delay;
378 timeout.tv_usec = 0;
379
380 if((select((stdin_fileno+1), &infds, NULL, NULL, &timeout)) == -1){
381 if(errno!=EINTR){
382 perror("select failed");
383 exit(1);
384 }
385 }
386
387 if(FD_ISSET(stdin_fileno, &infds)){
388 ch=getch();
389 if (ch == 'q'){
390 endwin();
391 return 0;
392 }
393 }
394
395 get_stats();
396
397 display_data();
398
399 /* To keep the numbers slightly accurate we do not want them updating more
400 * frequently than once a second.
401 */
402 sleep(1);
403
404 }
405
406
407
408 endwin();
409 return 0;
410 }